From eab3bd47698c828ab780577633e5ac320a45742e Mon Sep 17 00:00:00 2001 From: mektpoy Date: Thu, 22 Oct 2026 23:00:52 +0800 Subject: [PATCH] test(liveshare-protocol): round-trip the IPC fixtures with request tokens The v1 host/worker fixtures carried no registrationToken or token, so a legacy branch asserted them rejected and the optional-field case skipped them. They now carry valid tokens and round-trip through their codecs. The unknown access-mode fixture carries a token too, so its refusal is about the mode rather than the missing identity. The unread required lists are deleted; the optional lists now match what the parsers accept. --- .../host-to-worker--unknown-access-mode.json | 1 + .../v1/gateway-to-relay--share-rpc-res.json | 1 - .../v1/host-to-worker--add-share-minimal.json | 7 ++++--- .../frames/v1/host-to-worker--add-share.json | 6 +----- .../frames/v1/host-to-worker--remove-share.json | 1 - .../v1/host-to-worker--share-rpc-response.json | 12 +++--------- .../v1/relay-to-gateway--share-rpc-cancel.json | 1 - .../frames/v1/relay-to-gateway--share-rpc.json | 5 ----- .../tests/frames/v1/worker-to-host--ready.json | 1 - .../v1/worker-to-host--share-connected.json | 3 +-- .../frames/v1/worker-to-host--share-error.json | 3 +-- .../v1/worker-to-host--share-rpc-request.json | 5 +++-- .../tests/protocol-frames.spec.ts | 17 ++++++----------- 13 files changed, 20 insertions(+), 43 deletions(-) diff --git a/packages/experimental/liveshare-protocol/tests/frames/unknown/host-to-worker--unknown-access-mode.json b/packages/experimental/liveshare-protocol/tests/frames/unknown/host-to-worker--unknown-access-mode.json index 84e91b315c..d2bb46e136 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/unknown/host-to-worker--unknown-access-mode.json +++ b/packages/experimental/liveshare-protocol/tests/frames/unknown/host-to-worker--unknown-access-mode.json @@ -3,6 +3,7 @@ "note": "a share whose access mode is outside the closed enum fails the whole command instead of widening it", "frame": { "type": "add-share", + "registrationToken": "11111111-1111-4111-8111-111111111111", "share": { "shareId": "share-three", "sessionId": "session-three", diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/gateway-to-relay--share-rpc-res.json b/packages/experimental/liveshare-protocol/tests/frames/v1/gateway-to-relay--share-rpc-res.json index 0e6d0591e4..3a0c987181 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/gateway-to-relay--share-rpc-res.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/gateway-to-relay--share-rpc-res.json @@ -2,6 +2,5 @@ "dir": "gateway->relay", "note": "the owner's opaque answer to one routed request", "frame": { "type": "share-rpc-res", "id": 7, "status": 200, "body": { "ok": true } }, - "required": ["id", "status"], "optional": ["body"] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share-minimal.json b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share-minimal.json index 2be37e9757..25002fbece 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share-minimal.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share-minimal.json @@ -1,8 +1,9 @@ { "dir": "host->worker", - "note": "a share as a build without the optional spec fields publishes it: no sessionMode, no allowsFork, no deadline", + "note": "a share with only the required spec fields and the parser's default relay connection: no sessionMode, no allowsFork, no deadline", "frame": { "type": "add-share", + "registrationToken": "11111111-1111-4111-8111-111111111111", "share": { "shareId": "share-two", "sessionId": "session-two", @@ -11,9 +12,9 @@ "relay": "wss://relay.example", "gatewayToken": "token-two", "ownerDisplayName": "Owner", - "allowedSubjectIds": [] + "allowedSubjectIds": [], + "connection": { "mode": "relay" } } }, - "required": ["type", "share"], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share.json b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share.json index 2801b4e61b..05c159d2cc 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--add-share.json @@ -3,6 +3,7 @@ "note": "the owner host publishes one share to its gateway worker, every optional spec field present", "frame": { "type": "add-share", + "registrationToken": "11111111-1111-4111-8111-111111111111", "share": { "shareId": "share-one", "sessionId": "session-one", @@ -26,10 +27,5 @@ } } }, - "required": [ - "type", - "share", - "share.allowsFileUpload" - ], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--remove-share.json b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--remove-share.json index 158c57338f..5e95e57bb3 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--remove-share.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--remove-share.json @@ -2,6 +2,5 @@ "dir": "host->worker", "note": "the owner host withdraws one share", "frame": { "type": "remove-share", "shareId": "share-one" }, - "required": ["type", "shareId"], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--share-rpc-response.json b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--share-rpc-response.json index 901010f381..dac3c536da 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--share-rpc-response.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/host-to-worker--share-rpc-response.json @@ -3,6 +3,8 @@ "note": "the owner host hands its answer back for one in-flight request, naming the share it came through", "frame": { "type": "share-rpc-response", + "registrationToken": "11111111-1111-4111-8111-111111111111", + "token": "request-token", "id": 7, "status": 200, "body": { @@ -10,13 +12,5 @@ }, "shareId": "share-one" }, - "required": [ - "type", - "id", - "status" - ], - "optional": [ - "body", - "shareId" - ] + "optional": ["body"] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc-cancel.json b/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc-cancel.json index bfd4faf9f9..7598948726 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc-cancel.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc-cancel.json @@ -2,6 +2,5 @@ "dir": "relay->gateway", "note": "the reader left, so the Relay cancels one in-flight request", "frame": { "type": "share-rpc-cancel", "id": 8 }, - "required": ["id"], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc.json b/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc.json index 01af5a97f8..3e075b0ae6 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/relay-to-gateway--share-rpc.json @@ -16,10 +16,5 @@ "credential": "signed-owner-verified-token" } }, - "required": [ - "id", - "body", - "actor" - ], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--ready.json b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--ready.json index b521f5deb9..d36ff9191e 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--ready.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--ready.json @@ -2,6 +2,5 @@ "dir": "worker->host", "note": "the gateway worker is up", "frame": { "type": "ready" }, - "required": ["type"], "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-connected.json b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-connected.json index 1ae9d0084b..026be63a10 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-connected.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-connected.json @@ -1,7 +1,6 @@ { "dir": "worker->host", "note": "one share is registered on the Relay and reachable", - "frame": { "type": "share-connected", "shareId": "share-one" }, - "required": ["type", "shareId"], + "frame": { "type": "share-connected", "registrationToken": "11111111-1111-4111-8111-111111111111", "shareId": "share-one" }, "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-error.json b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-error.json index cf52fea83c..07e7133ff6 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-error.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-error.json @@ -1,7 +1,6 @@ { "dir": "worker->host", "note": "one share could not be carried, with the reason the worker read", - "frame": { "type": "share-error", "shareId": "share-one", "message": "relay refused registration status=401" }, - "required": ["type", "shareId", "message"], + "frame": { "type": "share-error", "registrationToken": "11111111-1111-4111-8111-111111111111", "shareId": "share-one", "message": "relay refused registration status=401" }, "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-rpc-request.json b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-rpc-request.json index 4f664debdd..db35cc8fc4 100644 --- a/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-rpc-request.json +++ b/packages/experimental/liveshare-protocol/tests/frames/v1/worker-to-host--share-rpc-request.json @@ -3,11 +3,12 @@ "note": "the gateway worker reports one routed request, with the identity the Relay asserted", "frame": { "type": "share-rpc-request", + "registrationToken": "11111111-1111-4111-8111-111111111111", + "token": "request-token", "id": 7, "shareId": "share-one", "body": { "op": "stream-open", "id": 1, "endpoint": "trajectory", "payload": {} }, "actor": { "providerId": "example", "tenantId": "tenant-a", "subjectId": "user_viewer" } }, - "required": ["type", "id", "shareId", "actor"], - "optional": ["body"] + "optional": [] } diff --git a/packages/experimental/liveshare-protocol/tests/protocol-frames.spec.ts b/packages/experimental/liveshare-protocol/tests/protocol-frames.spec.ts index c51f41ae3f..0fde0010fc 100644 --- a/packages/experimental/liveshare-protocol/tests/protocol-frames.spec.ts +++ b/packages/experimental/liveshare-protocol/tests/protocol-frames.spec.ts @@ -1,4 +1,4 @@ -/** Relay wire v1 remains compatible; same-package Host/worker IPC requires request tokens. */ +/** Relay wire version 1; same-package Host/worker IPC requires request tokens. */ import { readdirSync, readFileSync } from 'node:fs' import { join } from 'node:path' @@ -16,20 +16,18 @@ import { /** Which two endpoints exchanged a recorded frame, which also names the codec that reads it. */ type Direction = 'relay->gateway' | 'gateway->relay' | 'host->worker' | 'worker->host' -/** One frame recorded from a released build, with the fields that version may omit. */ +/** One frame the current build exchanges, with the fields it may omit. */ interface RecordedFrame { readonly dir: Direction readonly note: string readonly frame: Record /** Raw socket text, when the recording pins bytes rather than the frame's fields. */ readonly text?: string - /** Top-level fields this build always sent. */ - readonly required: readonly string[] - /** Top-level fields this build sent only when it had something to say. */ + /** Top-level fields this build sends only when it has something to say. */ readonly optional?: readonly string[] } -/** One frame this build must refuse: a later release's addition, or a value the vocabulary rejects. */ +/** One frame this build must refuse: a later build's addition, or a value the vocabulary rejects. */ interface RefusedFrame { readonly dir: Direction readonly note: string @@ -97,12 +95,9 @@ function withoutField(frame: Record, field: string): Record { - it('reads released Relay frames and rejects superseded same-package IPC identity', () => { + it('round-trips every current frame through the codec its direction names', () => { for (const recorded of readFrames('v1')) { - const legacyIdentity = (recorded.dir === 'host->worker' || recorded.dir === 'worker->host') - && recorded.frame.type !== 'ready' && recorded.frame.type !== 'remove-share' - if (legacyIdentity) expect(parseFrame(recorded.dir, wireText(recorded)), recorded.note).toBeUndefined() - else expect(parseFrame(recorded.dir, wireText(recorded)), recorded.note).toEqual(recorded.frame) + expect(parseFrame(recorded.dir, wireText(recorded)), recorded.note).toEqual(recorded.frame) } })