From 896dea5d19106bfc75173c3e8ecfdaf024d0acf0 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 8 Oct 2026 22:58:00 +0530 Subject: [PATCH 1/3] UTS: correct stale and inconsistent UTS docs - writing-test-specs.md: define CLOSE_CLIENT, which 464 lines of the corpus use but no doc defined (it was described only in the commit that added it). - writing-test-specs.md: add the objects/unit, objects/integration and objects/proxy Test ID categories that 339 objects Test IDs already use. - writing-test-specs.md: use `endpoint:` in the proxy test template, as proxy.md's create_proxy_session signature and every corpus call do, instead of `target: TargetConfig(...)`. - integration-testing.md: list objects_gc_test.md among the specs annotated with `## Protocol Variants`. --- uts/docs/integration-testing.md | 1 + uts/docs/writing-test-specs.md | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/uts/docs/integration-testing.md b/uts/docs/integration-testing.md index 352d66136..933bb260b 100644 --- a/uts/docs/integration-testing.md +++ b/uts/docs/integration-testing.md @@ -302,6 +302,7 @@ The following integration test specs are annotated with `## Protocol Variants`: **LiveObjects:** - `objects/integration/objects_lifecycle_test.md` - `objects/integration/objects_sync_test.md` +- `objects/integration/objects_gc_test.md` ## Writing Proxy Tests diff --git a/uts/docs/writing-test-specs.md b/uts/docs/writing-test-specs.md index aa403e6b2..0e14160d2 100644 --- a/uts/docs/writing-test-specs.md +++ b/uts/docs/writing-test-specs.md @@ -35,7 +35,7 @@ Every test in the UTS suite has a unique identifier. The ID appears explicitly i | Field | Description | |-------|-------------| -| `category` | One of: `rest/unit`, `rest/integration`, `rest/proxy`, `realtime/unit`, `realtime/integration`, `realtime/proxy` | +| `category` | One of: `rest/unit`, `rest/integration`, `rest/proxy`, `realtime/unit`, `realtime/integration`, `realtime/proxy`, `objects/unit`, `objects/integration`, `objects/proxy` | | `spec-point` | The primary spec point being tested (e.g. `RSC15l2`, `RTN14a`) | | `descriptive-name` | 2–4 hyphenated words describing the specific behaviour (e.g. `timeout-fallback`, `cloudfront-header`) | | `n` | 0-based index disambiguating multiple tests for the same spec point within the same file | @@ -343,7 +343,7 @@ Tests that [behaviour] when the proxy injects [fault]. ```pseudo session = create_proxy_session( - target: TargetConfig(realtimeHost: "sandbox.realtime.ably-nonprod.net", restHost: "sandbox.realtime.ably-nonprod.net"), + endpoint: "nonprod:sandbox", rules: [{ "match": { ... }, "action": { ... }, @@ -658,6 +658,18 @@ In **integration and proxy** specs these timeouts are **wall-clock time** (the t real server — see the *Timeout Strategy* section in `docs/integration-testing.md`); in unit specs they may be realised with fake/virtual timers. +### Closing Clients (`CLOSE_CLIENT`) + +Realtime clients hold internal timers (retry, heartbeat, suspend) that keep the test process alive after the assertions complete. A test that creates a Realtime client should end with `CLOSE_CLIENT(client)`, one call per client it created: + +```pseudo +ASSERT client.connection.state == ConnectionState.connected + +CLOSE_CLIENT(client) +``` + +`CLOSE_CLIENT` is a cleanup step, not an assertion: it closes the client so its timers stop, and doesn't wait for or assert the CLOSED state. Derived tests should close the client even when the test fails (see *Cleanup with afterEach* in `writing-derived-tests.md`). + ## Timer Mocking Tests verifying timeout behavior should use timer mocking where practical to avoid slow tests. From 49657f77c19fd6890fbd788d57a3a0a1549ad5cc Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 8 Oct 2026 22:58:00 +0530 Subject: [PATCH 2/3] UTS: pass endpoint to create_proxy_session in presence_reentry.md proxy.md declares `endpoint` as a required argument of create_proxy_session, and every other corpus call passes `endpoint: "nonprod:sandbox"`. The two calls in presence_reentry.md passed only `rules:`, leaving each SDK harness to guess a default. --- uts/realtime/integration/proxy/presence_reentry.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/uts/realtime/integration/proxy/presence_reentry.md b/uts/realtime/integration/proxy/presence_reentry.md index 86c411a18..ae1a849dd 100644 --- a/uts/realtime/integration/proxy/presence_reentry.md +++ b/uts/realtime/integration/proxy/presence_reentry.md @@ -71,7 +71,10 @@ key_name = key_parts[0] key_secret = key_parts[1] # Create proxy session with clean passthrough (no fault rules) -session = create_proxy_session(rules: []) +session = create_proxy_session( + endpoint: "nonprod:sandbox", + rules: [] +) # client: the presence member, connects through the proxy so we can inject ATTACHED # Needs a clientId for presence — use authCallback with JWT that includes clientId @@ -191,6 +194,7 @@ key_secret = key_parts[1] # 1. Close the WebSocket 3s after connect (giving time to attach + enter presence) # 2. Replace the 2nd ATTACHED on the channel with a non-resumed one session = create_proxy_session( + endpoint: "nonprod:sandbox", rules: [ { match: { type: "delay_after_ws_connect", delayMs: 3000 }, From 958f61f38206b41d5afeffed9b3b7d4ae28d9993 Mon Sep 17 00:00:00 2001 From: sacOO7 Date: Thu, 8 Oct 2026 22:58:00 +0530 Subject: [PATCH 3/3] UTS: replace __PASSTHROUGH__ with a fixed fake key in connection_resume Test 22 The RTN14h test replaced the first CONNECTED with a message whose connectionKey was "__PASSTHROUGH__". uts-proxy has no such placeholder: its replace action (v0.3.0 and main) sends the message verbatim, so the client always received that literal string. Use an explicit fake key, matching the other replace rules in this file, and say in a comment that the test only checks that the client attempts the resume. The test's assertions are unchanged. --- uts/realtime/integration/proxy/connection_resume.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uts/realtime/integration/proxy/connection_resume.md b/uts/realtime/integration/proxy/connection_resume.md index 90fddc848..c31f32e44 100644 --- a/uts/realtime/integration/proxy/connection_resume.md +++ b/uts/realtime/integration/proxy/connection_resume.md @@ -779,6 +779,10 @@ As of specification version 6.1.0 this replaces RTN15g (deleted). The client no 3. Refuse the second ws_connect (fires once). This keeps the client in DISCONNECTED while the TTL clock runs out, so when the TTL expires the client transitions to SUSPENDED. The third ws_connect (when the `suspendedRetryTimeout` fires) should be a fresh connection. ```pseudo +# The replace action sends its message verbatim (uts-proxy has no placeholder that +# keeps the server's real value), so the client receives the fixed fake +# connectionKey below. The resume after TTL expiry is expected to fail +# server-side either way; the test checks only that the client attempts it (RTN14h). session = create_proxy_session( endpoint: "nonprod:sandbox", rules: [ @@ -789,9 +793,9 @@ session = create_proxy_session( "message": { "action": 4, "connectionId": "proxy-ttl-test-id", - "connectionKey": "__PASSTHROUGH__", + "connectionKey": "proxy-ttl-test-key", "connectionDetails": { - "connectionKey": "__PASSTHROUGH__", + "connectionKey": "proxy-ttl-test-key", "clientId": null, "maxMessageSize": 65536, "maxInboundRate": 250,