Publish curated ITWorx-ModelForge source from 990401737f96c8d46a9f7b0d84994516cadcb6a0

This commit is contained in:
Public Source Publisher committed 2026-09-30 09:23:17 +00:00
1 parent 7082ab955a
commit 848f0d8f8a
434 files changed
+67298 -4315

No files matched your search

@@ -0,0 +1,724 @@
import { act, cleanup, fireEvent, render, screen } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { HardwareWorkspace } from "./HardwareWorkspace";
import { api, clearOperatorCredential, controlPlaneOriginForAgent, setOperatorCredential } from "../lib/api";
import type { HardwareState, NodeState, ObservedValue } from "../types";
const known = <T,>(value: T): ObservedValue<T> => ({ value, availability: "known" });
function node(id: string, hostname: string): NodeState {
return {
id, generation: 1, identity_key: `identity-${id}`, identity_source: "persisted_uuid", hostname,
display_name: `Display ${hostname}`, status: "active", os_name: "Linux", os_version: known("test"),
architecture: "x86_64", kernel_version: known("6.6"), cpu_model: known("Test CPU"),
logical_cpu_count: known(16), physical_core_count: known(8), total_ram_bytes: known(32 * 1024 ** 3),
available_ram_bytes: known(20 * 1024 ** 3), agent_version: "0.1.0", first_seen_at: "2026-09-01T00:00:00Z",
last_seen_at: "2026-09-01T00:00:00Z", inventory_at: "2026-09-01T00:00:00Z", hardware_fingerprint: "a".repeat(64),
enabled: true, liveness: "online", agent_health: "healthy", observation_source: "remote_agent", protocol_version: 1,
supported_capabilities: ["hardware.inventory"], last_heartbeat_at: "2026-09-01T00:00:00Z", labels: {},
production_eligible: false, lab_eligible: true, benchmark_eligible: false, storage: [], accelerators: [],
telemetry_age_seconds: null, inventory_age_seconds: null, role: "worker",
};
}
const hardware: HardwareState = {
overview: { status: "active", inventory_state: "active", node_count: 2, accelerator_count: 0 },
nodes: [node("node-a", "host-a"), node("node-b", "host-b")],
};
function lifecyclePreview(overrides: Partial<{
current_enabled: boolean; current_liveness: NodeState["liveness"]; target_enabled: boolean;
node_generation: number; can_apply: boolean; blockers: { code: string; message: string; record_type: string; count: number; resource_ids: string[] }[];
agent_evidence_after_enable: "unchanged" | "awaiting_fresh_authenticated_heartbeat";
}> = {}) {
return {
node_id: "node-a", persisted_identity: "identity-node-a", hostname: "host-a", display_name: "Display host-a",
current_enabled: true, current_liveness: "online" as const, target_enabled: false, node_generation: 1,
dependency_digest: "d".repeat(64), can_apply: true, blockers: [], agent_evidence_after_enable: "unchanged" as const,
...overrides,
};
}
const candidateImage = "modelforge-node-agent:1.3.0-rc.1";
const candidateRevision = "a".repeat(40);
const candidateLayers = [`sha256:${"1".repeat(64)}`, `sha256:${"2".repeat(64)}`];
const candidateBuildHostImageId = `sha256:${"b".repeat(64)}`;
const candidateManifestEntry = JSON.stringify({
tag: candidateImage,
image_id: candidateBuildHostImageId,
image_digest: null,
repo_digest: null,
architecture: "amd64",
labels: {
"org.opencontainers.image.title": "ITWorx ModelForge node agent",
"org.opencontainers.image.description": "Outbound-only compute node agent for ITWorx ModelForge",
"org.opencontainers.image.version": "1.3.0-rc.1",
"org.opencontainers.image.revision": candidateRevision,
"org.opencontainers.image.created": "2026-09-24T00:00:00Z",
"org.opencontainers.image.source": "ssh://git@example.invalid/model-forge.git",
"org.opencontainers.image.vendor": "ITWorx",
"org.opencontainers.image.licenses": "AGPL-3.0-or-later",
},
rootfs_layers: candidateLayers,
});
function selectCandidateBundleImage(): void {
fireEvent.change(screen.getByLabelText(/Node Agent image entry from the release manifest/i), { target: { value: candidateManifestEntry } });
}
afterEach(() => {
cleanup();
clearOperatorCredential();
vi.restoreAllMocks();
vi.useRealTimers();
});
describe("HardwareWorkspace Quick Jump target", () => {
it("tracks target changes in the same mount and never falls back for a missing ID", () => {
const props = { hardware, role: "admin" as const, onNavigate: vi.fn(), onChanged: vi.fn(), onError: vi.fn() };
const view = render(<HardwareWorkspace {...props} targetNodeId="node-a" />);
expect(screen.getByRole("heading", { name: "host-a" })).toBeInTheDocument();
view.rerender(<HardwareWorkspace {...props} targetNodeId="node-b" />);
expect(screen.getByRole("heading", { name: "host-b" })).toBeInTheDocument();
expect(screen.queryByRole("heading", { name: "host-a" })).not.toBeInTheDocument();
view.rerender(<HardwareWorkspace {...props} targetNodeId="missing-node" />);
expect(screen.getByRole("status")).toHaveTextContent(/Node missing-node is not in the loaded hardware index/i);
expect(screen.queryByRole("heading", { name: "host-a" })).not.toBeInTheDocument();
expect(screen.queryByRole("heading", { name: "host-b" })).not.toBeInTheDocument();
view.rerender(<HardwareWorkspace {...props} targetNodeId="node-a" />);
expect(screen.getByRole("heading", { name: "host-a" })).toBeInTheDocument();
});
it.each(["viewer", "operator"] as const)("hides node lifecycle and credential recovery actions from %s", (role) => {
render(<HardwareWorkspace role={role} hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
expect(screen.getByText(/Node lifecycle actions are restricted to administrators/i)).toBeInTheDocument();
expect(screen.getByText(/Credential recovery is restricted to administrators/i)).toBeInTheDocument();
expect(screen.getByText(/Node decommission is restricted to administrators/i)).toBeInTheDocument();
expect(screen.queryByRole("button", { name: /Rotate node credential/i })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: /Impact controleren/i })).not.toBeInTheDocument();
});
it("requires an impact review, operator, reason and exact identity before disabling a node", async () => {
const updatedHardware: HardwareState = {
...hardware,
nodes: hardware.nodes.map((item) => item.id === "node-a" ? { ...item, enabled: false, liveness: "disabled" } : item),
};
const fetchMock = vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => {
const url = String(input);
if (url.endsWith("/api/v1/admin/hardware/nodes/node-a/lifecycle/preview")) {
return new Response(JSON.stringify(lifecyclePreview()), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/admin/hardware/nodes/node-a/lifecycle")) {
return new Response(JSON.stringify({ node_id: "node-a", enabled: false, generation: 2, liveness: "disabled", agent_evidence_state: "unchanged" }), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) {
return new Response(JSON.stringify(updatedHardware), { status: 200, headers: { "Content-Type": "application/json" } });
}
return new Response("not found", { status: 404 });
});
const onChanged = vi.fn();
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={onChanged} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Review disable impact/i }));
expect(await screen.findByText(/No blocking dependencies found/i)).toBeInTheDocument();
expect(fetchMock).toHaveBeenCalledTimes(1);
const confirmButton = screen.getByRole("button", { name: /Confirm disable/i });
expect(confirmButton).toBeDisabled();
fireEvent.change(screen.getByLabelText(/Operator identity/i), { target: { value: "Jens" } });
fireEvent.change(screen.getByLabelText(/Reason/i), { target: { value: "Planned hardware maintenance after draining workloads." } });
fireEvent.change(screen.getByLabelText(/Type the persisted node identity/i), { target: { value: "wrong-node" } });
expect(confirmButton).toBeDisabled();
fireEvent.change(screen.getByLabelText(/Type the persisted node identity/i), { target: { value: "identity-node-a" } });
expect(confirmButton).toBeEnabled();
fireEvent.click(confirmButton);
expect(await screen.findByRole("status")).toHaveTextContent(/Node disabled/i);
expect(screen.getByRole("status")).toHaveTextContent(/reject agent heartbeats/i);
const lifecycleCalls = fetchMock.mock.calls.filter(([input]) => String(input).endsWith("/lifecycle"));
expect(lifecycleCalls).toHaveLength(1);
expect(JSON.parse(String(lifecycleCalls[0][1]?.body))).toEqual({
target_enabled: false,
expected_generation: 1,
dependency_digest: "d".repeat(64),
operator: "Jens",
reason: "Planned hardware maintenance after draining workloads.",
confirmation: "identity-node-a",
});
expect(new Headers(lifecycleCalls[0][1]?.headers).get("X-ModelForge-Admin-Token")).toBe("admin-session");
expect(onChanged).toHaveBeenCalledWith(updatedHardware);
});
it("keeps active workload blockers visible and offers no disable action", async () => {
const blocked = lifecyclePreview({
can_apply: false,
blockers: [{ code: "active_gpu_lease", message: "GPU leases must be released first", record_type: "gpu_lease", count: 1, resource_ids: ["lease-1"] }],
});
const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(JSON.stringify(blocked), { status: 200, headers: { "Content-Type": "application/json" } }),
);
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Review disable impact/i }));
expect(await screen.findByText(/active gpu lease · 1/i)).toBeInTheDocument();
expect(screen.getByText(/GPU leases must be released first/i)).toBeInTheDocument();
expect(screen.getByText(/Resolve each blocker/i)).toBeInTheDocument();
expect(screen.queryByRole("button", { name: /Confirm disable/i })).not.toBeInTheDocument();
expect(fetchMock).toHaveBeenCalledTimes(1);
});
it("keeps a re-enabled remote node offline and unknown until a fresh heartbeat", async () => {
const disabledHardware: HardwareState = {
...hardware,
nodes: hardware.nodes.map((item) => item.id === "node-a" ? { ...item, enabled: false, liveness: "disabled", generation: 2 } : item),
};
const freshHardware: HardwareState = {
...disabledHardware,
nodes: disabledHardware.nodes.map((item) => item.id === "node-a" ? { ...item, enabled: true, liveness: "offline", agent_health: "unknown", protocol_version: null, supported_capabilities: [], last_heartbeat_at: null } : item),
};
const fetchMock = vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => {
const url = String(input);
if (url.endsWith("/lifecycle/preview")) {
return new Response(JSON.stringify(lifecyclePreview({
current_enabled: false,
current_liveness: "disabled",
target_enabled: true,
node_generation: 2,
agent_evidence_after_enable: "awaiting_fresh_authenticated_heartbeat",
})), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/lifecycle")) {
return new Response(JSON.stringify({ node_id: "node-a", enabled: true, generation: 3, liveness: "offline", agent_evidence_state: "awaiting_fresh_authenticated_heartbeat" }), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) return new Response(JSON.stringify(freshHardware), { status: 200, headers: { "Content-Type": "application/json" } });
return new Response("not found", { status: 404 });
});
const onChanged = vi.fn();
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={disabledHardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={onChanged} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Review enable impact/i }));
expect(await screen.findByText(/Agent credential, protocol and health readiness remain unknown/i)).toBeInTheDocument();
fireEvent.change(screen.getByLabelText(/Operator identity/i), { target: { value: "Jens" } });
fireEvent.change(screen.getByLabelText(/Reason/i), { target: { value: "Return the node after maintenance." } });
fireEvent.change(screen.getByLabelText(/Type the persisted node identity/i), { target: { value: "identity-node-a" } });
fireEvent.click(screen.getByRole("button", { name: /Confirm enable/i }));
expect(await screen.findByRole("status")).toHaveTextContent(/remains offline until a fresh authenticated heartbeat/i);
expect(onChanged).toHaveBeenCalledWith(freshHardware);
expect(fetchMock).toHaveBeenCalledTimes(3);
});
it("invalidates stale lifecycle preview and does not retry a raced transition", async () => {
const fetchMock = vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => {
const url = String(input);
if (url.endsWith("/lifecycle/preview")) {
return new Response(JSON.stringify(lifecyclePreview()), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/lifecycle")) {
return new Response(JSON.stringify({ error: { code: "node_lifecycle_preview_stale", message: "Dependencies changed", details: {} } }), { status: 409, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) return new Response(JSON.stringify(hardware), { status: 200, headers: { "Content-Type": "application/json" } });
return new Response("not found", { status: 404 });
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Review disable impact/i }));
await screen.findByText(/No blocking dependencies found/i);
fireEvent.change(screen.getByLabelText(/Operator identity/i), { target: { value: "Jens" } });
fireEvent.change(screen.getByLabelText(/Reason/i), { target: { value: "Planned hardware maintenance after draining workloads." } });
fireEvent.change(screen.getByLabelText(/Type the persisted node identity/i), { target: { value: "identity-node-a" } });
fireEvent.click(screen.getByRole("button", { name: /Confirm disable/i }));
expect(await screen.findByRole("alert")).toHaveTextContent(/changed after review.*not retried/i);
expect(screen.queryByRole("button", { name: /Confirm disable/i })).not.toBeInTheDocument();
expect(fetchMock.mock.calls.filter(([input]) => String(input).endsWith("/lifecycle"))).toHaveLength(1);
expect(fetchMock).toHaveBeenCalledTimes(3);
});
it("rotates an admin-selected node credential only after identity confirmation and clears the one-time reveal", async () => {
const credential = "mfnode_one_time_rotated_secret";
const fetchMock = vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => {
const url = String(input);
if (url.endsWith("/api/v1/admin/hardware/nodes/node-a/credential/rotate")) {
return new Response(JSON.stringify({ node_id: "node-a", credential_id: "credential-2", node_credential: credential }), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) {
return new Response(JSON.stringify(hardware), { status: 200, headers: { "Content-Type": "application/json" } });
}
return new Response("not found", { status: 404 });
});
const onChanged = vi.fn();
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={onChanged} onError={vi.fn()} />);
expect(screen.getByText(/The current credential is revoked immediately/i)).toBeInTheDocument();
const confirmation = screen.getByLabelText(/Confirm by entering the node ID/i);
const rotateButton = screen.getByRole("button", { name: /Rotate node credential/i });
expect(rotateButton).toBeDisabled();
fireEvent.change(confirmation, { target: { value: "node-b" } });
expect(rotateButton).toBeDisabled();
fireEvent.change(confirmation, { target: { value: "node-a" } });
expect(rotateButton).toBeEnabled();
fireEvent.click(rotateButton);
expect(await screen.findByLabelText(/One-time node credential/i)).toHaveValue(credential);
expect(fetchMock).toHaveBeenCalledTimes(1);
expect(onChanged).not.toHaveBeenCalled();
const [rotationUrl, rotationInit] = fetchMock.mock.calls[0];
expect(String(rotationUrl)).toContain("/api/v1/admin/hardware/nodes/node-a/credential/rotate");
expect(rotationInit?.method).toBe("POST");
expect(rotationInit?.cache).toBe("no-store");
expect(new Headers(rotationInit?.headers).get("X-ModelForge-Admin-Token")).toBe("admin-session");
expect(window.localStorage.getItem("node_credential")).toBeNull();
expect(window.sessionStorage.getItem("node_credential")).toBeNull();
await act(async () => {
fireEvent.click(screen.getByRole("button", { name: /I installed the replacement.*refresh status/i }));
});
expect(fetchMock).toHaveBeenCalledTimes(2);
expect(onChanged).toHaveBeenCalledWith(hardware);
expect(screen.queryByLabelText(/One-time node credential/i)).not.toBeInTheDocument();
expect(screen.queryByText(credential)).not.toBeInTheDocument();
});
it("blocks an automatic retry when the rotation response is lost and gives the audit recovery step", async () => {
vi.spyOn(globalThis, "fetch").mockRejectedValue(new TypeError("Failed to fetch"));
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" hardware={hardware} targetNodeId="node-a" onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.change(screen.getByLabelText(/Confirm by entering the node ID/i), { target: { value: "node-a" } });
fireEvent.click(screen.getByRole("button", { name: /Rotate node credential/i }));
expect(await screen.findByRole("alert")).toHaveTextContent(/may have completed the rotation before the response was lost/i);
expect(screen.getByRole("alert")).toHaveTextContent(/check the admin audit timeline.*node status first/i);
expect(screen.getByRole("alert")).toHaveTextContent(/only start a new confirmed rotation when an administrator can install its replacement/i);
expect(screen.queryByRole("button", { name: /Rotate node credential/i })).not.toBeInTheDocument();
expect(screen.queryByLabelText(/One-time node credential/i)).not.toBeInTheDocument();
expect(fetch).toHaveBeenCalledTimes(1);
});
it("clears a rotated credential if the administrator role is downgraded", async () => {
const credential = "mfnode_demotion_secret";
vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => {
const url = String(input);
if (url.endsWith("/api/v1/admin/hardware/nodes/node-a/credential/rotate")) {
return new Response(JSON.stringify({ node_id: "node-a", credential_id: "credential-2", node_credential: credential }), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) return new Response(JSON.stringify(hardware), { status: 200, headers: { "Content-Type": "application/json" } });
return new Response("not found", { status: 404 });
});
setOperatorCredential("admin-session", Date.now() + 60_000);
const props = { hardware, targetNodeId: "node-a", onNavigate: vi.fn(), onChanged: vi.fn(), onError: vi.fn() };
const view = render(<HardwareWorkspace {...props} role="admin" />);
fireEvent.change(screen.getByLabelText(/Confirm by entering the node ID/i), { target: { value: "node-a" } });
fireEvent.click(screen.getByRole("button", { name: /Rotate node credential/i }));
expect(await screen.findByLabelText(/One-time node credential/i)).toHaveValue(credential);
view.rerender(<HardwareWorkspace {...props} role="viewer" />);
expect(screen.queryByLabelText(/One-time node credential/i)).not.toBeInTheDocument();
expect(screen.queryByText(credential)).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: /Impact controleren/i })).not.toBeInTheDocument();
});
it("does not carry a one-time credential into a different node detail", async () => {
const credential = "mfnode_node_a_secret";
vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => {
const url = String(input);
if (url.endsWith("/api/v1/admin/hardware/nodes/node-a/credential/rotate")) {
return new Response(JSON.stringify({ node_id: "node-a", credential_id: "credential-2", node_credential: credential }), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) return new Response(JSON.stringify(hardware), { status: 200, headers: { "Content-Type": "application/json" } });
return new Response("not found", { status: 404 });
});
setOperatorCredential("admin-session", Date.now() + 60_000);
const props = { hardware, role: "admin" as const, onNavigate: vi.fn(), onChanged: vi.fn(), onError: vi.fn() };
const view = render(<HardwareWorkspace {...props} targetNodeId="node-a" />);
fireEvent.change(screen.getByLabelText(/Confirm by entering the node ID/i), { target: { value: "node-a" } });
fireEvent.click(screen.getByRole("button", { name: /Rotate node credential/i }));
expect(await screen.findByLabelText(/One-time node credential/i)).toHaveValue(credential);
view.rerender(<HardwareWorkspace {...props} targetNodeId="node-b" />);
expect(screen.getByRole("heading", { name: "host-b" })).toBeInTheDocument();
expect(screen.queryByLabelText(/One-time node credential/i)).not.toBeInTheDocument();
expect(screen.queryByText(credential)).not.toBeInTheDocument();
});
it.each(["viewer", "operator"] as const)("does not offer enrollment to the %s role", (role) => {
render(<HardwareWorkspace role={role} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
expect(screen.queryByRole("button", { name: /Enroll node/i })).not.toBeInTheDocument();
expect(screen.getByText(/only administrators can enroll compute nodes/i)).toBeInTheDocument();
});
it("clears an open one-time token if the operator role is downgraded", async () => {
const token = "mfenroll_demotion_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-demotion",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {},
});
setOperatorCredential("admin-session", Date.now() + 60_000);
const props = { hardware, onNavigate: vi.fn(), onChanged: vi.fn(), onError: vi.fn() };
const view = render(<HardwareWorkspace {...props} role="admin" />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
selectCandidateBundleImage();
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
expect(await screen.findByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
view.rerender(<HardwareWorkspace {...props} role="viewer" />);
expect(screen.queryByLabelText(/One-time enrollment token/i)).not.toBeInTheDocument();
expect(screen.queryByRole("heading", { name: /Configure the node agent/i })).not.toBeInTheDocument();
view.rerender(<HardwareWorkspace {...props} role="admin" />);
expect(screen.queryByRole("heading", { name: /Configure the node agent/i })).not.toBeInTheDocument();
});
it("starts an admin enrollment with an explicit expiry choice", () => {
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
expect(screen.getByLabelText(/Enrollment token expires in/i)).toBeInTheDocument();
expect(screen.getByText(/Production eligibility is locked off for RC enrollment/i)).toBeInTheDocument();
});
it("locks node setup to the current API origin", () => {
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
const originInput = screen.getByLabelText(/Control plane URL/i);
expect(originInput).toHaveValue(controlPlaneOriginForAgent());
expect(originInput).toHaveAttribute("readonly");
expect(screen.getByText(/locked to the Console's current API origin/i)).toBeInTheDocument();
});
it("requires a verified RC bundle manifest entry and rejects missing or mismatched identities", () => {
const create = vi.spyOn(api, "createEnrollment");
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
const createButton = screen.getByRole("button", { name: /Create enrollment token/i });
const imageInput = screen.getByLabelText(/Node Agent image entry from the release manifest/i);
expect(createButton).toBeDisabled();
expect(screen.getByRole("alert")).toHaveTextContent(/release manifest/i);
fireEvent.change(imageInput, { target: { value: JSON.stringify({ ...JSON.parse(candidateManifestEntry), tag: "modelforge-node-agent:latest" }) } });
expect(createButton).toBeDisabled();
expect(screen.getByRole("alert")).toHaveTextContent(/exact 1.3.0-rc.1.*latest/i);
fireEvent.change(imageInput, { target: { value: JSON.stringify({ ...JSON.parse(candidateManifestEntry), rootfs_layers: [] }) } });
expect(createButton).toBeDisabled();
expect(screen.getByRole("alert")).toHaveTextContent(/RootFS layer digests/i);
fireEvent.change(imageInput, { target: { value: candidateManifestEntry } });
expect(createButton).toBeEnabled();
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
expect(create).not.toHaveBeenCalled();
});
it("shell-quotes manifest label values before placing them in the generated command", async () => {
const token = "mfenroll_manifest_quote_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-quoted-manifest",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {},
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
const manifestEntry = JSON.parse(candidateManifestEntry) as { labels: Record<string, string> };
manifestEntry.labels["org.opencontainers.image.description"] = "Node agent's reviewed candidate";
fireEvent.change(screen.getByLabelText(/Node Agent image entry from the release manifest/i), { target: { value: JSON.stringify(manifestEntry) } });
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
expect(await screen.findByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
const command = screen.getByLabelText(/Safe start command/i).textContent ?? "";
expect(command).toContain("'Node agent'\\''s reviewed candidate'");
expect(command).not.toContain("; touch");
expect(command).not.toContain(token);
});
it("supports registry images only when pinned to a digest and verifies the pull", async () => {
const token = "mfenroll_registry_test_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-registry",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {},
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
fireEvent.click(screen.getByLabelText(/Registry image pinned by digest/i));
const createButton = screen.getByRole("button", { name: /Create enrollment token/i });
const imageInput = screen.getByLabelText(/Exact Node Agent registry image digest/i);
fireEvent.change(imageInput, { target: { value: "registry.example.net/team/modelforge-node-agent:latest" } });
expect(createButton).toBeDisabled();
expect(screen.getByRole("alert")).toHaveTextContent(/64 lowercase hex.*floating tags/i);
const digestReference = `registry.example.net/team/modelforge-node-agent@sha256:${"c".repeat(64)}`;
fireEvent.change(imageInput, { target: { value: digestReference } });
expect(createButton).toBeEnabled();
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
fireEvent.click(createButton);
expect(await screen.findByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
const command = screen.getByLabelText(/Safe start command/i).textContent ?? "";
expect(command).toContain(`docker pull '${digestReference}'`);
expect(command).toContain("RepoDigests");
expect(command).toContain("config --images");
expect(command).toContain("--no-build --pull never node-agent");
expect(command).toContain("container_image_id=$(docker inspect --format '{{.Image}}'");
expect(command).not.toContain(token);
});
it("creates an RC-safe enrollment and keeps the secret out of generated commands", async () => {
const token = "mfenroll_one_time_test_secret";
const create = vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-1",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {
MODELFORGE_AGENT_CONTROL_PLANE_URL: "<control-plane-url>",
MODELFORGE_AGENT_ENROLLMENT_TOKEN: token,
},
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
selectCandidateBundleImage();
fireEvent.change(screen.getByLabelText(/Display name/i), { target: { value: "RC canary node" } });
fireEvent.change(screen.getByLabelText(/Enrollment token expires in/i), { target: { value: "3600" } });
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
expect(await screen.findByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
expect(create).toHaveBeenCalledWith(expect.objectContaining({
display_name: "RC canary node",
expires_in_seconds: 3600,
production_eligible: false,
lab_eligible: true,
}), "modelforge:in-memory-operator-session");
const command = screen.getByLabelText(/Safe start command/i).textContent ?? "";
expect(command).toContain(controlPlaneOriginForAgent());
expect(command).toContain(candidateImage);
expect(command).toContain(JSON.stringify(candidateLayers));
expect(command).toContain(candidateRevision);
expect(command).toContain("{{.Architecture}}");
expect(command).toContain("{{.Image}}");
expect(command).toContain("--no-build --pull never");
expect(command).toContain("config --images");
expect(command).toContain("docker image inspect --format '{{json .RootFS.Layers}}' 'modelforge-node-agent:1.3.0-rc.1'");
expect(command).toContain("test \"$compose_image\" = 'modelforge-node-agent:1.3.0-rc.1'");
for (const [labelKey, labelValue] of Object.entries((JSON.parse(candidateManifestEntry) as { labels: Record<string, string> }).labels)) {
expect(command).toContain(labelKey);
expect(command).toContain(labelValue);
}
expect(command).not.toContain("docker pull");
expect(command).not.toContain(candidateBuildHostImageId);
expect(command).not.toContain("--build");
expect(screen.getByLabelText(/Non-secret node configuration/i).textContent).toContain(controlPlaneOriginForAgent());
expect(screen.getByLabelText(/Non-secret node configuration/i).textContent).toContain(`MODELFORGE_NODE_AGENT_IMAGE=${candidateImage}`);
expect(command).toContain("set +x");
expect(command).toContain("set -eu");
expect(command).toContain("chmod 600");
expect(command).toContain("trap");
expect(command).toContain("grep -Eq");
for (const key of ["MODELFORGE_AGENT_CONTROL_PLANE_URL", "MODELFORGE_NODE_AGENT_IMAGE"]) {
expect(command).toContain(`${key}_ASSIGNMENT_COUNT=$(grep -Ec`);
expect(command).toContain(`test "$${key}_ASSIGNMENT_COUNT" -eq 1`);
expect(command).toContain(`grep -Fqx -- '${key}=`);
}
expect(command).toContain("env -u MODELFORGE_AGENT_ENROLLMENT_TOKEN -u MODELFORGE_AGENT_CONTROL_PLANE_URL -u MODELFORGE_NODE_AGENT_IMAGE");
expect(command).not.toContain(token);
expect(window.localStorage.getItem("enrollment_token")).toBeNull();
expect(window.sessionStorage.getItem("enrollment_token")).toBeNull();
});
it("clears the revealed token when the unused enrollment is revoked", async () => {
const token = "mfenroll_revoke_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-revoke",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {},
});
const revoke = vi.spyOn(api, "revokeEnrollment").mockResolvedValue({});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
selectCandidateBundleImage();
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
expect(await screen.findByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
fireEvent.click(screen.getByRole("button", { name: /Revoke unused token/i }));
expect(await screen.findByText(/This token was revoked/i)).toBeInTheDocument();
expect(screen.queryByLabelText(/One-time enrollment token/i)).not.toBeInTheDocument();
expect(revoke).toHaveBeenCalledWith("enrollment-revoke", "modelforge:in-memory-operator-session");
});
it("clears the revealed token automatically when the one-time expiry elapses", async () => {
vi.useFakeTimers();
const token = "mfenroll_expiry_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-expiry",
enrollment_token: token,
expires_at: new Date(Date.now() + 1_000).toISOString(),
setup_environment: {},
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
selectCandidateBundleImage();
await act(async () => {
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
});
expect(screen.getByLabelText(/One-time enrollment token/i)).toHaveTextContent(token);
await act(async () => {
vi.advanceTimersByTime(1_001);
});
expect(screen.queryByLabelText(/One-time enrollment token/i)).not.toBeInTheDocument();
expect(screen.getByText(/Token expired/i)).toBeInTheDocument();
vi.useRealTimers();
});
it("does not call a node ready before the matching enrollment, inventory, protocol, and health are proven", async () => {
const token = "mfenroll_readiness_secret";
vi.spyOn(api, "createEnrollment").mockResolvedValue({
id: "enrollment-2",
enrollment_token: token,
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
setup_environment: {},
});
let summaryRead = 0;
const unrelatedNode = node("unrelated", "unrelated-host");
const incompatibleNode = {
...node("node-b", "enrolled-host"),
liveness: "offline" as const,
agent_health: "incompatible" as const,
protocol_version: 99,
last_heartbeat_at: null,
last_inventory_received_at: new Date(Date.now() - 601_000).toISOString(),
inventory_age_seconds: 601,
last_telemetry_received_at: new Date(Date.now() - 91_000).toISOString(),
telemetry_age_seconds: 91,
last_connection_error: "protocol mismatch",
};
const readyNode = {
...node("node-b", "enrolled-host"),
liveness: "online" as const,
agent_health: "healthy" as const,
protocol_version: 1,
last_heartbeat_at: new Date().toISOString(),
last_inventory_received_at: new Date().toISOString(),
inventory_age_seconds: 2,
last_telemetry_received_at: new Date().toISOString(),
telemetry_age_seconds: 2,
};
const connectedOnlyNode = {
...node("node-b", "enrolled-host"),
liveness: "online" as const,
agent_health: "healthy" as const,
protocol_version: 1,
last_heartbeat_at: new Date().toISOString(),
last_inventory_received_at: null,
inventory_age_seconds: null,
last_telemetry_received_at: null,
telemetry_age_seconds: null,
};
const disabledNode = { ...readyNode, enabled: false };
vi.spyOn(globalThis, "fetch").mockImplementation(async (input) => {
const url = String(input);
if (url.endsWith("/api/v1/admin/node-enrollments")) {
summaryRead += 1;
const linked = summaryRead >= 2;
return new Response(JSON.stringify([{
id: "enrollment-2",
created_at: new Date().toISOString(),
expires_at: new Date(Date.now() + 15 * 60_000).toISOString(),
used_at: linked ? new Date().toISOString() : null,
revoked_at: null,
enrolled_node_id: linked ? "node-b" : null,
}]), { status: 200, headers: { "Content-Type": "application/json" } });
}
if (url.endsWith("/api/v1/hardware")) {
const nodeState = summaryRead <= 2
? [unrelatedNode]
: summaryRead === 3
? [unrelatedNode, connectedOnlyNode]
: summaryRead === 4
? [unrelatedNode, incompatibleNode]
: summaryRead === 5
? [unrelatedNode, readyNode]
: [unrelatedNode, disabledNode];
return new Response(JSON.stringify({ ...hardware, nodes: nodeState }), { status: 200, headers: { "Content-Type": "application/json" } });
}
return new Response("not found", { status: 404 });
});
setOperatorCredential("admin-session", Date.now() + 60_000);
render(<HardwareWorkspace role="admin" supportedProtocolVersions={[1]} hardware={hardware} onNavigate={vi.fn()} onChanged={vi.fn()} onError={vi.fn()} />);
fireEvent.click(screen.getByRole("button", { name: /Enroll node/i }));
selectCandidateBundleImage();
fireEvent.click(screen.getByRole("button", { name: /Create enrollment token/i }));
expect(await screen.findByLabelText(/One-time enrollment token/i)).toBeInTheDocument();
expect(screen.getAllByText(/UNKNOWN.*enrolled node ID/i)).toHaveLength(5);
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText(/Waiting for the agent to use this token/i)).toBeInTheDocument();
expect(screen.getAllByText(/UNKNOWN.*enrolled node ID/i)).toHaveLength(5);
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText(/Node node-b is not in the hardware inventory yet/i)).toBeInTheDocument();
expect(screen.queryByText("Node is ready", { exact: true })).not.toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText(/Heartbeat is online/i)).toBeInTheDocument();
expect(screen.getByText("Node is not ready", { exact: true })).toBeInTheDocument();
expect(screen.getByText(/No node inventory report has been received yet/i)).toBeInTheDocument();
expect(screen.getByText(/No telemetry report has been received yet/i)).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText(/protocol 99 is unsupported/i)).toBeInTheDocument();
expect(screen.getByText("Node is not ready", { exact: true })).toBeInTheDocument();
expect(screen.getByText(/Heartbeat age unknown.*protocol mismatch/i)).toBeInTheDocument();
expect(screen.getByText(/Inventory is stale: age 10m 1s/i)).toBeInTheDocument();
expect(screen.getByText(/Agent health is incompatible/i)).toBeInTheDocument();
expect(screen.getByText(/Telemetry is stale: telemetry age 1m 31s/i)).toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText("Node is ready", { exact: true })).toBeInTheDocument();
expect(screen.getByText(/telemetry age: 2s/i)).toBeInTheDocument();
const cleanupCommand = screen.getByLabelText(/Clear enrollment secret from node container/i).textContent ?? "";
expect(cleanupCommand).toContain(controlPlaneOriginForAgent());
expect(cleanupCommand).toContain("grep -Eq");
expect(cleanupCommand).toContain(candidateImage);
expect(cleanupCommand).toContain(JSON.stringify(candidateLayers));
expect(cleanupCommand).toContain(candidateRevision);
expect(cleanupCommand).toContain("{{.Architecture}}");
expect(cleanupCommand).toContain("{{.Image}}");
expect(cleanupCommand).not.toContain(candidateBuildHostImageId);
for (const key of ["MODELFORGE_AGENT_CONTROL_PLANE_URL", "MODELFORGE_NODE_AGENT_IMAGE"]) {
expect(cleanupCommand).toContain(`${key}_ASSIGNMENT_COUNT=$(grep -Ec`);
expect(cleanupCommand).toContain(`test "$${key}_ASSIGNMENT_COUNT" -eq 1`);
expect(cleanupCommand).toContain(`grep -Fqx -- '${key}=`);
}
expect(cleanupCommand).toContain("env -u MODELFORGE_AGENT_ENROLLMENT_TOKEN -u MODELFORGE_AGENT_CONTROL_PLANE_URL -u MODELFORGE_NODE_AGENT_IMAGE");
expect(cleanupCommand).toContain("--no-build --pull never --force-recreate node-agent");
expect(cleanupCommand).not.toContain("--build");
fireEvent.click(screen.getByRole("button", { name: /Check node readiness/i }));
expect(await screen.findByText("Node is not ready", { exact: true })).toBeInTheDocument();
expect(screen.getByText(/The node is disabled/i)).toBeInTheDocument();
});
});