Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions uts/docs/integration-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 14 additions & 2 deletions uts/docs/writing-test-specs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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": { ... },
Expand Down Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions uts/realtime/integration/proxy/connection_resume.md
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand All @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion uts/realtime/integration/proxy/presence_reentry.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 },
Expand Down
Loading