diff --git a/scripts/upgrade-tests/test-upgrade-path.sh b/scripts/upgrade-tests/test-upgrade-path.sh index e4eeeecb4ab..14ffee9acea 100755 --- a/scripts/upgrade-tests/test-upgrade-path.sh +++ b/scripts/upgrade-tests/test-upgrade-path.sh @@ -150,6 +150,8 @@ function initialize_test_list() { docker exec ${OLD_CONTAINER} ln -sf /kong/bin/kong /upgrade-test/bin docker exec ${OLD_CONTAINER} bash -c "ln -sf /kong/spec/* /upgrade-test/spec" docker exec ${OLD_CONTAINER} tar -xf ${TESTS_TAR} -C /upgrade-test + docker cp spec/helpers/http_mock ${OLD_CONTAINER}:/upgrade-test/spec/helpers + docker cp spec/helpers/http_mock.lua ${OLD_CONTAINER}:/upgrade-test/spec/helpers rm ${TESTS_TAR} } @@ -185,7 +187,7 @@ function run_tests() { } function cleanup() { - git worktree remove worktree/$OLD_KONG_VERSION + git worktree remove worktree/$OLD_KONG_VERSION --force $COMPOSE down } diff --git a/spec/02-integration/16-queues/01-shutdown_spec.lua b/spec/02-integration/16-queues/01-shutdown_spec.lua index cc487f09439..bc03770a4bc 100644 --- a/spec/02-integration/16-queues/01-shutdown_spec.lua +++ b/spec/02-integration/16-queues/01-shutdown_spec.lua @@ -1,5 +1,5 @@ local helpers = require "spec.helpers" - +local http_mock = require "spec.helpers.http_mock" local HTTP_SERVER_PORT = helpers.get_available_port() @@ -81,6 +81,11 @@ for _, strategy in helpers.each_strategy() do end) it("queue is flushed before kong exits", function() + local mock = http_mock.new(HTTP_SERVER_PORT) + mock:start() + finally(function() + mock:stop() + end) local res = assert(proxy_client:send({ method = "GET", @@ -95,10 +100,7 @@ for _, strategy in helpers.each_strategy() do local pid_file, err = helpers.stop_kong(nil, nil, nil, "QUIT", true) assert(pid_file, err) - local thread = helpers.http_server(HTTP_SERVER_PORT, { timeout = 10 }) - local ok, _, body = thread:join() - assert(ok) - assert(body) + mock.eventually:has_request() helpers.wait_pid(pid_file) helpers.cleanup_kong() diff --git a/spec/03-plugins/37-opentelemetry/04-exporter_spec.lua b/spec/03-plugins/37-opentelemetry/04-exporter_spec.lua index 141be9f89f6..619956ab975 100644 --- a/spec/03-plugins/37-opentelemetry/04-exporter_spec.lua +++ b/spec/03-plugins/37-opentelemetry/04-exporter_spec.lua @@ -346,7 +346,6 @@ for _, strategy in helpers.each_strategy() do lazy_teardown(function() helpers.stop_kong() - helpers.kill_http_server(HTTP_SERVER_PORT) end) it("send enough spans", function () diff --git a/spec/05-migration/plugins/http-log/migrations/001_280_to_300_spec.lua b/spec/05-migration/plugins/http-log/migrations/001_280_to_300_spec.lua index 4399aef2a45..320b15096fc 100644 --- a/spec/05-migration/plugins/http-log/migrations/001_280_to_300_spec.lua +++ b/spec/05-migration/plugins/http-log/migrations/001_280_to_300_spec.lua @@ -1,68 +1,21 @@ local cjson = require "cjson" -local tablex = require "pl.tablex" +local http_mock = require "spec.helpers.http_mock" -local uh = require "spec/upgrade_helpers" +local uh = require "spec.upgrade_helpers" +-- we intentionally use a fixed port as this file may be loaded multiple times +-- to test the migration process. do not change it to use dynamic port. local HTTP_PORT = 29100 --- Copied from 3.x helpers.lua - -local function http_server(port, opts) - local threads = require "llthreads2.ex" - opts = opts or {} - local thread = threads.new( - { - function(port, opts) - local socket = require "socket" - local server = assert(socket.tcp()) - server:settimeout(opts.timeout or 60) - assert(server:setoption('reuseaddr', true)) - assert(server:bind("*", port)) - assert(server:listen()) - local client = assert(server:accept()) - - local lines = {} - local line, err - repeat - line, err = client:receive("*l") - if err then - break - else - table.insert(lines, line) - end - until line == "" - - if #lines > 0 and lines[1] == "GET /delay HTTP/1.0" then - ngx.sleep(2) - end - - if err then - server:close() - error(err) - end - - local body, _ = client:receive("*a") - - client:send("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n") - client:close() - server:close() - - return lines, body - end - }, - port, opts) - return thread:start() -end - describe("http-log plugin migration", function() - + local mock lazy_setup(function() assert(uh.start_kong()) end) lazy_teardown(function () - assert(uh.stop_kong()) + assert(uh.stop_kong(nil, true)) end) local log_server_url = "http://localhost:" .. HTTP_PORT .. "/" @@ -92,17 +45,26 @@ describe("http-log plugin migration", function() uh.create_example_service() end) - uh.all_phases("expected log header is added", function () - local thread = http_server(HTTP_PORT, { timeout = 10 }) + before_each(function () + mock = http_mock.new(HTTP_PORT) + mock:start() + end) - uh.send_proxy_get_request() + after_each(function () + mock:stop(true) + end) - local ok, headers = thread:join() - assert.truthy(ok) + uh.all_phases("expected log header is added", function () + uh.send_proxy_get_request() - -- verify that the log HTTP request had the configured header - local idx = tablex.find(headers, custom_header_name .. ": " .. custom_header_content) - assert.not_nil(idx, headers) + mock.eventually:has_request_satisfy(function(request) + local headers = request.headers + assert.not_nil(headers, "headers do not exist") + -- verify that the log HTTP request had the configured header + -- somehow ngx.req.get_headers() wants to return a table for a single value header + -- I don't know why but it's not relevant to this test + assert(custom_header_content == headers[custom_header_name] or custom_header_content == headers[custom_header_name][1]) + end) end) uh.new_after_finish("has updated http-log configuration", function () diff --git a/spec/helpers.lua b/spec/helpers.lua index 281a9e4ea60..08a93959d53 100644 --- a/spec/helpers.lua +++ b/spec/helpers.lua @@ -1301,75 +1301,6 @@ local function kill_tcp_server(port) end ---- Starts a local HTTP server. --- --- **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. --- If the request received has path `/delay` then the response will be delayed --- by 2 seconds. --- @function http_server --- @tparam number port The port the server will be listening on --- @tparam[opt] table opts options defining the server's behavior with the following fields: --- @tparam[opt=60] number opts.timeout time (in seconds) after which the server exits --- @return A thread object (from the `llthreads2` Lua package) --- @see kill_http_server -local function http_server(port, opts) - print(debug.traceback("[warning] http_server is deprecated, " .. - "use helpers.start_kong's fixture parameter " .. - "or helpers.http_mock instead.", 2)) - local threads = require "llthreads2.ex" - opts = opts or {} - if TEST_COVERAGE_MODE == "true" then - opts.timeout = TEST_COVERAGE_TIMEOUT - end - local thread = threads.new({ - function(port, opts) - local socket = require "socket" - local server = assert(socket.tcp()) - server:settimeout(opts.timeout or 60) - assert(server:setoption('reuseaddr', true)) - assert(server:bind("*", port)) - assert(server:listen()) - local client = assert(server:accept()) - - local content_length - local lines = {} - local line, err - repeat - line, err = client:receive("*l") - if err then - break - end - table.insert(lines, line) - content_length = tonumber(line:lower():match("^content%-length:%s*(%d+)$")) or content_length - until line == "" - - if #lines > 0 and lines[1] == "GET /delay HTTP/1.0" then - ngx.sleep(2) - end - - if err then - server:close() - error(err) - end - - local body, _ = client:receive(content_length or "*a") - - client:send("HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n") - client:close() - server:close() - - return lines, body - end - }, port, opts) - - return thread:start() -end - - local code_status = { [200] = "OK", [201] = "Created", @@ -1553,17 +1484,6 @@ local function http_mock(port, opts) end ---- Stops a local HTTP server. --- A server previously created with `http_server` can be stopped prematurely by --- calling this function. --- @function kill_http_server --- @param port the port the HTTP server is listening on. --- @see http_server -local function kill_http_server(port) - os.execute("fuser -n tcp -k " .. port) -end - - --- Starts a local UDP server. -- Reads the specified number of packets and then closes. -- The server-thread return values depend on `n`: @@ -3931,9 +3851,7 @@ end tcp_server = tcp_server, udp_server = udp_server, kill_tcp_server = kill_tcp_server, - http_server = http_server, http_mock = http_mock, - kill_http_server = kill_http_server, get_proxy_ip = get_proxy_ip, get_proxy_port = get_proxy_port, proxy_client = proxy_client, diff --git a/spec/helpers/http_mock/asserts.lua b/spec/helpers/http_mock/asserts.lua index a7a88b4c5b9..87836692ebd 100644 --- a/spec/helpers/http_mock/asserts.lua +++ b/spec/helpers/http_mock/asserts.lua @@ -41,7 +41,7 @@ local function eventually_has(check, mock, ...) time = time + step_time end - error(err or "assertion fail", 2) + error(err or "assertion fail. No request is sent and recorded.", 2) end -- wait until timeout to check if the assertion is true for all logs @@ -73,6 +73,10 @@ function build_in_checks.request_satisfy(session, f) return f(session.req) or "request satisfy" end +function build_in_checks.request() + return "request exist" +end + function build_in_checks.response_satisfy(session, f) return f(session.resp) or "response satisfy" end