From cf864c37c1b67705906892d146efb61c270e9a1d Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Wed, 29 Jul 2026 08:40:38 +0800 Subject: [PATCH] test(lago): replace the docker-dependent case with a mock endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit lago.t was skipped as a whole file since #12903, leaving the plugin with no test-nginx coverage: TEST 1 is plain check_schema validation and was only collateral damage of the file-level skip, while TEST 2 cloned getlago/lago over the network and brought up its docker compose stack, which is the actual flake. Restore the schema tests and replace the real-stack case with a deterministic one: a mock of Lago's batch endpoint in t/lib/server.lua records what the plugin sends, and the route drives one event through it. This runs on every PR with no network clone or docker, and asserts the plugin's real contract — the /api/v1/events/batch endpoint, the bearer token, the event fields, and that the ${var} templates are resolved. Fixes #12904 --- t/lib/server.lua | 11 ++++++++ t/plugin/lago.t | 69 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/t/lib/server.lua b/t/lib/server.lua index d933478cdc6f..9ea8fbae753b 100644 --- a/t/lib/server.lua +++ b/t/lib/server.lua @@ -1272,4 +1272,15 @@ function _M.mock_compressed_upstream_response() end +-- mock of Lago's batch events endpoint (POST /api/v1/events/batch); logs the +-- Authorization header and request body so lago.t can assert on what the plugin +-- actually sent, then answers 200 with an empty batch like Lago does +function _M.api_v1_events_batch() + ngx.req.read_body() + ngx.log(ngx.WARN, "lago auth: ", ngx.req.get_headers()["Authorization"] or "") + ngx.log(ngx.WARN, "lago body: ", ngx.req.get_body_data() or "") + ngx.say('{"events": []}') +end + + return _M diff --git a/t/plugin/lago.t b/t/plugin/lago.t index d97875e05ea6..046e43e68dca 100644 --- a/t/plugin/lago.t +++ b/t/plugin/lago.t @@ -14,10 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -use t::APISIX; - -# This test cannot be executed normally at the moment, so it will be temporarily skipped and fixed in a later PR. -plan(skip_all => 'skip test case'); +use t::APISIX 'no_plan'; repeat_each(1); no_long_string(); @@ -69,12 +66,58 @@ property "event_properties" validation failed: wrong type: expected object, got -=== TEST 2: test ---- timeout: 302 ---- max_size: 2048000 ---- exec -cd t && pnpm test plugin/lago.spec.mts 2>&1 ---- no_error_log -failed to execute the script with status ---- response_body eval -qr/PASS plugin\/lago.spec.mts/ +=== TEST 2: set up a route whose lago plugin sends events to the mock endpoint +--- 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, + [[{ + "plugins": { + "lago": { + "endpoint_addrs": ["http://127.0.0.1:1980"], + "token": "test-token", + "event_transaction_id": "txn-${request_id}", + "event_subscription_id": "sub-1", + "event_code": "test", + "event_properties": { + "tier": "normal", + "status": "${status}" + }, + "batch_max_size": 1 + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- response_body +passed + + + +=== TEST 3: hitting the route batches one event and sends it to the mock +--- request +GET /hello +--- wait: 2 +--- response_body +hello world +--- error_log +lago auth: Bearer test-token +"code":"test" +"external_subscription_id":"sub-1" +"transaction_id":"txn- +"tier":"normal" +"status":"200"