Skip to content

Commit

Permalink
test(*): implement new HTTP mocking
Browse files Browse the repository at this point in the history
Fix KAG-1148

apply suggestions

Co-authored-by: Chrono <chrono_cpp@me.com>
Co-authored-by: Hans Hübner <hans.huebner@gmail.com>
  • Loading branch information
3 people committed May 23, 2023
1 parent f679cdf commit fbb3a4d
Show file tree
Hide file tree
Showing 10 changed files with 1,026 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.VSCodeCounter

servroot*
mockserver

# kong
nginx_tmp/
Expand Down
222 changes: 222 additions & 0 deletions spec/02-integration/01-helpers/03-http_mock_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
local http_mock = require "spec.helpers.http_mock"
local pl_file = require "pl.file"

for _, tls in ipairs {true, false} do
describe("http_mock with " .. (tls and "https" or "http") , function()
local mock, client
lazy_setup(function()
mock = assert(http_mock.new(nil, {
["/"] = {
access = [[
ngx.print("hello world")
ngx.exit(200)
]]
},
["/404"] = {
access = [[
ngx.exit(404)
]]
}
}, {
eventually_timeout = 0.5,
tls = tls,
gen_client = true,
log_opts = {
resp = true,
resp_body = true
}
}))

assert(mock:start())
end)

lazy_teardown(function()
assert(mock:stop())
end)

before_each(function()
client = mock:get_client()
end)

after_each(function()
mock:clean()
-- it's an known issue of http_client that if we do not close the client, the next request will error out
client:close()
mock.client = nil
end)

it("get #response", function()
local res = assert(client:send({}))
assert.response(res).has.status(200)
assert.same(res:read_body(), "hello world")

mock.eventually:has_response_satisfy(function(resp)
assert.same(resp.body, "hello world")
end)
end)

it("clean works", function()
client:send({})
client:send({})
mock:clean()

assert.error(function()
mock.eventually:has_response_satisfy(function(resp)
assert.same(resp.body, "hello world")
end)
end)
end)

it("clean works 2", function()
mock.eventually:has_no_response_satisfy(function(resp)
assert.same(resp.body, "hello world")
end)
end)

it("mutiple request", function()
assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({}))).has.status(200)

local records = mock:retrieve_mocking_logs()

assert.equal(3, #records)
end)

it("request field", function()
assert.response(assert(client:send({}))).has.status(200)

mock.eventually:has_request_satisfy(function(req)
assert.match("localhost:%d+", req.headers.Host)
assert(req.headers["User-Agent"])
req.headers["Host"] = nil
req.headers["User-Agent"] = nil
assert.same(req, {
headers = {},
method = "GET",
uri = "/"
})
end)
end)

it("http_mock assertion", function()
local function new_check(record, status)
assert.same(record.resp.status, status)
return "has a response with status " .. status
end

http_mock.register_assert("status", new_check)

assert.response(assert(client:send({}))).has.status(200)
assert.no_error(function()
mock.eventually:has_status(200)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.error(function()
mock.eventually:has_status(404)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.no_error(function()
mock.eventually:has_no_status(404)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.error(function()
mock.eventually:has_no_status(200)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({}))).has.status(200)
assert.no_error(function()
mock.eventually:all_status(200)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({
path = "/404"
}))).has.status(404)
assert.error(function()
mock.eventually:all_status(200)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({
path = "/404"
}))).has.status(404)
assert.no_error(function()
mock.eventually:not_all_status(200)
end)

assert.response(assert(client:send({}))).has.status(200)
assert.response(assert(client:send({}))).has.status(200)
assert.error(function()
mock.eventually:not_all_status(200)
end)
end)
end)
end

describe("http_mock error catch", function()
it("error catch", function()
local mock = assert(http_mock.new(nil, [[
error("hello world")
ngx.exit(200)
]], {
eventually_timeout = 0.5,
tls = true,
gen_client = true,
log_opts = {
resp = true,
resp_body = true
}
}))

finally(function()
assert(mock:stop())
end)

assert(mock:start())
local client = mock:get_client()
local res = assert(client:send({}))
assert.response(res).has.status(500)

mock.eventually:has_error_satisfy(function(err)
return assert.same("hello world", err[1][1])
end)

mock:clean()
-- then we have no Error
mock.eventually:has_no_error()
end)
end)

describe("http_mock config", function()
it("default mocking", function()
local mock = assert(http_mock.new())
assert(mock:start())
finally(function()
assert(mock:stop())
end)
local client = mock:get_client()
local res = assert(client:send({}))
assert.response(res).has.status(200)
assert.same(res:read_body(), "ok")
end)

it("prefix", function()
local mock_prefix = "servroot_mock1"
local mock = assert(http_mock.new(nil, nil, {
prefix = mock_prefix
}))
mock:start()
finally(function()
assert(mock:stop())
end)

local pid_filename = mock_prefix .. "/logs/nginx.pid"

assert(pl_file.access_time(pid_filename) ~= nil, "mocking not in the correct place")
end)
end)
2 changes: 1 addition & 1 deletion spec/fixtures/https_server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ function https_server.shutdown(self)
return count
end


-- **DEPRECATED**: please use `spec.helpers.http_mock` instead.
function https_server.new(port, hostname, protocol, check_hostname, workers, delay)
local self = setmetatable({}, https_server)
local host
Expand Down
8 changes: 7 additions & 1 deletion spec/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,8 @@ end

--- Starts a local HTTP server.
--
-- **DEPRECATED**: please use an `http_mock` instead (see example at `start_kong`).
-- **DEPRECATED**: please use `spec.helpers.http_mock` instead. `http_server` has very poor
-- support to anything other then a single shot simple request.
--
-- Accepts a single connection and then closes. Sends a 200 ok, 'Connection:
-- close' response.
Expand Down Expand Up @@ -1489,6 +1490,9 @@ end


--- Start a local HTTP server with coroutine.
--
-- **DEPRECATED**: please use `spec.helpers.http_mock` instead.
--
-- local mock = helpers.http_mock(1234, { timeout = 0.1 })
-- wait for a request, and respond with the custom response
-- the request is returned as the function's return values
Expand Down Expand Up @@ -3437,6 +3441,8 @@ end
-- dns_mock = helpers.dns_mock.new()
-- }
--
-- **DEPRECATED**: http_mock fixture is deprecated. Please use `spec.helpers.http_mock` instead.
--
-- fixtures.dns_mock:A {
-- name = "a.my.srv.test.com",
-- address = "127.0.0.1",
Expand Down
Loading

0 comments on commit fbb3a4d

Please sign in to comment.