From b2db9e8d1a10904e0960fb09a3449305b26602c6 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Wed, 11 Jan 2017 16:10:18 -0800 Subject: [PATCH] tests(router) some fixes due to bad merging/rebasing --- kong/core/balancer.lua | 4 +- spec/02-integration/04-core/02-hooks_spec.lua | 487 ++++++------------ 2 files changed, 166 insertions(+), 325 deletions(-) diff --git a/kong/core/balancer.lua b/kong/core/balancer.lua index 95c476749319..454e2a0edfca 100644 --- a/kong/core/balancer.lua +++ b/kong/core/balancer.lua @@ -147,7 +147,7 @@ end -- @return balancer if found, or `false` if not found, or nil+error on error local get_balancer = function(target) -- NOTE: only called upon first lookup, so `cache_only` limitations do not apply here - local hostname = target.upstream.host + local hostname = target.host -- first go and find the upstream object, from cache or the db local upstream, err = get_upstream(hostname) @@ -300,7 +300,7 @@ local function execute(target) if not ip then if port == "dns server error; 3 name error" then -- in this case a "503 service unavailable", others will be a 500. - log(ERROR, "name resolution failed for '", tostring(target.host), + log(ERROR, "name resolution failed for '", tostring(target.host), "': ", port) return responses.send(503) end diff --git a/spec/02-integration/04-core/02-hooks_spec.lua b/spec/02-integration/04-core/02-hooks_spec.lua index 22c9671978ef..fc2f4fcca7f0 100644 --- a/spec/02-integration/04-core/02-hooks_spec.lua +++ b/spec/02-integration/04-core/02-hooks_spec.lua @@ -6,29 +6,16 @@ local pl_path = require "pl.path" local pl_file = require "pl.file" local pl_stringx = require "pl.stringx" -local api_client, client - -- cache entry inserted as a sentinel whenever a db lookup returns nothing -local db_miss_sentinel = { null = true } - -local function get_cache(key) - local r = assert(api_client:send { - method = "GET", - path = "/cache/"..key, - headers = {} - }) - assert.response(r).has.status(200) - return assert.response(r).has.jsonbody() -end +local DB_MISS_SENTINEL = { null = true } describe("Core Hooks", function() describe("Global", function() - describe("Plugin entity invalidation on API", function() + describe("Global Plugin entity invalidation on API", function() + local client, api_client local plugin before_each(function() - helpers.dao:truncate_tables() - assert(helpers.dao.apis:insert { name = "hooks1", hosts = { "hooks1.com" }, @@ -46,29 +33,15 @@ describe("Core Hooks", function() upstream_url = "http://mockbin.com" }) - assert(helpers.dao.apis:insert { - name = "hooks3", - hosts = { "hooks3.com" }, - upstream_url = "http://mockbin.com" - }) - - assert(helpers.dao.apis:insert { - name = "hooks4", - hosts = { "hooks4.com" }, - upstream_url = "http://mockbin.com" - }) - helpers.start_kong() client = helpers.proxy_client() api_client = helpers.admin_client() end) - after_each(function() if client and api_client then client:close() api_client:close() end - helpers.stop_kong() end) @@ -88,8 +61,12 @@ describe("Core Hooks", function() assert.response(res).has.status(200) -- Make sure the cache is not populated - local entry = get_cache(cache.plugin_key("basic-auth", nil, nil)) - assert.same(db_miss_sentinel, entry) -- db-miss sentinel value + local r = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", nil, nil) + }) + assert.response(r).has.status(200) + assert.same(DB_MISS_SENTINEL, assert.response(r).has.jsonbody()) -- db-miss sentinel value -- Add plugin local res = assert(api_client:send { @@ -116,7 +93,12 @@ describe("Core Hooks", function() assert.response(res).has.status(401) -- in effect plugin, so failure -- Make sure the cache is populated - local entry = get_cache(cache.plugin_key("basic-auth", nil, nil)) + local r = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", nil, nil) + }) + assert.response(r).has.status(200) + local entry = assert.response(r).has.jsonbody() assert.is_true(entry.enabled) assert.is.same("basic-auth", entry.name) end) @@ -134,7 +116,11 @@ describe("Core Hooks", function() assert.is_string(res.headers["X-RateLimit-Limit-minute"]) -- Make sure the cache is populated - get_cache(cache.plugin_key("rate-limiting", nil, nil)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", nil, nil) + }) + assert.res_status(200, res) -- Delete plugin local res = assert(api_client:send { @@ -144,7 +130,14 @@ describe("Core Hooks", function() assert.res_status(204, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("rate-limiting", nil, nil)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", nil, nil) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again without any authorization local res = assert(client:send { @@ -160,9 +153,19 @@ describe("Core Hooks", function() end) describe("Global Plugin entity invalidation on Consumer", function() + local client, api_client local plugin, consumer + setup(function() + helpers.dao:truncate_tables() + end) before_each(function() + assert(helpers.dao.apis:insert { + name = "hook1", + hosts = { "hooks1.com" }, + upstream_url = "http://mockbin.com" + }) + assert(helpers.dao.plugins:insert { name = "key-auth", config = {} @@ -171,7 +174,6 @@ describe("Core Hooks", function() consumer = assert(helpers.dao.consumers:insert { username = "test" }) - assert(helpers.dao.keyauth_credentials:insert { key = "kong", consumer_id = consumer.id @@ -183,7 +185,16 @@ describe("Core Hooks", function() config = { minute = 10 } }) - assert(helpers.reload_kong()) + helpers.start_kong() + client = helpers.proxy_client() + api_client = helpers.admin_client() + end) + after_each(function() + if client and api_client then + client:close() + api_client:close() + end + helpers.stop_kong() end) it("should invalidate a global plugin when deleting", function() @@ -199,7 +210,11 @@ describe("Core Hooks", function() assert.is_string(res.headers["X-RateLimit-Limit-minute"]) -- Make sure the cache is populated - get_cache(cache.plugin_key("rate-limiting", nil, consumer.id)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", nil, consumer.id) + }) + assert.res_status(200, res) -- Delete plugin local res = assert(api_client:send { @@ -209,7 +224,14 @@ describe("Core Hooks", function() assert.res_status(204, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("rate-limiting", nil, consumer.id)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", nil, consumer.id) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again without any authorization local res = assert(client:send { @@ -253,12 +275,9 @@ describe("Core Hooks", function() local consumer, api2, basic_auth2, api3, rate_limiting_consumer before_each(function() - helpers.dao:truncate_tables() - consumer = assert(helpers.dao.consumers:insert { - username = "consumer12" + username = "consumer1" }) - assert(helpers.dao.basicauth_credentials:insert { username = "user123", password = "pass123", @@ -272,7 +291,7 @@ describe("Core Hooks", function() }) api2 = assert(helpers.dao.apis:insert { - name = "hooks-consumer", + name = "hook2", hosts = { "hooks-consumer.com" }, upstream_url = "http://mockbin.com" }) @@ -283,7 +302,7 @@ describe("Core Hooks", function() }) api3 = assert(helpers.dao.apis:insert { - name = "hooks-plugins", + name = "hook3", hosts = { "hooks-plugins.com" }, upstream_url = "http://mockbin.com" }) @@ -307,6 +326,17 @@ describe("Core Hooks", function() minute = 3 } }) + + helpers.start_kong() + client = helpers.proxy_client() + api_client = helpers.admin_client() + end) + after_each(function() + if client and api_client then + client:close() + api_client:close() + end + helpers.stop_kong() end) describe("Plugin entity invalidation", function() @@ -323,7 +353,11 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Make sure the cache is populated - get_cache(cache.plugin_key("basic-auth", api2.id, nil)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", api2.id, nil) + }) + assert.res_status(200, res) -- Delete plugin local res = assert(api_client:send { @@ -333,7 +367,14 @@ describe("Core Hooks", function() assert.res_status(204, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("basic-auth", api2.id, nil)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", api2.id, nil) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again without any authorization local res = assert(client:send { @@ -369,7 +410,11 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Make sure the cache is populated - get_cache(cache.plugin_key("basic-auth", api2.id, nil)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", api2.id, nil) + }) + assert.res_status(200, res) -- Update plugin local res = assert(api_client:send { @@ -385,7 +430,14 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("basic-auth", api2.id, nil)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("basic-auth", api2.id, nil) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again without any authorization local res = assert(client:send { @@ -412,7 +464,11 @@ describe("Core Hooks", function() assert.equal(3, tonumber(res.headers["x-ratelimit-limit-minute"])) -- Make sure the cache is populated - get_cache(cache.plugin_key("rate-limiting", api3.id, consumer.id)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", api3.id, consumer.id) + }) + assert.res_status(200, res) -- Delete plugin local res = assert(api_client:send { @@ -422,7 +478,14 @@ describe("Core Hooks", function() assert.res_status(204, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("rate-limiting", api3.id, consumer.id)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", api3.id, consumer.id) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again local res = assert(client:send { @@ -451,7 +514,11 @@ describe("Core Hooks", function() assert.equal(3, tonumber(res.headers["x-ratelimit-limit-minute"])) -- Make sure the cache is populated - get_cache(cache.plugin_key("rate-limiting", api3.id, consumer.id)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", api3.id, consumer.id) + }) + assert.res_status(200, res) -- Update plugin local res = assert(api_client:send { @@ -467,7 +534,14 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Wait for cache to be invalidated - helpers.wait_for_invalidation(cache.plugin_key("rate-limiting", api3.id, consumer.id)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.plugin_key("rate-limiting", api3.id, consumer.id) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again local res = assert(client:send { @@ -481,7 +555,6 @@ describe("Core Hooks", function() assert.res_status(200, res) assert.equal(10, tonumber(res.headers["x-ratelimit-limit-minute"])) end) - end) describe("Consumer entity invalidation", function() @@ -498,7 +571,11 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Make sure the cache is populated - get_cache(cache.consumer_key(consumer.id)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.consumer_key(consumer.id) + }) + assert.res_status(200, res) -- Delete consumer local res = assert(api_client:send { @@ -508,10 +585,24 @@ describe("Core Hooks", function() assert.res_status(204, res) -- Wait for consumer be invalidated - helpers.wait_for_invalidation(cache.consumer_key(consumer.id)) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.consumer_key(consumer.id) + }) + res:read_body() + return res.status == 404 + end, 3) -- Wait for Basic Auth credential to be invalidated - helpers.wait_for_invalidation(cache.basicauth_credential_key("user123")) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.basicauth_credential_key("user123") + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again local res = assert(client:send { @@ -538,7 +629,11 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Make sure the cache is populated - get_cache(cache.consumer_key(consumer.id)) + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.consumer_key(consumer.id) + }) + assert.res_status(200, res) -- Update consumer local res = assert(api_client:send { @@ -554,7 +649,14 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Wait for consumer be invalidated - helpers.wait_for_invalidation(cache.consumer_key(consumer.id),3) + helpers.wait_until(function() + local res = assert(api_client:send { + method = "GET", + path = "/cache/"..cache.consumer_key(consumer.id) + }) + res:read_body() + return res.status == 404 + end, 3) -- Consuming the API again local res = assert(client:send { @@ -568,273 +670,12 @@ describe("Core Hooks", function() assert.res_status(200, res) -- Making sure the cache is updated - local body = get_cache(cache.consumer_key(consumer.id)) - assert.equal("updated_consumer", body.username) - end) - end) - - describe("Upstreams entity", function() - local upstream - - before_each(function() - assert(helpers.dao.apis:insert { - name = "hooks3", - hosts = { "hooks3.com" }, - upstream_url = "http://mybalancer" - }) - - upstream = assert(helpers.dao.upstreams:insert { - name = "mybalancer", - }) - - assert(helpers.dao.targets:insert { - upstream_id = upstream.id, - target = "mockbin.com:80", - weight = 10, - }) - end) - - it("invalidates the upstream-list when adding an upstream", function() - -- Making a request to populate the cache with the upstreams - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.upstreams_dict_key(upstream.id)) - -- add an upstream - local res = assert(api_client:send { - method = "POST", - path = "/upstreams", - headers = { - ["Content-Type"] = "application/json" - }, - body = { - name = "my2nd.upstream", - }, - }) - assert.response(res).has.status(201) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.upstreams_dict_key(upstream.id)) - end) - it("invalidates the upstream-list when updating an upstream", function() - -- Making a request to populate the cache with the upstreams - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.upstreams_dict_key(upstream.id)) - -- patch the upstream local res = assert(api_client:send { - method = "PATCH", - path = "/upstreams/"..upstream.id, - headers = { - ["Content-Type"] = "application/json" - }, - body = { - slots = 10, - orderlist = { 1,2,3,4,5,6,7,8,9,10 } - }, - }) - assert.response(res).has.status(200) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.upstreams_dict_key(upstream.id)) - end) - it("invalidates the upstream-list when deleting an upstream", function() - -- Making a request to populate the cache with the upstreams - local res = assert(client:send { method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.upstreams_dict_key(upstream.id)) - -- delete the upstream - local res = assert(api_client:send { - method = "DELETE", - path = "/upstreams/mybalancer", - }) - assert.response(res).has.status(204) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.upstreams_dict_key(upstream.id)) - end) - it("invalidates an upstream when updating an upstream", function() - -- Making a request to populate the cache with the upstream - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.upstream_key(upstream.id)) - -- patch the upstream - local res = assert(api_client:send { - method = "PATCH", - path = "/upstreams/"..upstream.id, - headers = { - ["Content-Type"] = "application/json" - }, - body = { - slots = 10, - orderlist = { 1,2,3,4,5,6,7,8,9,10 } - }, - }) - assert.response(res).has.status(200) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.upstream_key(upstream.id)) - end) - it("invalidates an upstream when deleting an upstream", function() - -- Making a request to populate the cache with the upstream - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.upstream_key(upstream.id)) - -- delete the upstream - local res = assert(api_client:send { - method = "DELETE", - path = "/upstreams/mybalancer", - }) - assert.response(res).has.status(204) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.upstream_key(upstream.id)) - end) - it("invalidates the target-history when updating an upstream", function() - -- Making a request to populate target history for upstream - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.targets_key(upstream.id)) - -- patch the upstream - local res = assert(api_client:send { - method = "PATCH", - path = "/upstreams/"..upstream.id, - headers = { - ["Content-Type"] = "application/json" - }, - body = { - slots = 10, - orderlist = { 1,2,3,4,5,6,7,8,9,10 } - }, - }) - assert.response(res).has.status(200) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.targets_key(upstream.id)) - end) - it("invalidates the target-history when deleting an upstream", function() - -- Making a request to populate target history for upstream - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks3.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.targets_key(upstream.id)) - -- delete the upstream - local res = assert(api_client:send { - method = "DELETE", - path = "/upstreams/mybalancer", - }) - assert.response(res).has.status(204) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.targets_key(upstream.id)) - end) - end) - - describe("Targets entity", function() - local upstream - - setup(function() - helpers.dao:truncate_tables() - - assert(helpers.dao.apis:insert { - name = "hooks4", - hosts = { "hooks4.com" }, - upstream_url = "http://mybalancer" - }) - upstream = assert(helpers.dao.upstreams:insert { - name = "mybalancer", - }) - assert(helpers.dao.targets:insert { - upstream_id = upstream.id, - target = "mockbin.com:80", - weight = 10, - }) - - helpers.stop_kong() - helpers.start_kong() - client = helpers.proxy_client() - api_client = helpers.admin_client() - end) - it("invalidates the target-history when adding a target", function() - -- Making a request to populate target history for upstream - local res = assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks4.com" - } - }) - assert.response(res).has.status(200) - -- validate that the cache is populated - get_cache(cache.targets_key(upstream.id)) - -- Adding a new target - local res = assert(api_client:send { - method = "POST", - path = "/upstreams/mybalancer/targets", - headers = { - ["Content-Type"] = "application/json" - }, - body = { - target = "mockbin.com:80", - weight = 5, - } - }) - assert.response(res).has.status(201) - -- wait for invalidation of the cache - helpers.wait_for_invalidation(cache.targets_key(upstream.id)) - -- Making another request to re-populate target history - assert(client:send { - method = "GET", - path = "/status/200", - headers = { - ["Host"] = "hooks4.com" - } + path = "/cache/"..cache.consumer_key(consumer.id) }) - -- validate that the cache is populated - local body = get_cache(cache.targets_key(upstream.id)) - -- check contents - assert.equal(10, body[1].weight) -- initial weight value - assert.equal(5, body[2].weight) -- new weight value + local body = assert.res_status(200, res) + assert.equal("updated_consumer", cjson.decode(body).username) end) end)