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. 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, 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 },