test: cover server restart session recovery
This commit is contained in:
@@ -193,6 +193,103 @@ describe("YNX-1105e: Server state recovery", () => {
|
|||||||
await secondRuntime.stop();
|
await secondRuntime.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("SR-02: restart drops in-memory active sessions and requires reconnect", async () => {
|
||||||
|
const storePath = await createTempServerStorePath();
|
||||||
|
const store = createYonexusServerStore(storePath);
|
||||||
|
const now = 1_710_000_000;
|
||||||
|
|
||||||
|
const firstTransport = createMockTransport();
|
||||||
|
const firstRuntime = createYonexusServerRuntime({
|
||||||
|
config: {
|
||||||
|
followerIdentifiers: ["client-a"],
|
||||||
|
notifyBotToken: "stub-token",
|
||||||
|
adminUserId: "admin-user",
|
||||||
|
listenHost: "127.0.0.1",
|
||||||
|
listenPort: 8787
|
||||||
|
},
|
||||||
|
store,
|
||||||
|
transport: firstTransport.transport,
|
||||||
|
now: () => now
|
||||||
|
});
|
||||||
|
|
||||||
|
await firstRuntime.start();
|
||||||
|
const record = firstRuntime.state.registry.clients.get("client-a");
|
||||||
|
expect(record).toBeDefined();
|
||||||
|
|
||||||
|
record!.pairingStatus = "paired";
|
||||||
|
record!.publicKey = "test-public-key";
|
||||||
|
record!.secret = "test-secret";
|
||||||
|
record!.status = "online";
|
||||||
|
record!.lastAuthenticatedAt = now;
|
||||||
|
record!.lastHeartbeatAt = now;
|
||||||
|
record!.updatedAt = now;
|
||||||
|
|
||||||
|
firstRuntime.state.registry.sessions.set("client-a", {
|
||||||
|
identifier: "client-a",
|
||||||
|
socket: createMockSocket(),
|
||||||
|
isAuthenticated: true,
|
||||||
|
connectedAt: now,
|
||||||
|
lastActivityAt: now,
|
||||||
|
publicKey: "test-public-key"
|
||||||
|
});
|
||||||
|
|
||||||
|
await firstRuntime.stop();
|
||||||
|
|
||||||
|
const secondTransport = createMockTransport();
|
||||||
|
const secondRuntime = createYonexusServerRuntime({
|
||||||
|
config: {
|
||||||
|
followerIdentifiers: ["client-a"],
|
||||||
|
notifyBotToken: "stub-token",
|
||||||
|
adminUserId: "admin-user",
|
||||||
|
listenHost: "127.0.0.1",
|
||||||
|
listenPort: 8787
|
||||||
|
},
|
||||||
|
store,
|
||||||
|
transport: secondTransport.transport,
|
||||||
|
now: () => now + 5
|
||||||
|
});
|
||||||
|
|
||||||
|
await secondRuntime.start();
|
||||||
|
|
||||||
|
const reloadedRecord = secondRuntime.state.registry.clients.get("client-a");
|
||||||
|
expect(reloadedRecord).toMatchObject({
|
||||||
|
identifier: "client-a",
|
||||||
|
pairingStatus: "paired",
|
||||||
|
secret: "test-secret",
|
||||||
|
publicKey: "test-public-key",
|
||||||
|
status: "online",
|
||||||
|
lastAuthenticatedAt: now,
|
||||||
|
lastHeartbeatAt: now
|
||||||
|
});
|
||||||
|
expect(secondRuntime.state.registry.sessions.size).toBe(0);
|
||||||
|
|
||||||
|
const reconnectConnection = createConnection();
|
||||||
|
await secondRuntime.handleMessage(
|
||||||
|
reconnectConnection,
|
||||||
|
encodeBuiltin(
|
||||||
|
buildHello(
|
||||||
|
{
|
||||||
|
identifier: "client-a",
|
||||||
|
hasSecret: true,
|
||||||
|
hasKeyPair: true,
|
||||||
|
publicKey: "test-public-key",
|
||||||
|
protocolVersion: YONEXUS_PROTOCOL_VERSION
|
||||||
|
},
|
||||||
|
{ requestId: "req-hello-reconnect", timestamp: now + 5 }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const helloAck = decodeBuiltin(secondTransport.sentToConnection[0].message);
|
||||||
|
expect(helloAck.type).toBe("hello_ack");
|
||||||
|
expect(helloAck.payload).toMatchObject({
|
||||||
|
identifier: "client-a",
|
||||||
|
nextAction: "auth_required"
|
||||||
|
});
|
||||||
|
|
||||||
|
await secondRuntime.stop();
|
||||||
|
});
|
||||||
|
|
||||||
it("SR-05: corrupted server store raises YonexusServerStoreCorruptionError", async () => {
|
it("SR-05: corrupted server store raises YonexusServerStoreCorruptionError", async () => {
|
||||||
const storePath = await createTempServerStorePath();
|
const storePath = await createTempServerStorePath();
|
||||||
await writeFile(storePath, '{"version":1,"clients":"oops"}\n', "utf8");
|
await writeFile(storePath, '{"version":1,"clients":"oops"}\n', "utf8");
|
||||||
|
|||||||
Reference in New Issue
Block a user