cc-libs/tools/trap-sandbox/test-integration/duplicate.test.ts

53 lines
2.1 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import { formatFailure, startCraftos, startSandbox, waitFor } from "./harness.js";
// Two real computers with the same traposId (id:label): newest-wins. After both
// complete hello, exactly one registration exists; aborting the newest clears it
// (the displaced first computer is in its 5s reconnect backoff), proving the newest
// connection is the one that's registered.
test("duplicate traposId is resolved newest-wins", async () => {
const sandbox = await startSandbox();
const TRAPOS_ID = "9:dup";
const first = startCraftos("gateway-client.lua", {
computerId: 9,
computerLabel: "dup",
shellArgs: [sandbox.baseUrl, "-", "idle"],
});
const second = startCraftos("gateway-client.lua", {
computerId: 9,
computerLabel: "dup",
shellArgs: [sandbox.baseUrl, "-", "idle"],
});
try {
await waitFor(() => first.snapshot().includes("__SANDBOX_READY__"), 12_000, "first connected");
assert.ok(sandbox.registry.has("local", TRAPOS_ID), "first should be registered");
await waitFor(() => second.snapshot().includes("__SANDBOX_READY__"), 12_000, "second connected");
// Newest-wins: still exactly one registration for the shared id.
assert.equal(sandbox.registry.count(), 1, "exactly one registration after the duplicate");
assert.ok(sandbox.registry.has("local", TRAPOS_ID));
// Aborting the newest clears the entry; the displaced first is in reconnect
// backoff (~5s) and has not re-registered yet.
second.abort();
await second.done.catch(() => undefined);
await waitFor(() => sandbox.registry.count() === 0, 3_000, "newest was the live registration");
} catch (error) {
throw new Error(
formatFailure(
error instanceof Error ? error.message : String(error),
`first:\n${first.snapshot()}\nsecond:\n${second.snapshot()}`,
),
{ cause: error },
);
} finally {
first.abort();
second.abort();
await Promise.all([first.done.catch(() => undefined), second.done.catch(() => undefined)]);
await sandbox.close();
}
});