Public release release-98d969b26488
Source commit: 98d969b26488b4cda8b2381fa870276a00ca98ea Public tree identity: sha256:d02dd1e8d3547a489bb300741bed544bdc60bb8fe0bd541fd43ce9bfa7129a3e
This commit is contained in:
commit
8ded2b6a42
210 changed files with 76954 additions and 0 deletions
229
scripts/vscode-extension-smoke.js
Executable file
229
scripts/vscode-extension-smoke.js
Executable file
|
|
@ -0,0 +1,229 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
const assert = require("assert");
|
||||
|
||||
const extension = require("../vscode-extension/extension");
|
||||
const packageJson = require("../vscode-extension/package.json");
|
||||
const extensionSource = fs.readFileSync(
|
||||
path.join(__dirname, "../vscode-extension/extension.js"),
|
||||
"utf8"
|
||||
);
|
||||
const repo = path.resolve(__dirname, "..");
|
||||
|
||||
assert.strictEqual(packageJson.main, "./extension.js");
|
||||
assert(fs.existsSync(path.join(__dirname, "../vscode-extension", packageJson.main)));
|
||||
assert.deepStrictEqual(packageJson.dependencies || {}, {});
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-vscode-"));
|
||||
fs.mkdirSync(path.join(root, "envs/linux"), { recursive: true });
|
||||
fs.writeFileSync(path.join(root, "envs/linux/Containerfile"), "FROM alpine\n");
|
||||
fs.mkdirSync(path.join(root, ".clusterflux"), { recursive: true });
|
||||
fs.writeFileSync(
|
||||
extension.clusterfluxViewStatePath(root),
|
||||
JSON.stringify({
|
||||
nodes: [{ id: "node-linux", status: "online", capabilities: "Command RootlessPodman" }],
|
||||
processes: [{ id: "vp-build", status: "running", entry: "build" }],
|
||||
logs: [{ task: "compile-linux", message: "stdout=12 stderr=0", bytes: 12 }],
|
||||
artifacts: [{ path: "/vfs/artifacts/app.tar.zst", status: "retained", size: 12 }],
|
||||
inspector: [{ label: "debug", value: "attached" }]
|
||||
})
|
||||
);
|
||||
|
||||
const envs = extension.discoverEnvironmentNames(root);
|
||||
assert.deepStrictEqual(envs, ["linux"]);
|
||||
|
||||
const diagnostics = extension.diagnoseEnvReferences(
|
||||
'let _ = env!("linux"); let _ = env!("windows");',
|
||||
envs
|
||||
);
|
||||
assert.strictEqual(diagnostics.length, 1);
|
||||
assert.strictEqual(diagnostics[0].name, "windows");
|
||||
assert.match(diagnostics[0].message, /envs\/windows\/Containerfile/);
|
||||
|
||||
const inspectCommand = extension.bundleInspectCommand(root, "/repo");
|
||||
assert.strictEqual(inspectCommand.command, "cargo");
|
||||
assert.deepStrictEqual(inspectCommand.args.slice(0, 8), [
|
||||
"run",
|
||||
"-q",
|
||||
"-p",
|
||||
"clusterflux-cli",
|
||||
"--bin",
|
||||
"clusterflux",
|
||||
"--",
|
||||
"bundle"
|
||||
]);
|
||||
assert(inspectCommand.args.includes("inspect"));
|
||||
assert(inspectCommand.args.includes("--project"));
|
||||
assert(inspectCommand.args.includes(root));
|
||||
assert(inspectCommand.args.includes("--json"));
|
||||
|
||||
const refreshed = extension.refreshBundleBeforeLaunch(root, "/repo", (command, args, options) => {
|
||||
assert.strictEqual(command, "cargo");
|
||||
assert(args.includes("bundle"));
|
||||
assert.strictEqual(options.cwd, "/repo");
|
||||
return {
|
||||
status: 0,
|
||||
stdout: JSON.stringify({ metadata: { identity: "sha256:abc" } }),
|
||||
stderr: ""
|
||||
};
|
||||
});
|
||||
assert.strictEqual(refreshed.metadata.identity, "sha256:abc");
|
||||
|
||||
const launch = extension.resolveClusterfluxDebugConfiguration(
|
||||
{ uri: { fsPath: root } },
|
||||
{}
|
||||
);
|
||||
assert.deepStrictEqual(launch, {
|
||||
name: "Clusterflux: Launch Virtual Process",
|
||||
type: "clusterflux",
|
||||
request: "launch",
|
||||
entry: "build",
|
||||
project: root,
|
||||
runtimeBackend: "local-services"
|
||||
});
|
||||
assert.strictEqual(
|
||||
extension.clusterfluxProcessId("/workspace/app", "build"),
|
||||
"vp-e4bd6ef50539"
|
||||
);
|
||||
assert.strictEqual(
|
||||
extension.existingProcessRelationship(
|
||||
{ process: "vp-e4bd6ef50539", state: "running" },
|
||||
"vp-e4bd6ef50539"
|
||||
),
|
||||
"same_launch_target"
|
||||
);
|
||||
assert.strictEqual(
|
||||
extension.existingProcessRelationship(
|
||||
{ process: "vp-other", state: "running" },
|
||||
"vp-e4bd6ef50539"
|
||||
),
|
||||
"different_launch_target"
|
||||
);
|
||||
|
||||
const liveProcesses = extension.loadLiveProcesses(root, "/repo", (_command, args) => {
|
||||
assert.deepStrictEqual(args.slice(-3), ["process", "list", "--json"]);
|
||||
return {
|
||||
status: 0,
|
||||
stdout: JSON.stringify({
|
||||
coordinator: "https://clusterflux.michelpaulissen.com",
|
||||
tenant: "tenant-live",
|
||||
project: "project-live",
|
||||
user: "user-live",
|
||||
processes: [{ process: "vp-live", state: "cancelling" }]
|
||||
}),
|
||||
stderr: ""
|
||||
};
|
||||
});
|
||||
assert.deepStrictEqual(liveProcesses.processes, [
|
||||
{ process: "vp-live", state: "cancelling" }
|
||||
]);
|
||||
assert.strictEqual(liveProcesses.project, "project-live");
|
||||
|
||||
const adapter = extension.debugAdapterExecutableSpec(root, repo);
|
||||
assert.strictEqual(adapter.command, "cargo");
|
||||
assert.deepStrictEqual(adapter.args, [
|
||||
"run",
|
||||
"-q",
|
||||
"-p",
|
||||
"clusterflux-dap",
|
||||
"--bin",
|
||||
"clusterflux-debug-dap"
|
||||
]);
|
||||
assert.deepStrictEqual(adapter.options, { cwd: repo });
|
||||
|
||||
const releasedAdapterPath = path.join(root, process.platform === "win32" ? "clusterflux-debug-dap.exe" : "clusterflux-debug-dap");
|
||||
fs.writeFileSync(releasedAdapterPath, "");
|
||||
const releasedAdapter = extension.debugAdapterExecutableSpec(root, repo);
|
||||
assert.strictEqual(releasedAdapter.command, releasedAdapterPath);
|
||||
assert.deepStrictEqual(releasedAdapter.args, []);
|
||||
assert.deepStrictEqual(releasedAdapter.options, { cwd: root });
|
||||
|
||||
assert.throws(
|
||||
() =>
|
||||
extension.refreshBundleBeforeLaunch(root, "/repo", () => ({
|
||||
status: 1,
|
||||
stdout: "",
|
||||
stderr: "missing environment linux"
|
||||
})),
|
||||
/missing environment linux/
|
||||
);
|
||||
|
||||
assert(
|
||||
packageJson.contributes.viewsContainers.activitybar.some(
|
||||
(container) => container.id === "clusterflux" && container.title === "Clusterflux"
|
||||
),
|
||||
"package.json must contribute a Clusterflux activity-bar container"
|
||||
);
|
||||
assert(
|
||||
fs.existsSync(path.join(__dirname, "../vscode-extension/resources/clusterflux.svg")),
|
||||
"Clusterflux activity-bar icon must exist"
|
||||
);
|
||||
const packageViewIds = packageJson.contributes.views.clusterflux.map((view) => view.id).sort();
|
||||
const descriptorViewIds = extension.clusterfluxViewDescriptors().map((view) => view.id).sort();
|
||||
assert.deepStrictEqual(descriptorViewIds, [
|
||||
"clusterflux.artifacts",
|
||||
"clusterflux.inspector",
|
||||
"clusterflux.logs",
|
||||
"clusterflux.nodes",
|
||||
"clusterflux.processes"
|
||||
]);
|
||||
assert.deepStrictEqual(packageViewIds, descriptorViewIds);
|
||||
for (const viewId of descriptorViewIds) {
|
||||
const items = extension.clusterfluxViewItems(
|
||||
extension.loadClusterfluxViewState(root),
|
||||
viewId
|
||||
);
|
||||
assert(
|
||||
items.length > 0 && !items[0].label.startsWith("No "),
|
||||
`${viewId} should render state-backed items`
|
||||
);
|
||||
}
|
||||
assert.deepStrictEqual(
|
||||
extension.clusterfluxViewItems(extension.loadClusterfluxViewState(root), "clusterflux.nodes")[0],
|
||||
{
|
||||
label: "node-linux",
|
||||
description: "online Command RootlessPodman"
|
||||
}
|
||||
);
|
||||
|
||||
assert(
|
||||
packageJson.contributes.debuggers.some((debuggerContribution) => debuggerContribution.type === "clusterflux"),
|
||||
"package.json must contribute the clusterflux debugger type"
|
||||
);
|
||||
for (const viewId of descriptorViewIds) {
|
||||
assert(
|
||||
packageJson.activationEvents.includes(`onView:${viewId}`),
|
||||
`${viewId} should activate the extension when opened`
|
||||
);
|
||||
}
|
||||
const launchProperties =
|
||||
packageJson.contributes.debuggers[0].configurationAttributes.launch.properties;
|
||||
assert.strictEqual(launchProperties.runtimeBackend.default, "local-services");
|
||||
assert(launchProperties.runtimeBackend.enum.includes("live-services"));
|
||||
assert.strictEqual(launchProperties.coordinatorEndpoint.default, undefined);
|
||||
assert.strictEqual(launchProperties.tenant, undefined);
|
||||
assert.strictEqual(launchProperties.projectId, undefined);
|
||||
assert.strictEqual(launchProperties.actorUser, undefined);
|
||||
assert(
|
||||
packageJson.contributes.debuggers[0].configurationAttributes.attach,
|
||||
"package.json must contribute an attach configuration"
|
||||
);
|
||||
for (const command of [
|
||||
"clusterflux.refreshProcesses",
|
||||
"clusterflux.process.attach",
|
||||
"clusterflux.process.cancel",
|
||||
"clusterflux.process.abort"
|
||||
]) {
|
||||
assert(
|
||||
packageJson.contributes.commands.some((entry) => entry.command === command),
|
||||
`${command} must be contributed`
|
||||
);
|
||||
}
|
||||
assert.match(extensionSource, /registerDebugAdapterDescriptorFactory\("clusterflux"/);
|
||||
assert.match(extensionSource, /clusterflux-debug-dap/);
|
||||
assert.match(extensionSource, /\.clusterflux\/views\.json/);
|
||||
|
||||
fs.rmSync(root, { recursive: true, force: true });
|
||||
console.log("VS Code extension smoke passed");
|
||||
Loading…
Add table
Add a link
Reference in a new issue