You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Review-driven fixes on the UTS refactoring (PR #1228 threads):
- uts infra: awaitState/awaitChannelState could double-resume their
continuation (the state listener and the immediate check race on
different threads; check-then-resume is not atomic). Use the atomic
single-winner tryResume/completeResume pair (@InternalCoroutinesApi).
- liveobjects tests: dispose ObjectsPool in teardown where it leaked a
GC coroutine + adapter subscription (LiveObjectTombstoneTest,
DefaultRealtimeObjectAsyncTest), matching the documented S-4 contract;
align ValueTypesTest to the dispose-before-unmockkAll ordering.
- liveobjects integration: retain the provisioned SandboxApp and delete
it in tearDownAfterClass (best-effort, matching the :java suites).
- InternalLiveMapApiTest: replace the stale note claiming a real
GET /time fires — setupSyncedChannel installs a MockHttpClient that
answers /time locally; the unit tier is hermetic.
- deviations.md (:java): restructure into the canonical four-section
format from writing-derived-tests.md (UTS Spec Errors / Failing Tests /
Adapted Tests / Mock Infrastructure Limitations), preserving all
recorded deviations; fix the RTN16g2 heading to describe the workaround
rather than restate it as a requirement; drop the stale moved-pointer.
- uts/README.md: replace the invalid-Kotlin ellipsis with the real
systemProperty expression from uts/build.gradle.kts.
- uts-to-kotlin skill: point the deviation checklist at the tier's module
deviations file; spell out the full TestHelpers.kt path.
The ObjectsSyncTracker channelSerial regex finding is intentionally not
fixed here — tracked cross-SDK in ably/specification#520.
Verified: liveobjects unit 389/0; :java/:uts UTS unit 6/0, 3/0;
integration 29/0, 5/0, 4/0; codenarc + checkstyle green.
Copy file name to clipboardExpand all lines: .claude/skills/uts-to-kotlin/SKILL.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -645,7 +645,7 @@ For each test case, verify:
645
645
Deviations are discovered by running, so this check applies in evaluate mode. For any place where the
646
646
generated test diverges from the spec pseudocode (adapted assertion, env-gated skip, or omitted step):
647
647
-[ ] A `// DEVIATION:` comment explains why
648
-
-[ ] The deviation is recorded in `lib/src/test/kotlin/io/ably/lib/uts/deviations.md`
648
+
-[ ] The deviation is recorded in the tier's module deviations file (see "Deviations file" above: `lib/src/test/kotlin/io/ably/lib/uts/deviations.md` for realtime/rest tiers, `liveobjects/src/test/kotlin/io/ably/lib/liveobjects/uts/deviations.md` for objects tiers)
649
649
650
650
If you find gaps during this review, fix them, then **re-run the audit script** until `missingInKotlin` /
651
651
`orphanInKotlin` are empty and every `perTest` entry reconciles, and re-run Step 5 (compile) — and, in
Deviations from the Ably spec identified during UTS test translation. Each entry records the spec point, what the spec requires, what the SDK actually does, and which test contains the deviation gate.
4
-
5
-
**Scope:** this file now lives alongside the realtime UTS suites in the `:java` module
6
-
(`lib/src/test/kotlin/io/ably/lib/uts/`) and holds deviations for the **realtime/rest tiers** it
7
-
hosts. All **objects** tiers (unit, integration and proxy) moved to `:liveobjects`'s own test source
8
-
set alongside the tests they document; their deviations (the typed-SDK / language adaptations, the
9
-
intentional RTO18d entry, and any objects integration/proxy entries) are in
10
-
`liveobjects/src/test/kotlin/io/ably/lib/liveobjects/uts/deviations.md`. For the shared UTS infra these
11
-
suites consume, the tier smoke examples, and the `RUN_DEVIATIONS` mechanism, see `uts/README.md`.
12
-
13
-
Entries are grouped by actionability (shared taxonomy across both files; only groups with entries in
14
-
this file appear as sections below):
15
-
16
-
| Group | Meaning | Action |
17
-
|---|---|---|
18
-
|**1) Genuine SDK bugs — open**| runtime behaviour differs from the spec; ably-js is compliant | fix the SDK |
19
-
|**2) Shared gap — open in both SDKs**| ably-java and ably-js deviate the same way | optional joint fix (spec is ahead of both) |
20
-
|**3) Expected — typed-SDK / language adaptations**| not bugs: RTTS API partitioning, compile-time guarantees, internal-wire visibility | none — correct as documented |
21
-
|**4) Intentional deviation**| deliberate SDK design choice; the spec point itself is questioned | none unless the spec is revised |
@@ -32,16 +27,48 @@ this file appear as sections below):
32
27
33
28
---
34
29
35
-
# 1) Genuine SDK bugs — open (realtime module)
30
+
## UTS Spec Errors
31
+
32
+
*(none)*
33
+
34
+
## Failing Tests
36
35
37
-
*Runtime behaviour differs from the spec and ably-js is compliant — real bugs, pending an SDK fix.*
36
+
*SDK non-compliance where the spec-correct assertion is present but skipped (env-gated behind `RUN_DEVIATIONS`). These are the primary output — each maps to a potential issue to file.*
38
37
39
38
> ⚠ **RTL13b / RTL13c:** the channel-state UTS tests these two entries cite are **not currently part of the
40
39
> uts suite** (no `RTL13*` tests or gates exist in `unit/realtime/` — only `ConnectionRecoveryTest.kt` is
41
40
> translated). The entries are retained as confirmed SDK gaps (cross-checked against ably-js in
42
41
> `ABLY-JS-JAVA-DEVIATIONS-COMPARISON.md`); re-verify them when the channels module translation lands.
42
+
> (RTL13b is recorded under **Adapted Tests** — it adapts the test setup rather than env-gating an assertion.)
43
+
44
+
### RTL13c — channelRetryTimeout not cancelled when connection leaves CONNECTED
45
+
46
+
**Spec point:** RTL13c
47
+
**What the spec requires:** When the connection is no longer CONNECTED, any pending automatic channel reattach timer (channelRetryTimeout) must be cancelled. The channel should remain SUSPENDED without attempting to reattach until the connection is restored.
48
+
**What the SDK does:** The channelRetryTimeout fires regardless of connection state. When it fires while disconnected, the channel transitions to ATTACHING even though there is no active connection, and no ATTACH message can be sent.
49
+
**Tests affected:**
50
+
-`RTL13c - automatic retry cancelled when connection is no longer CONNECTED` (RTL13c/retry-cancelled-disconnected-0) — the assertions `assertEquals(attachCountAfterDisconnect, attachCount)` and `assertEquals(ChannelState.suspended, channel.state)` are gated behind `RUN_DEVIATIONS`.
51
+
52
+
**Status:** Open SDK bug — ably-js is compliant; fix the SDK.
53
+
54
+
### RTN16f — msgSerial not initialised from recovery key on connect
55
+
56
+
**Spec point:** RTN16f
57
+
**What the spec requires:** When instantiated with the `recover` option, the SDK initialises its internal `msgSerial` counter to the value stored in the recovery key, so the first published message carries that serial.
58
+
**What the SDK does:**`ConnectionManager.onConnected()` resets `msgSerial` to 0 whenever `connection.id` is null on the fresh client (line 1316), even when the `recover` option is set. The recovered serial is discarded.
59
+
**Workaround in tests:** The spec-correct assertion (`assertEquals(42L, msgSerial)`) is gated behind `RUN_DEVIATIONS`. A regression guard assertion (`assertEquals(0L, msgSerial)`) runs by default to catch any unintentional change to the SDK's actual behaviour.
60
+
**Tests affected:**
61
+
-`RTN16f - recover option initializes msgSerial from recoveryKey` (RTN16f/recover-initializes-msgserial-0) — `assertEquals(42L, ...)` gated; `assertEquals(0L, ...)` added as regression guard.
62
+
63
+
**Status:** Open SDK bug — ably-js is compliant; fix the SDK.
64
+
65
+
## Adapted Tests
43
66
44
-
## RTL13b — ATTACHING → SUSPENDED via `realtimeRequestTimeout` not implemented
67
+
*SDK non-compliance where the test asserts the SDK's actual behaviour (or adapts its setup/stimulus to the SDK's reality) instead of using the spec's unreachable path. It passes, guards against regressions, and documents the deviation.*
68
+
69
+
> ⚠ Not currently part of the uts suite — see the shared **RTL13b / RTL13c** caveat under **Failing Tests**.
70
+
71
+
### RTL13b — ATTACHING → SUSPENDED via realtimeRequestTimeout not implemented
45
72
46
73
**Spec point:** RTL13b
47
74
**What the spec requires:** If a channel's reattach request (triggered by RTL13a) does not receive a response within `realtimeRequestTimeout`, the channel must transition from ATTACHING to SUSPENDED and schedule a retry after `channelRetryTimeout`.
@@ -53,19 +80,9 @@ this file appear as sections below):
53
80
-`RTL13b - repeated failures cycle SUSPENDED to ATTACHING indefinitely` (RTL13b/repeated-failure-cycle-2) — mock sends DETACHED instead of withholding response
54
81
-`RTL13c - automatic retry cancelled when connection is no longer CONNECTED` (RTL13c/retry-cancelled-disconnected-0) — setup path changed
55
82
56
-
---
57
-
58
-
## RTL13c — channelRetryTimeout not cancelled when connection leaves CONNECTED
59
-
60
-
**Spec point:** RTL13c
61
-
**What the spec requires:** When the connection is no longer CONNECTED, any pending automatic channel reattach timer (channelRetryTimeout) must be cancelled. The channel should remain SUSPENDED without attempting to reattach until the connection is restored.
62
-
**What the SDK does:** The channelRetryTimeout fires regardless of connection state. When it fires while disconnected, the channel transitions to ATTACHING even though there is no active connection, and no ATTACH message can be sent.
63
-
**Tests affected:**
64
-
-`RTL13c - automatic retry cancelled when connection is no longer CONNECTED` (RTL13c/retry-cancelled-disconnected-0) — the assertions `assertEquals(attachCountAfterDisconnect, attachCount)` and `assertEquals(ChannelState.suspended, channel.state)` are gated behind `RUN_DEVIATIONS`.
65
-
66
-
---
83
+
**Status:** Open SDK bug — ably-js is compliant; fix the SDK.
67
84
68
-
## RTN16g2 — Fatal ERROR must be sent without closing the transport
85
+
###RTN16g2 — the spec's fatal-ERROR-plus-close trigger can't drive this SDK to FAILED
69
86
70
87
**Spec point:** RTN16g2
71
88
**What the spec requires:** Trigger FAILED state by sending a fatal ERROR message followed by closing the WebSocket (`send_to_client_and_close`), using error code 50000/statusCode 500.
@@ -76,24 +93,8 @@ this file appear as sections below):
76
93
**Tests affected:**
77
94
-`RTN16g2 - createRecoveryKey returns null in inactive states and before first connect` (RTN16g2/recovery-key-null-inactive-0) — error code and send method changed.
78
95
79
-
---
80
-
81
-
## RTN16f — msgSerial not initialised from recovery key on connect
82
-
83
-
**Spec point:** RTN16f
84
-
**What the spec requires:** When instantiated with the `recover` option, the SDK initialises its internal `msgSerial` counter to the value stored in the recovery key, so the first published message carries that serial.
85
-
**What the SDK does:**`ConnectionManager.onConnected()` resets `msgSerial` to 0 whenever `connection.id` is null on the fresh client (line 1316), even when the `recover` option is set. The recovered serial is discarded.
86
-
**Workaround in tests:** The spec-correct assertion (`assertEquals(42L, msgSerial)`) is gated behind `RUN_DEVIATIONS`. A regression guard assertion (`assertEquals(0L, msgSerial)`) runs by default to catch any unintentional change to the SDK's actual behaviour.
87
-
**Tests affected:**
88
-
-`RTN16f - recover option initializes msgSerial from recoveryKey` (RTN16f/recover-initializes-msgserial-0) — `assertEquals(42L, ...)` gated; `assertEquals(0L, ...)` added as regression guard.
89
-
90
-
---
91
-
96
+
**Status:** Open SDK bug — ably-js is compliant; fix the SDK.
92
97
93
-
#Objects deviations — moved
98
+
## Mock Infrastructure Limitations
94
99
95
-
All objects tiers (**unit, integration and proxy**) live in `:liveobjects`'s own test source set,
96
-
and their deviation records (the typed-SDK / language adaptations, the former groups 3 & 4 as they
97
-
applied to objects, and any objects integration/proxy entries) are in
98
-
`liveobjects/src/test/kotlin/io/ably/lib/liveobjects/uts/deviations.md`. This file keeps only the
99
-
deviations for the realtime/rest tiers hosted in `:java`.
0 commit comments