d68f003000
CI / Change detection (push) Has been cancelled
CI / Version drift (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Workflow RLM cache (push) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / npm wrapper smoke (push) Has been cancelled
CI / Mobile runtime smoke (push) Has been cancelled
CI / Workflow lint (push) Has been cancelled
CI / Documentation (push) Has been cancelled
Web Frontend / Lint & Type Check (push) Failing after 1s
Auto-close harvested PRs / close (push) Failing after 1s
cargo-deny / cargo-deny (bans licenses sources) (push) Failing after 1s
Security audit / cargo-audit (push) Failing after 1s
Sync to CNB / sync (push) Failing after 1s
cargo-deny / cargo-deny (advisories) (push) Failing after 3s
Web Frontend / Deploy to Cloudflare (push) Has been cancelled
158 lines
5.2 KiB
JavaScript
158 lines
5.2 KiB
JavaScript
const assert = require("node:assert/strict");
|
|
const test = require("node:test");
|
|
|
|
const pkg = require("../package.json");
|
|
const { _internal } = require("../scripts/install");
|
|
|
|
test("postinstall opts into optional install mode", () => {
|
|
assert.equal(pkg.scripts.postinstall, "node scripts/install.js --optional");
|
|
});
|
|
|
|
test("optional install can be enabled by command-line flag or env", () => {
|
|
assert.equal(_internal.isOptionalInstall(["--optional"], {}), true);
|
|
assert.equal(_internal.isOptionalInstall([], {}), false);
|
|
assert.equal(_internal.isOptionalInstall([], { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), true);
|
|
assert.equal(_internal.isOptionalInstall([], { DEEPSEEK_OPTIONAL_INSTALL: "1" }), true);
|
|
});
|
|
|
|
test("optional mode only changes install-time defaults", () => {
|
|
assert.equal(_internal.maxAttempts("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 1);
|
|
assert.equal(_internal.maxAttempts("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 5);
|
|
assert.equal(_internal.defaultTimeoutMs("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 15_000);
|
|
assert.equal(_internal.defaultTimeoutMs("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 300_000);
|
|
assert.equal(_internal.defaultStallMs("install", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 5_000);
|
|
assert.equal(_internal.defaultStallMs("runtime", { DEEPSEEK_TUI_OPTIONAL_INSTALL: "1" }), 30_000);
|
|
});
|
|
|
|
test("pnpm optional postinstall skips install-time download", () => {
|
|
assert.equal(
|
|
_internal.shouldSkipOptionalPostinstall("install", ["--optional"], {
|
|
npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64",
|
|
}),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
_internal.shouldSkipOptionalPostinstall("runtime", ["--optional"], {
|
|
npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64",
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
_internal.shouldSkipOptionalPostinstall("install", [], {
|
|
npm_config_user_agent: "pnpm/10.11.0 npm/? node/v22.15.0 win32 x64",
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
_internal.shouldSkipOptionalPostinstall("install", ["--optional"], {
|
|
npm_config_user_agent: "npm/11.3.0 node/v22.15.0 win32 x64",
|
|
}),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test("optional install only swallows retryable download failures", () => {
|
|
const socketHangUp = new Error("socket hang up");
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", socketHangUp, ["--optional"], {}),
|
|
true,
|
|
);
|
|
|
|
const timedOut = new Error("download exceeded total timeout of 15000 ms");
|
|
timedOut.code = "EDOWNLOADTIMEOUT";
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", timedOut, ["--optional"], {}),
|
|
true,
|
|
);
|
|
|
|
const unsupported = new Error("Unsupported platform: freebsd");
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", unsupported, ["--optional"], {}),
|
|
false,
|
|
);
|
|
|
|
const badChecksum = new Error("Checksum mismatch for codewhale-linux-x64");
|
|
badChecksum.nonRetryable = true;
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", badChecksum, ["--optional"], {}),
|
|
false,
|
|
);
|
|
|
|
const glibc = new Error("requires glibc 2.34 or newer");
|
|
glibc.nonRetryable = true;
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", glibc, ["--optional"], {}),
|
|
false,
|
|
);
|
|
});
|
|
|
|
test("optional install still swallows wrapped http 5xx failures", async () => {
|
|
const previous = process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL;
|
|
process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL = "1";
|
|
const http5xx = new Error("Request failed with status 502: https://example.invalid");
|
|
http5xx.name = "HttpStatusError";
|
|
http5xx.status = 502;
|
|
|
|
try {
|
|
await assert.rejects(
|
|
_internal.withRetry("fetch https://example.invalid", async () => {
|
|
throw http5xx;
|
|
}, "install"),
|
|
(wrapped) => {
|
|
assert.equal(wrapped.name, "HttpStatusError");
|
|
assert.equal(wrapped.status, 502);
|
|
assert.equal(
|
|
_internal.shouldIgnoreInstallFailure("install", wrapped, ["--optional"], {}),
|
|
true,
|
|
);
|
|
return true;
|
|
},
|
|
);
|
|
} finally {
|
|
if (previous === undefined) {
|
|
delete process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL;
|
|
} else {
|
|
process.env.DEEPSEEK_TUI_OPTIONAL_INSTALL = previous;
|
|
}
|
|
}
|
|
});
|
|
|
|
test("withRetry prints install hint on first retryable failure", async () => {
|
|
const previousWrite = process.stderr.write;
|
|
const previousSetTimeout = global.setTimeout;
|
|
let stderr = "";
|
|
let attempts = 0;
|
|
process.stderr.write = (chunk) => {
|
|
stderr += String(chunk);
|
|
return true;
|
|
};
|
|
global.setTimeout = (callback) => {
|
|
callback();
|
|
return 0;
|
|
};
|
|
|
|
try {
|
|
const result = await _internal.withRetry(
|
|
"fetch https://github.com/example",
|
|
async () => {
|
|
attempts += 1;
|
|
if (attempts === 1) {
|
|
const err = new Error("connect ETIMEDOUT 20.205.243.166:443");
|
|
err.code = "ETIMEDOUT";
|
|
throw err;
|
|
}
|
|
return "ok";
|
|
},
|
|
"runtime",
|
|
);
|
|
|
|
assert.equal(result, "ok");
|
|
assert.equal(attempts, 2);
|
|
assert.match(stderr, /codewhale install hint:/);
|
|
assert.match(stderr, /#npm-binary-download-times-out/);
|
|
} finally {
|
|
process.stderr.write = previousWrite;
|
|
global.setTimeout = previousSetTimeout;
|
|
}
|
|
});
|