From 06a9058a8b1c96a1a3a41611d699fa88c9030f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E5=A5=87=E8=87=BB?= Date: Tue, 23 Jun 2026 14:55:12 +0800 Subject: [PATCH 1/3] fix(limit-conn): use parent resource key for consumer isolation Previously, when limit-conn was configured at the consumer level, connection limits were applied per-route instead of globally per consumer. This occurred because the key generation concatenated ctx.conf_type and ctx.conf_version, which included route-specific information. This commit fixes the issue by using conf._meta.parent.resource_key for key generation, consistent with the same fix already applied to limit-req (#13019) and limit-count plugins. Now consumer-level connection limits are properly shared across all routes accessed by the same consumer. Fixes #13584 Changes: - Added gen_limit_key() function using parent.resource_key approach - Replaced key = key .. ctx.conf_type .. ctx.conf_version with gen_limit_key(conf, ctx, key) in run_limit_conn() - Updated test cases to match new key format - Added test cases (TEST 35-42) verifying consumer isolation across multiple routes --- apisix/plugins/limit-conn/init.lua | 17 ++- t/plugin/limit-conn.t | 199 ++++++++++++++++++++++++++++- 2 files changed, 211 insertions(+), 5 deletions(-) diff --git a/apisix/plugins/limit-conn/init.lua b/apisix/plugins/limit-conn/init.lua index 0d45bd29074d..ad20ebcdc83e 100644 --- a/apisix/plugins/limit-conn/init.lua +++ b/apisix/plugins/limit-conn/init.lua @@ -16,6 +16,7 @@ -- local limit_conn_new = require("resty.limit.conn").new local core = require("apisix.core") +local apisix_plugin = require("apisix.plugin") local is_http = ngx.config.subsystem == "http" local sleep = core.sleep local tonumber = tonumber @@ -128,6 +129,17 @@ local function get_rules(ctx, conf) end +local function gen_limit_key(conf, ctx, key) + local parent = conf._meta and conf._meta.parent + if not parent or not parent.resource_key then + core.log.error("failed to generate key invalid parent: ", core.json.encode(parent)) + return nil + end + + return parent.resource_key .. ':' .. apisix_plugin.conf_version(conf) .. ':' .. key +end + + local function create_limit_obj(conf, rule, default_conn_delay) core.log.info("create new limit-conn plugin instance") @@ -190,7 +202,10 @@ local function run_limit_conn(conf, rule, ctx) key = ctx.var["remote_addr"] end - key = key .. ctx.conf_type .. ctx.conf_version + key = gen_limit_key(conf, ctx, key) + if not key then + return 500 + end core.log.info("limit key: ", key) local delay, err = lim:incoming(key, true) diff --git a/t/plugin/limit-conn.t b/t/plugin/limit-conn.t index 93c69730fc62..b0fd6e58b755 100644 --- a/t/plugin/limit-conn.t +++ b/t/plugin/limit-conn.t @@ -623,7 +623,7 @@ GET /test_concurrency 503 503 --- error_log -limit key: 10.10.10.1route +limit key: routes/1: @@ -714,7 +714,7 @@ GET /test_concurrency 503 503 --- error_log -limit key: 10.10.10.2route +limit key: routes/1: @@ -988,7 +988,7 @@ GET /test_concurrency 200 200 --- error_log_like eval -qr/limit key: consumer_jackroute&consumer\d+/ +qr/limit key: routes\/\d+:\d+:consumer_jack/ @@ -1077,7 +1077,7 @@ GET /test_concurrency 503 503 --- error_log_like eval -qr/limit key: consumer_jackroute&consumer\d+/ +qr/limit key: routes\/\d+:\d+:consumer_jack/ @@ -1200,3 +1200,194 @@ GET /t --- error_code: 400 --- response_body {"error_msg":"failed to check the configuration of plugin limit-conn err: property \"allow_degradation\" validation failed: wrong type: expected boolean, got string"} + + +=== TEST 35: create consumer with limit-conn +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/consumers/jack', + ngx.HTTP_PUT, + [[{ + "username": "jack", + "plugins": { + "key-auth": { + "key": "jack-key" + }, + "limit-conn": { + "conn": 2, + "burst": 0, + "default_conn_delay": 0.1, + "rejected_code": 503, + "key": "consumer_name" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + +=== TEST 36: create route 1 with key-auth +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/hello", + "plugins": { + "key-auth": {} + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + +=== TEST 37: create route 2 with key-auth (different uri, same consumer should share conn limit) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/2', + ngx.HTTP_PUT, + [[{ + "uri": "/ip", + "plugins": { + "key-auth": {} + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + +=== TEST 38: consumer jack accesses route 1 twice (within conn limit) +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello" +] +--- more_headers +apikey: jack-key +--- error_code eval +[200, 200] + + +=== TEST 39: consumer jack accesses route 2 - should be rejected (consumer-level conn=2 already used by route1) +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello", + "GET /ip" +] +--- more_headers +apikey: jack-key +--- error_code eval +[200, 200, 503] + + +=== TEST 40: create another consumer bob with separate limit-conn config +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/consumers/bob', + ngx.HTTP_PUT, + [[{ + "username": "bob", + "plugins": { + "key-auth": { + "key": "bob-key" + }, + "limit-conn": { + "conn": 2, + "burst": 0, + "default_conn_delay": 0.1, + "rejected_code": 503, + "key": "consumer_name" + } + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed + + +=== TEST 41: bob is isolated from jack - bob should not be affected by jack's connections +--- pipelined_requests eval +[ + "GET /hello", + "GET /hello", + "GET /hello", + "GET /hello" +] +--- more_headers +apikey: bob-key +--- error_code eval +[200, 200, 503, 503] + + +=== TEST 42: clean up test data +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + t('/apisix/admin/routes/1', ngx.HTTP_DELETE) + t('/apisix/admin/routes/2', ngx.HTTP_DELETE) + t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE) + t('/apisix/admin/consumers/bob', ngx.HTTP_DELETE) + ngx.say("done") + } + } +--- request +GET /t +--- response_body +done From 0ad3a4eca1d5f96b6c6f5d531d4071cfb73e7651 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Wed, 29 Jul 2026 16:59:07 +0800 Subject: [PATCH 2/3] test(limit-conn): assert the real limit key and cover the shared counter The expected keys were written as `routes/1`, but `resource_key` is the full etcd key, so the assertions in limit-conn.t never matched; limit-conn-redis.t still carried the pre-fix format. `error_log_like` is not a test-nginx section either, so those two blocks were never evaluated. The consumer-level blocks are moved to t/plugin/limit-conn-shared-counter.t and rewritten to fire the requests in parallel: limit-conn counts concurrent connections and releases the counter in the log phase, so the pipelined requests copied from the limit-req test could never hit the limit. --- t/plugin/limit-conn-redis.t | 8 +- t/plugin/limit-conn-shared-counter.t | 229 +++++++++++++++++++++++++++ t/plugin/limit-conn.t | 207 +----------------------- 3 files changed, 241 insertions(+), 203 deletions(-) create mode 100644 t/plugin/limit-conn-shared-counter.t diff --git a/t/plugin/limit-conn-redis.t b/t/plugin/limit-conn-redis.t index ad3224442205..4c4112d8d2e4 100644 --- a/t/plugin/limit-conn-redis.t +++ b/t/plugin/limit-conn-redis.t @@ -587,8 +587,8 @@ GET /test_concurrency --- response_body status:200, count:6 status:503, count:4 ---- error_log -limit key: 10.10.10.1route +--- error_log eval +qr/limit key: \/apisix\/routes\/1:\d+:10\.10\.10\.1/ @@ -679,8 +679,8 @@ GET /test_concurrency --- response_body status:200, count:6 status:503, count:4 ---- error_log -limit key: 10.10.10.2route +--- error_log eval +qr/limit key: \/apisix\/routes\/1:\d+:10\.10\.10\.2/ diff --git a/t/plugin/limit-conn-shared-counter.t b/t/plugin/limit-conn-shared-counter.t new file mode 100644 index 000000000000..d0e78c29d904 --- /dev/null +++ b/t/plugin/limit-conn-shared-counter.t @@ -0,0 +1,229 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX 'no_plan'; + +log_level('info'); +repeat_each(1); +no_long_string(); +no_shuffle(); +no_root_location(); + +add_block_preprocessor(sub { + my ($block) = @_; + my $port = $ENV{TEST_NGINX_SERVER_PORT}; + + if ((!defined $block->error_log) && (!defined $block->no_error_log)) { + $block->set_value("no_error_log", "[error]"); + } + + if (!defined $block->request) { + $block->set_value("request", "GET /t"); + } + + # limit-conn counts *concurrent* connections and releases the counter in the + # log phase, so the requests have to overlap: pipelined requests are handled + # one after another and would never hit the limit. + my $config = $block->config // <<_EOC_; + location /concurrent { + content_by_lua_block { + local httpc = require("resty.http") + + local function hit(uri, apikey) + local hc = httpc:new() + local res, err = hc:request_uri("http://127.0.0.1:$port" .. uri, + {headers = {apikey = apikey}}) + if not res then + ngx.log(ngx.ERR, "request to ", uri, " failed: ", err) + return 0 + end + return res.status + end + + -- two_routes: same consumer hits two different routes + -- two_consumers: two consumers hit the same route + local reqs = { + two_routes = {{"/limit_conn", "jack-key"}, {"/limit_conn2", "jack-key"}}, + two_consumers = {{"/limit_conn", "jack-key"}, {"/limit_conn", "bob-key"}}, + } + + local threads = {} + for i, req in ipairs(reqs[ngx.var.arg_case]) do + threads[i] = ngx.thread.spawn(hit, req[1], req[2]) + end + + local codes = {} + for i, th in ipairs(threads) do + local _, status = ngx.thread.wait(th) + codes[i] = status + end + + table.sort(codes) + ngx.say(table.concat(codes, ",")) + } + } +_EOC_ + + $block->set_value("config", $config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: consumer jack with limit-conn (conn = 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/consumers/jack', + ngx.HTTP_PUT, + [[{ + "username": "jack", + "plugins": { + "key-auth": { + "key": "jack-key" + }, + "limit-conn": { + "conn": 1, + "burst": 0, + "default_conn_delay": 0.1, + "rejected_code": 503, + "key": "consumer_name" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 2: consumer bob with its own limit-conn (conn = 1) +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/consumers/bob', + ngx.HTTP_PUT, + [[{ + "username": "bob", + "plugins": { + "key-auth": { + "key": "bob-key" + }, + "limit-conn": { + "conn": 1, + "burst": 0, + "default_conn_delay": 0.1, + "rejected_code": 503, + "key": "consumer_name" + } + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 3: set 2 routes with key-auth, both proxying to the slow upstream +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "uri": "/limit_conn", + "plugins": { + "key-auth": {} + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } + }]] + ) + if code >= 300 then + ngx.status = code + ngx.say(body) + return + end + + code, body = t('/apisix/admin/routes/2', + ngx.HTTP_PUT, + [[{ + "uri": "/limit_conn2", + "plugins": { + "key-auth": {}, + "proxy-rewrite": { + "uri": "/limit_conn" + } + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "127.0.0.1:1980": 1 + } + } + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 4: the counter is shared across routes and keyed by the consumer +--- request +GET /concurrent?case=two_routes +--- response_body +200,503 +--- error_log eval +qr/limit key: \/apisix\/consumers\/jack:\d+:jack/ +--- timeout: 10 + + + +=== TEST 5: different consumers keep their own counter +--- request +GET /concurrent?case=two_consumers +--- response_body +200,200 +--- timeout: 10 diff --git a/t/plugin/limit-conn.t b/t/plugin/limit-conn.t index b0fd6e58b755..06bbdeec8a9e 100644 --- a/t/plugin/limit-conn.t +++ b/t/plugin/limit-conn.t @@ -622,8 +622,8 @@ GET /test_concurrency 503 503 503 ---- error_log -limit key: routes/1: +--- error_log eval +qr/limit key: \/apisix\/routes\/1:\d+:10\.10\.10\.1/ @@ -713,8 +713,8 @@ GET /test_concurrency 503 503 503 ---- error_log -limit key: routes/1: +--- error_log eval +qr/limit key: \/apisix\/routes\/1:\d+:10\.10\.10\.2/ @@ -987,8 +987,8 @@ GET /test_concurrency 200 200 200 ---- error_log_like eval -qr/limit key: routes\/\d+:\d+:consumer_jack/ +--- error_log eval +qr/limit key: \/apisix\/routes\/\d+:\d+:consumer_jack/ @@ -1076,8 +1076,8 @@ GET /test_concurrency 503 503 503 ---- error_log_like eval -qr/limit key: routes\/\d+:\d+:consumer_jack/ +--- error_log eval +qr/limit key: \/apisix\/routes\/\d+:\d+:consumer_jack/ @@ -1200,194 +1200,3 @@ GET /t --- error_code: 400 --- response_body {"error_msg":"failed to check the configuration of plugin limit-conn err: property \"allow_degradation\" validation failed: wrong type: expected boolean, got string"} - - -=== TEST 35: create consumer with limit-conn ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers/jack', - ngx.HTTP_PUT, - [[{ - "username": "jack", - "plugins": { - "key-auth": { - "key": "jack-key" - }, - "limit-conn": { - "conn": 2, - "burst": 0, - "default_conn_delay": 0.1, - "rejected_code": 503, - "key": "consumer_name" - } - } - }]] - ) - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - -=== TEST 36: create route 1 with key-auth ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/1', - ngx.HTTP_PUT, - [[{ - "uri": "/hello", - "plugins": { - "key-auth": {} - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } - } - }]] - ) - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - -=== TEST 37: create route 2 with key-auth (different uri, same consumer should share conn limit) ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/routes/2', - ngx.HTTP_PUT, - [[{ - "uri": "/ip", - "plugins": { - "key-auth": {} - }, - "upstream": { - "type": "roundrobin", - "nodes": { - "127.0.0.1:1980": 1 - } - } - }]] - ) - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - -=== TEST 38: consumer jack accesses route 1 twice (within conn limit) ---- pipelined_requests eval -[ - "GET /hello", - "GET /hello" -] ---- more_headers -apikey: jack-key ---- error_code eval -[200, 200] - - -=== TEST 39: consumer jack accesses route 2 - should be rejected (consumer-level conn=2 already used by route1) ---- pipelined_requests eval -[ - "GET /hello", - "GET /hello", - "GET /ip" -] ---- more_headers -apikey: jack-key ---- error_code eval -[200, 200, 503] - - -=== TEST 40: create another consumer bob with separate limit-conn config ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - local code, body = t('/apisix/admin/consumers/bob', - ngx.HTTP_PUT, - [[{ - "username": "bob", - "plugins": { - "key-auth": { - "key": "bob-key" - }, - "limit-conn": { - "conn": 2, - "burst": 0, - "default_conn_delay": 0.1, - "rejected_code": 503, - "key": "consumer_name" - } - } - }]] - ) - if code >= 300 then - ngx.status = code - end - ngx.say(body) - } - } ---- request -GET /t ---- response_body -passed - - -=== TEST 41: bob is isolated from jack - bob should not be affected by jack's connections ---- pipelined_requests eval -[ - "GET /hello", - "GET /hello", - "GET /hello", - "GET /hello" -] ---- more_headers -apikey: bob-key ---- error_code eval -[200, 200, 503, 503] - - -=== TEST 42: clean up test data ---- config - location /t { - content_by_lua_block { - local t = require("lib.test_admin").test - t('/apisix/admin/routes/1', ngx.HTTP_DELETE) - t('/apisix/admin/routes/2', ngx.HTTP_DELETE) - t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE) - t('/apisix/admin/consumers/bob', ngx.HTTP_DELETE) - ngx.say("done") - } - } ---- request -GET /t ---- response_body -done From fd672b0b272cb2da960cc11723f6726917f23526 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Wed, 29 Jul 2026 17:45:40 +0800 Subject: [PATCH 3/3] fix(limit-conn): honour allow_degradation when the key cannot be built Every other failure path in run_limit_conn() falls back to allow_degradation; the new nil-key branch was the only one that always returned 500. Also drop the now misleading `ver:` log line, since ctx.conf_version no longer takes part in the key. Tests: - limit-conn-shared-counter.t keys both consumers on remote_addr, so they resolve to the same value and only the parent resource_key keeps them apart. TEST 5 previously passed with or without the fix; now it fails without it. - The file deletes its routes and consumers again. /apisix/routes/2 (uri /limit_conn2) leaked into t/plugin/workflow3.t, which expects that uri to 404 and got 401 from the leftover key-auth route. - workflow3.t asserts both _vid suffixes: the two workflow rules carry identical limit-conn confs on one route, so _vid is all that separates them. - stream-plugin/limit-conn.t asserts the stream_route key shape, pinning the fact that stream routes go through the same router.lua filter. --- apisix/plugins/limit-conn/init.lua | 5 ++-- t/plugin/limit-conn-shared-counter.t | 41 ++++++++++++++++++++++++---- t/plugin/workflow3.t | 5 ++++ t/stream-plugin/limit-conn.t | 5 ++++ 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/apisix/plugins/limit-conn/init.lua b/apisix/plugins/limit-conn/init.lua index 7fd2faba87ad..1157716b4512 100644 --- a/apisix/plugins/limit-conn/init.lua +++ b/apisix/plugins/limit-conn/init.lua @@ -211,6 +211,9 @@ local function run_limit_conn(conf, rule, ctx) key = gen_limit_key(conf, ctx, key) if not key then + if conf.allow_degradation then + return + end return 500 end core.log.info("limit key: ", key) @@ -246,8 +249,6 @@ end function _M.increase(conf, ctx) - core.log.info("ver: ", ctx.conf_version) - local rules, err = get_rules(ctx, conf) if not rules or #rules == 0 then core.log.error("failed to get limit conn rules: ", err) diff --git a/t/plugin/limit-conn-shared-counter.t b/t/plugin/limit-conn-shared-counter.t index d0e78c29d904..fdd5f6651c0f 100644 --- a/t/plugin/limit-conn-shared-counter.t +++ b/t/plugin/limit-conn-shared-counter.t @@ -84,7 +84,7 @@ run_tests(); __DATA__ -=== TEST 1: consumer jack with limit-conn (conn = 1) +=== TEST 1: consumer jack with limit-conn (conn = 1, key shared with bob) --- config location /t { content_by_lua_block { @@ -102,7 +102,7 @@ __DATA__ "burst": 0, "default_conn_delay": 0.1, "rejected_code": 503, - "key": "consumer_name" + "key": "remote_addr" } } }]] @@ -119,7 +119,7 @@ passed -=== TEST 2: consumer bob with its own limit-conn (conn = 1) +=== TEST 2: consumer bob with the very same limit-conn config --- config location /t { content_by_lua_block { @@ -137,7 +137,7 @@ passed "burst": 0, "default_conn_delay": 0.1, "rejected_code": 503, - "key": "consumer_name" + "key": "remote_addr" } } }]] @@ -216,14 +216,45 @@ GET /concurrent?case=two_routes --- response_body 200,503 --- error_log eval -qr/limit key: \/apisix\/consumers\/jack:\d+:jack/ +qr/limit key: \/apisix\/consumers\/jack:\d+:127\.0\.0\.1/ +--- no_error_log +[error] --- timeout: 10 === TEST 5: different consumers keep their own counter +jack and bob resolve to the same key value (remote_addr) on the same route, so +only the parent resource_key keeps them apart. --- request GET /concurrent?case=two_consumers --- response_body 200,200 +--- error_log eval +qr/limit key: \/apisix\/consumers\/bob:\d+:127\.0\.0\.1/ --- timeout: 10 + + + +=== TEST 6: clean up +The routes and consumers created here would otherwise leak into the next file of +the same CI job: /limit_conn2 is expected to 404 in t/plugin/workflow3.t. +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + for _, uri in ipairs({"/apisix/admin/routes/1", "/apisix/admin/routes/2", + "/apisix/admin/consumers/jack", + "/apisix/admin/consumers/bob"}) do + local code = t(uri, ngx.HTTP_DELETE) + if code >= 300 then + ngx.status = code + ngx.say("failed to delete ", uri) + return + end + end + ngx.say("done") + } + } +--- response_body +done diff --git a/t/plugin/workflow3.t b/t/plugin/workflow3.t index e993381af02a..60f1ffab1dae 100644 --- a/t/plugin/workflow3.t +++ b/t/plugin/workflow3.t @@ -262,6 +262,11 @@ GET /test_concurrency2 503 503 503 +--- error_log eval +[ + qr/limit key: \/apisix\/routes\/1:\d+:127\.0\.0\.1:1/, + qr/limit key: \/apisix\/routes\/1:\d+:127\.0\.0\.1:2/, +] diff --git a/t/stream-plugin/limit-conn.t b/t/stream-plugin/limit-conn.t index c6c7c89c0c0d..3a733475ef16 100644 --- a/t/stream-plugin/limit-conn.t +++ b/t/stream-plugin/limit-conn.t @@ -141,6 +141,11 @@ GET /test_concurrency 200 200 --- stream_enable +--- error_log eval +qr/limit key: \/apisix\/stream_routes\/1:\d+:127\.0\.0\.1/ +--- no_error_log +[error] +[alert]