Co-authored-by: alvinfei <alvinfei@tencent.com> Co-authored-by: Cursor <cursoragent@cursor.com>
50 lines
1.7 KiB
JavaScript
50 lines
1.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import test from "node:test";
|
|
|
|
const source = await readFile(
|
|
new URL("./verify-linux-upgrade-rollback.mjs", import.meta.url),
|
|
"utf8",
|
|
);
|
|
|
|
test("Linux upgrade matrix proves N-1 to N and crash rollback separately", () => {
|
|
for (const marker of [
|
|
"upgrade_n_minus_one_to_n",
|
|
"makeFailingDistribution",
|
|
"upgrade_health_check_failed",
|
|
"selection_not_restored",
|
|
"failed_version_retained",
|
|
"recalled_after_rollback",
|
|
"database_file_changed_during_failed_upgrade",
|
|
"uninstall_preserve_data",
|
|
"inactive-before-uninstall",
|
|
]) {
|
|
assert.ok(source.includes(marker), marker);
|
|
}
|
|
assert.match(source, /currentDistribution\.manifest\.build_number <=/);
|
|
assert.match(source, /manifest\.files\["core\/one-memory"\]/);
|
|
assert.match(source, /crashingExecutable = "\/bin\/false"/);
|
|
const crashUpgrade = source.slice(
|
|
source.indexOf("const failedUpgrade = run("),
|
|
source.indexOf("if (failedUpgrade.status !== 1)"),
|
|
);
|
|
assert.match(crashUpgrade, /"upgrade-to-crashing-build"/);
|
|
assert.match(crashUpgrade, /\[1\]/);
|
|
assert.match(
|
|
crashUpgrade,
|
|
/180_000/,
|
|
"the outer crash-upgrade timeout must cover failure detection and rollback readiness",
|
|
);
|
|
const statusWait = source.slice(
|
|
source.indexOf("async function waitForRunningStatus"),
|
|
source.indexOf("async function waitForRecall"),
|
|
);
|
|
assert.match(statusWait, /\[0, 1, 3\]/);
|
|
assert.match(statusWait, /if \(result\.status === 0\)/);
|
|
assert.match(source, /recalled_after_rollback/);
|
|
assert.match(
|
|
source,
|
|
/databaseAfterUninstall\.sha256 !== databaseBeforeUninstall\.sha256/,
|
|
);
|
|
});
|