socketduct 0.1.25 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -2
- package/changelog.d/20261010130509-bound-log-frame-compression-memory.md +1 -0
- package/docs/runbooks/jsonl-integrity-rollout.md +8 -6
- package/package.json +2 -2
- package/scripts/test.js +9 -14
- package/src/logging/compressed-log-writer.js +1 -1
- package/src/logging/zstd-frame-codec.js +15 -1
- package/test/e2e/gateway-process.test.js +93 -92
- package/test/e2e/logger-shutdown-process.test.js +40 -37
- package/test/e2e/reverse-client-recovery-process.test.js +107 -103
- package/test/e2e/reverse-gateway-process.test.js +328 -318
- package/test/integration/initial-target-recovery.test.js +333 -334
- package/test/integration/logging-cli.test.js +121 -119
- package/test/integration/logging-compressed-recovery.test.js +96 -95
- package/test/integration/multiplexed-compatibility.test.js +178 -177
- package/test/integration/multiplexed-corrections.test.js +360 -359
- package/test/integration/multiplexed-failures.test.js +253 -251
- package/test/integration/multiplexed-transport-set.test.js +334 -322
- package/test/integration/multiplexed-transport.test.js +135 -134
- package/test/integration/reverse-gateway-stream-id-reset.test.js +90 -89
- package/test/integration/reverse-gateway.test.js +2309 -2218
- package/test/integration/reverse-resume-continuity.test.js +219 -218
- package/test/integration/reverse-route-class.test.js +358 -341
- package/test/integration/socketduct-http-agent.test.js +314 -312
- package/test/integration/socketduct-https-agent.test.js +516 -485
- package/test/integration/stream-compression.test.js +862 -824
- package/test/integration/tcp-forwarding.test.js +2550 -2447
- package/test/integration/tls-forwarding.test.js +593 -592
- package/test/unit/auth/auth.test.js +43 -44
- package/test/unit/auth/static-token-store.test.js +9 -8
- package/test/unit/client/connect.test.js +41 -40
- package/test/unit/client/deferred-virtual-socket.test.js +95 -94
- package/test/unit/client/multiplexed-spool-budget.test.js +155 -154
- package/test/unit/client/multiplexed-transport-set.test.js +830 -748
- package/test/unit/client/socketduct-socket.test.js +768 -771
- package/test/unit/client/virtual-socket.test.js +198 -168
- package/test/unit/config/docker-gateway-files.test.js +224 -224
- package/test/unit/config/environment.test.js +472 -492
- package/test/unit/index.test.js +53 -52
- package/test/unit/logging/compressed-log-worker.test.js +23 -22
- package/test/unit/logging/compressed-log-writer.test.js +155 -154
- package/test/unit/logging/log-retention.test.js +52 -47
- package/test/unit/logging/log-segment-index.test.js +84 -81
- package/test/unit/logging/zstd-frame-codec.test.js +28 -19
- package/test/unit/protocol/compression.test.js +254 -298
- package/test/unit/protocol/frame.test.js +280 -276
- package/test/unit/protocol/v3-compression.test.js +21 -23
- package/test/unit/protocol/v3-frame.test.js +42 -41
- package/test/unit/release-configuration.test.js +15 -12
- package/test/unit/reverse/disconnect-attribution.test.js +65 -64
- package/test/unit/reverse-terminal-outcomes.test.js +53 -50
- package/test/unit/server/control-handler.test.js +232 -231
- package/test/unit/server/primary.test.js +51 -49
- package/test/unit/server/relay-runtime.test.js +280 -294
- package/test/unit/sessions/session.test.js +48 -62
- package/test/unit/spool/spool-file.test.js +401 -385
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import test from "node:test"
|
|
1
|
+
import {describe, expect, it} from "@velocious/testing"
|
|
3
2
|
|
|
4
3
|
import {
|
|
5
4
|
createSession,
|
|
@@ -8,77 +7,64 @@ import {
|
|
|
8
7
|
SessionStore
|
|
9
8
|
} from "../../../src/sessions/session.js"
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
describe("session store", () => {
|
|
11
|
+
it("createSession creates a named creating session with an opaque identifier", () => {
|
|
12
|
+
const session = createSession({name: "Office link", ownerId: "user-1", target: {host: "127.0.0.1", port: 22}})
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
})
|
|
14
|
+
expect(session.name).toBe("Office link")
|
|
15
|
+
expect(session.ownerId).toBe("user-1")
|
|
16
|
+
expect(session.state).toBe("creating")
|
|
17
|
+
expect(session.identifier).toMatch(/^[a-zA-Z0-9_-]{32,}$/)
|
|
18
|
+
expect(session.clientSequence).toBe(0)
|
|
19
|
+
expect(session.relaySequence).toBe(0)
|
|
20
|
+
expect(session.target).toEqual({host: "127.0.0.1", port: 22})
|
|
21
|
+
})
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
it("transitionSession only allows legal lifecycle transitions", () => {
|
|
24
|
+
const session = createSession({name: "Flaky line", ownerId: "user-1", target: {host: "127.0.0.1", port: 22}, identifier: "session_123456789012345678901234567890"})
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
expect(transitionSession(session, "active").state).toBe("active")
|
|
27
|
+
expect(transitionSession({...session, state: "interrupted"}, "resuming").state).toBe("resuming")
|
|
28
|
+
expect(transitionSession({...session, state: "resuming"}, "active").state).toBe("active")
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
/illegal session state transition/i
|
|
33
|
-
)
|
|
34
|
-
})
|
|
30
|
+
expect(() => transitionSession({...session, state: "active"}, "resuming")).toThrow(/illegal session state transition/i)
|
|
31
|
+
})
|
|
35
32
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
it("SessionStore resumes sessions by identifier for the owning user", () => {
|
|
34
|
+
const store = new SessionStore()
|
|
35
|
+
const session = store.create({name: "Müggelheim relay", ownerId: "kasper", target: {host: "127.0.0.1", port: 22}})
|
|
36
|
+
store.transition(session.identifier, "active")
|
|
37
|
+
store.transition(session.identifier, "interrupted")
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
const resumed = resumeSession(store, {
|
|
40
|
+
identifier: session.identifier,
|
|
41
|
+
ownerId: "kasper"
|
|
42
|
+
})
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})
|
|
44
|
+
expect(resumed.identifier).toBe(session.identifier)
|
|
45
|
+
expect(resumed.state).toBe("resuming")
|
|
46
|
+
})
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
it("SessionStore rejects resume for a missing or expired session", () => {
|
|
49
|
+
const store = new SessionStore({now: () => 2_000})
|
|
50
|
+
store.create({name: "Expired", ownerId: "user-1", target: {host: "127.0.0.1", port: 22}, identifier: "expired_session_12345678901234567890", expiresAt: 1_000})
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
() => resumeSession(store, {identifier: "
|
|
57
|
-
|
|
58
|
-
)
|
|
59
|
-
assert.throws(
|
|
60
|
-
() => resumeSession(store, {identifier: "expired_session_12345678901234567890", ownerId: "user-1"}),
|
|
61
|
-
/expired/i
|
|
62
|
-
)
|
|
63
|
-
})
|
|
52
|
+
expect(() => resumeSession(store, {identifier: "missing_session_12345678901234567890", ownerId: "user-1"})).toThrow(/not found/i)
|
|
53
|
+
expect(() => resumeSession(store, {identifier: "expired_session_12345678901234567890", ownerId: "user-1"})).toThrow(/expired/i)
|
|
54
|
+
})
|
|
64
55
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
it("SessionStore rejects resume while initial target acquisition is still creating", () => {
|
|
57
|
+
const store = new SessionStore()
|
|
58
|
+
const session = store.create({name: "Pending", ownerId: "user-1", target: {host: "127.0.0.1", port: 22}})
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
(
|
|
71
|
-
|
|
72
|
-
)
|
|
73
|
-
assert.equal(store.get(session.identifier)?.state, "creating")
|
|
74
|
-
})
|
|
60
|
+
expect(() => resumeSession(store, {identifier: session.identifier, ownerId: "user-1"})).toThrow(/not resumable/i)
|
|
61
|
+
expect(store.get(session.identifier)?.state).toBe("creating")
|
|
62
|
+
})
|
|
75
63
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
it("SessionStore prevents a different user from resuming a session", () => {
|
|
65
|
+
const store = new SessionStore()
|
|
66
|
+
const session = store.create({name: "Private", ownerId: "owner", target: {host: "127.0.0.1", port: 22}})
|
|
79
67
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/does not belong/i
|
|
83
|
-
)
|
|
68
|
+
expect(() => resumeSession(store, {identifier: session.identifier, ownerId: "other-user"})).toThrow(/does not belong/i)
|
|
69
|
+
})
|
|
84
70
|
})
|