191 lines
7.7 KiB
JavaScript
191 lines
7.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import { DatabaseSync } from "node:sqlite";
|
|
import test from "node:test";
|
|
import {
|
|
ADMIN_HOST_CONTROL_PLANE_ATTENTION_SQL,
|
|
ADMIN_HOST_CONTROL_PLANE_SUMMARY_SQL,
|
|
CONTROL_PLANE_CONTACT_DELAYED_MS,
|
|
CONTROL_PLANE_CONTACT_FRESH_MS,
|
|
OWNED_HOSTS_WITH_CONTROL_PLANE_CONTACT_SQL,
|
|
controlPlaneContactCutoffs,
|
|
deriveAdminHostControlPlaneSnapshot,
|
|
deriveControlPlaneContact,
|
|
} from "../db/device-control-plane.ts";
|
|
|
|
test("derives honest control-plane contact states without claiming relay presence", () => {
|
|
const now = Date.parse("2026-08-12T12:00:00.000Z");
|
|
assert.equal(deriveControlPlaneContact(null, now).state, "never");
|
|
assert.equal(
|
|
deriveControlPlaneContact(new Date(now - CONTROL_PLANE_CONTACT_FRESH_MS).toISOString(), now).state,
|
|
"fresh",
|
|
);
|
|
assert.equal(
|
|
deriveControlPlaneContact(new Date(now - CONTROL_PLANE_CONTACT_FRESH_MS - 1).toISOString(), now).state,
|
|
"delayed",
|
|
);
|
|
assert.equal(
|
|
deriveControlPlaneContact(new Date(now - CONTROL_PLANE_CONTACT_DELAYED_MS).toISOString(), now).state,
|
|
"delayed",
|
|
);
|
|
assert.equal(
|
|
deriveControlPlaneContact(new Date(now - CONTROL_PLANE_CONTACT_DELAYED_MS - 1).toISOString(), now).state,
|
|
"stale",
|
|
);
|
|
assert.equal(deriveControlPlaneContact("not-a-time", now).state, "invalid");
|
|
assert.equal(
|
|
deriveControlPlaneContact(new Date(now + 6 * 60 * 1_000).toISOString(), now).state,
|
|
"invalid",
|
|
);
|
|
});
|
|
|
|
test("uses the latest successful device credential use as a derived control-plane check-in", () => {
|
|
const db = new DatabaseSync(":memory:");
|
|
db.exec(`
|
|
CREATE TABLE hosts (
|
|
id TEXT PRIMARY KEY, account_id TEXT NOT NULL, lifecycle TEXT NOT NULL,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
CREATE TABLE device_credentials (
|
|
id TEXT PRIMARY KEY, host_id TEXT NOT NULL, last_used_at TEXT
|
|
);
|
|
INSERT INTO hosts VALUES
|
|
('host_active', 'acct_owner', 'active', '2026-08-12T10:00:00.000Z'),
|
|
('host_never', 'acct_owner', 'active', '2026-08-12T11:00:00.000Z'),
|
|
('host_other', 'acct_other', 'active', '2026-08-12T11:30:00.000Z');
|
|
INSERT INTO device_credentials VALUES
|
|
('credential_old', 'host_active', '2026-08-12T10:10:00.000Z'),
|
|
('credential_current', 'host_active', '2026-08-12T11:55:00.000Z'),
|
|
('credential_other', 'host_other', '2026-08-12T11:59:00.000Z');
|
|
`);
|
|
const rows = db.prepare(OWNED_HOSTS_WITH_CONTROL_PLANE_CONTACT_SQL).all("acct_owner");
|
|
assert.deepEqual(
|
|
rows.map((row) => ({ id: row.id, lastSeen: row.control_plane_last_seen_at })),
|
|
[
|
|
{ id: "host_never", lastSeen: null },
|
|
{ id: "host_active", lastSeen: "2026-08-12T11:55:00.000Z" },
|
|
],
|
|
);
|
|
db.close();
|
|
});
|
|
|
|
test("aggregates every active host and bounds the administrator attention list", () => {
|
|
const db = new DatabaseSync(":memory:");
|
|
db.exec(`
|
|
CREATE TABLE accounts (id TEXT PRIMARY KEY, email TEXT NOT NULL);
|
|
CREATE TABLE hosts (
|
|
id TEXT PRIMARY KEY, account_id TEXT NOT NULL, name TEXT NOT NULL,
|
|
os TEXT NOT NULL, lifecycle TEXT NOT NULL, slot_state TEXT NOT NULL,
|
|
daemon_version TEXT
|
|
);
|
|
CREATE TABLE device_credentials (
|
|
id TEXT PRIMARY KEY, host_id TEXT NOT NULL, last_used_at TEXT
|
|
);
|
|
INSERT INTO accounts VALUES ('acct', 'owner@example.test');
|
|
INSERT INTO hosts VALUES
|
|
('host_fresh', 'acct', 'Fresh', 'windows', 'active', 'active', '0.2.6'),
|
|
('host_delayed', 'acct', 'Delayed', 'linux', 'active', 'active', NULL),
|
|
('host_stale', 'acct', 'Stale', 'linux', 'active', 'active', '0.2.6'),
|
|
('host_never', 'acct', 'Never', 'windows', 'active', 'active', NULL),
|
|
('host_invalid', 'acct', 'Invalid', 'linux', 'active', 'active', '0.2.6'),
|
|
('host_revoked', 'acct', 'Revoked', 'linux', 'deactivated', 'released', '0.2.6');
|
|
INSERT INTO device_credentials VALUES
|
|
('credential_fresh', 'host_fresh', '2026-08-12T11:55:00.000Z'),
|
|
('credential_delayed', 'host_delayed', '2026-08-12T11:40:00.000Z'),
|
|
('credential_stale', 'host_stale', '2026-08-12T10:00:00.000Z'),
|
|
('credential_invalid', 'host_invalid', '2026-08-12T12:06:00.000Z'),
|
|
('credential_revoked', 'host_revoked', '2026-08-12T11:59:00.000Z');
|
|
`);
|
|
const generatedAt = "2026-08-12T12:00:00.000Z";
|
|
const cutoffs = controlPlaneContactCutoffs(generatedAt);
|
|
const parameters = [cutoffs.futureLimitAt, cutoffs.freshCutoff, cutoffs.delayedCutoff];
|
|
const summary = {
|
|
...db.prepare(ADMIN_HOST_CONTROL_PLANE_SUMMARY_SQL).get(...parameters),
|
|
};
|
|
const attentionHosts = db
|
|
.prepare(ADMIN_HOST_CONTROL_PLANE_ATTENTION_SQL)
|
|
.all(...parameters);
|
|
const snapshot = deriveAdminHostControlPlaneSnapshot({
|
|
generatedAt,
|
|
summary,
|
|
attentionHosts,
|
|
});
|
|
assert.deepEqual(
|
|
{
|
|
totalActive: snapshot.totalActive,
|
|
fresh: snapshot.fresh,
|
|
delayed: snapshot.delayed,
|
|
stale: snapshot.stale,
|
|
never: snapshot.never,
|
|
invalid: snapshot.invalid,
|
|
versionUnknown: snapshot.versionUnknown,
|
|
},
|
|
{
|
|
totalActive: 5,
|
|
fresh: 1,
|
|
delayed: 1,
|
|
stale: 1,
|
|
never: 1,
|
|
invalid: 1,
|
|
versionUnknown: 2,
|
|
},
|
|
);
|
|
assert.deepEqual(
|
|
snapshot.attentionHosts.map((host) => [host.id, host.contact_state]),
|
|
[
|
|
["host_invalid", "invalid"],
|
|
["host_never", "never"],
|
|
["host_stale", "stale"],
|
|
["host_delayed", "delayed"],
|
|
],
|
|
);
|
|
const insertHost = db.prepare(
|
|
`INSERT INTO hosts
|
|
(id, account_id, name, os, lifecycle, slot_state, daemon_version)
|
|
VALUES (?, 'acct', ?, 'linux', 'active', 'active', '0.2.6')`,
|
|
);
|
|
const insertCredential = db.prepare(
|
|
"INSERT INTO device_credentials (id, host_id, last_used_at) VALUES (?, ?, '2026-08-12T10:00:00.000Z')",
|
|
);
|
|
for (let index = 0; index < 30; index += 1) {
|
|
const suffix = String(index).padStart(2, "0");
|
|
const hostId = `host_bulk_${suffix}`;
|
|
insertHost.run(hostId, `Bulk ${suffix}`);
|
|
insertCredential.run(`credential_bulk_${suffix}`, hostId);
|
|
}
|
|
const boundedAttention = db
|
|
.prepare(ADMIN_HOST_CONTROL_PLANE_ATTENTION_SQL)
|
|
.all(...parameters);
|
|
assert.equal(boundedAttention.length, 25);
|
|
assert.deepEqual(
|
|
boundedAttention.slice(0, 2).map((host) => host.contact_state),
|
|
["invalid", "never"],
|
|
);
|
|
db.close();
|
|
});
|
|
|
|
test("labels user and administrator signals as Cloud contact instead of relay online", async () => {
|
|
const [dashboard, hosts, admin, repository, stateModel, operationsDoc, plan] = await Promise.all([
|
|
readFile(new URL("../app/dashboard/page.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../app/dashboard/hosts/page.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../app/admin/page.tsx", import.meta.url), "utf8"),
|
|
readFile(new URL("../db/repository.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../docs/state-model.md", import.meta.url), "utf8"),
|
|
readFile(new URL("../docs/beta-operations.md", import.meta.url), "utf8"),
|
|
readFile(new URL("../docs/implementation-plan.md", import.meta.url), "utf8"),
|
|
]);
|
|
assert.match(repository, /OWNED_HOSTS_WITH_CONTROL_PLANE_CONTACT_SQL/);
|
|
assert.match(dashboard, /deriveControlPlaneContact/);
|
|
assert.match(hosts, /控制面签到/);
|
|
assert.match(hosts, /是否在线仍以共享 Relay 的实时连接为准/);
|
|
assert.doesNotMatch(hosts, /host\.connection_state === "online"/);
|
|
assert.match(admin, /主机控制面签到/);
|
|
assert.match(admin, /最多列出 25 台非正常主机/);
|
|
assert.match(admin, /只证明 daemon 已通过控制面鉴权/);
|
|
assert.match(admin, /不单独证明长连接、重连或 sealed 会话质量/);
|
|
assert.match(stateModel, /last_used_at/);
|
|
assert.match(stateModel, /不证明.*relay/);
|
|
assert.match(operationsDoc, /后台区分 active、延迟、offline/);
|
|
assert.match(plan, /管理员后台即时汇总启用主机的控制面签到/);
|
|
});
|