52 lines
2.0 KiB
TypeScript
52 lines
2.0 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 displaced first
|
|
// computer does not affect the live registration, and a gateway->computer ping is
|
|
// still answered by the newest computer.
|
|
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", "60"],
|
|
});
|
|
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));
|
|
|
|
first.abort();
|
|
await first.done.catch(() => undefined);
|
|
const payload = await sandbox.registry.request("local", TRAPOS_ID, "ping", {}, 2_000);
|
|
assert.deepEqual(payload, { traposId: TRAPOS_ID }, "newest stayed registered after first exited");
|
|
} 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();
|
|
}
|
|
});
|