clusterflux-public/scripts/cli-output-mode-smoke.js
2026-07-04 15:30:37 +02:00

166 lines
5.3 KiB
JavaScript

#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "examples/launch-build-demo");
const isolatedCwd = fs.mkdtempSync(path.join(os.tmpdir(), "disasmer-cli-output-"));
function disasmer(args, env = {}, cwd = repo) {
return cp.execFileSync(
"cargo",
[
"run",
"-q",
"--manifest-path",
path.join(repo, "Cargo.toml"),
"-p",
"disasmer-cli",
"--bin",
"disasmer",
"--",
...args,
],
{
cwd,
encoding: "utf8",
env: {
...process.env,
...env,
},
}
);
}
function json(args, env, cwd) {
return JSON.parse(disasmer(args, env, cwd));
}
function assertHuman(name, output, requiredPatterns) {
assert(
!output.trimStart().startsWith("{"),
`${name} default output should be human-readable text, not JSON`
);
for (const pattern of requiredPatterns) {
assert.match(output, pattern, `${name} human output missing ${pattern}`);
}
}
const helpHuman = disasmer(["help"]);
assertHuman("help", helpHuman, [
/Primary workflow:/,
/disasmer login --browser/,
/disasmer project init/,
/disasmer node attach --worker/,
/Disasmer: Launch Virtual Process/,
/Hosted account creation happens in the browser login flow/,
/--json/,
]);
const loginHuman = disasmer(["login", "--coordinator", "https://coord.example.test"]);
assertHuman("login", loginHuman, [
/Disasmer login/,
/flow: device/,
/verify: https:\/\/coord\.example\.test\/auth\/device/,
]);
const loginJson = json(["login", "--coordinator", "https://coord.example.test", "--json"]);
assert.strictEqual(loginJson.coordinator, "https://coord.example.test");
assert(loginJson.human_flow.Device);
const doctorHuman = disasmer(["doctor"]);
assertHuman("doctor", doctorHuman, [
/Disasmer doctor/,
/coordinator reachability: not_configured/,
/dependencies:/,
/auth:/,
/node capabilities:/,
/node readiness: (ready_to_attach|local_dependencies_missing|limited_capabilities)/,
/node next:/,
]);
const doctorJson = json(["doctor", "--json"]);
assert.strictEqual(doctorJson.coordinator_reachability.checked, false);
assert.strictEqual(doctorJson.coordinator_reachability.status, "not_configured");
assert(
["ready_to_attach", "local_dependencies_missing", "limited_capabilities"].includes(
doctorJson.node_readiness_summary.status
)
);
assert.strictEqual(doctorJson.node_readiness_summary.explicit_attach_required, true);
assert.strictEqual(
doctorJson.node_readiness_summary.command_execution_capability,
true
);
assert(Array.isArray(doctorJson.node_readiness_summary.missing_local_dependencies));
assert(doctorJson.node_readiness_summary.next_actions.length >= 2);
const authJson = json(["auth", "status", "--json"], {
DISASMER_TOKEN: "token",
DISASMER_TOKEN_EXPIRES_AT: "2026-07-04T00:00:00Z",
}, isolatedCwd);
assert.strictEqual(authJson.session.kind, "human");
assert.strictEqual(authJson.session.token_expiry_posture, "expires_at");
assert.strictEqual(authJson.session.expires_at, "2026-07-04T00:00:00Z");
assert.strictEqual(authJson.coordinator_account_status.checked, false);
assert.strictEqual(authJson.coordinator_account_status.account_status, "unknown");
assert.strictEqual(
authJson.coordinator_account_status.private_moderation_details_exposed,
false
);
const inspectHuman = disasmer(["bundle", "inspect", "--project", project]);
assertHuman("bundle inspect", inspectHuman, [
/Disasmer bundle inspect/,
/bundle: sha256:/,
/environments:/,
]);
const inspectJson = json(["bundle", "inspect", "--project", project, "--json"]);
assert.strictEqual(inspectJson.project, project);
assert.match(inspectJson.metadata.identity, /^sha256:/);
assert.match(inspectJson.metadata.wasm_code, /^sha256:/);
assert.strictEqual(inspectJson.metadata.task_metadata.default_entrypoint, "build");
assert(inspectJson.metadata.task_metadata.entrypoints.includes("release"));
assert.strictEqual(
inspectJson.metadata.source_metadata.transfer_policy.coordinator_receives_source_bytes_by_default,
false
);
assert.strictEqual(
inspectJson.metadata.source_metadata.transfer_policy.default_full_repo_tarball,
false
);
assert.strictEqual(inspectJson.metadata.debug_metadata.dap_virtual_process, true);
assert.strictEqual(
inspectJson.metadata.large_input_policy.selected_inputs_are_content_digests,
true
);
assert.strictEqual(inspectJson.metadata.large_input_policy.selected_input_bytes_included, false);
assert.strictEqual(inspectJson.metadata.large_input_policy.full_repository_bytes_included, false);
assert.strictEqual(
inspectJson.metadata.large_input_policy.silent_task_argument_serialization,
false
);
assert(inspectJson.metadata.large_input_policy.supported_handle_types.includes("SourceSnapshot"));
assert.strictEqual(
inspectJson.metadata.restart_compatibility.source_edits_can_restart_from_clean_task_boundary,
true
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.requires_clean_checkpoint_boundary,
true
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.compares_task_abi,
inspectJson.metadata.task_metadata.task_abi
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.incompatible_changes_require_whole_process_restart,
true
);
console.log("CLI output mode smoke passed");