mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-19 09:44:07 +00:00
fix(upgrade): doctor fetches tags before deciding latest + post-flight asserts served version (#173) (#174)
Two fixes for the two halves of issue #173, both from live incidents during the 2026-07-17 fleet update: 1. scripts/doctor.mjs — `git show origin/main:package.json` reads the LOCALLY CACHED remote ref; without a fetch first, any machine that hadn't pulled since the last release saw latest == current and reported "Already at latest" (live repro: Oracle VM at 3.21.1 with v3.22.1 released). The doctor now runs `git fetch --tags --quiet` (15s timeout) before comparing, gated on !opts.skipNetwork; on failure (offline/auth) it falls through to the cached ref — the pre-existing behavior. All existing doctor tests pass mockLatest + skipNetwork, so no test touches the network. 2. scripts/upgrade.mjs — post-flight accepted any healthy /health (auth.ok only), so a stale process holding the port passed post-flight while still serving the OLD version (live repro: a Jul-7 nohup-fallback orphan held :3456; upgrade "succeeded", /health kept serving 3.21.1). New exported predicate postFlightOk(body, target): auth.ok AND /health.version === target (leading-v tolerant; empty target degrades to the auth-only check, never blocks). The failure message now reports the last-seen version and points at the stale-process diagnosis (`ss -ltnp` / `lsof -i`). Tests: +4, mutation-proven — reverting the predicate to auth-only fails the "orphan case" test (337/1). Full suite 338 passed / 0 failed. No server.mjs change — scripts layer only; no cli.js operation involved, so no citation applies. Closes #173 Co-authored-by: dtzp555 <dtzp555@gmail.com> Co-authored-by: Claude <claude-opus-4-8> <noreply@anthropic.com>
This commit is contained in:
+25
-1
@@ -822,10 +822,34 @@ test("doctor falls back to currentVersion when origin/main unreachable (no stale
|
||||
});
|
||||
|
||||
// ── Upgrade Tests ──
|
||||
import { runUpgrade } from "./scripts/upgrade.mjs";
|
||||
import { runUpgrade, postFlightOk } from "./scripts/upgrade.mjs";
|
||||
|
||||
console.log("\nUpgrade:");
|
||||
|
||||
// ── postFlightOk (issue #173) — the acceptance predicate for phase 6 ─────────
|
||||
// Mutation-proof: revert the version comparison to auth-only and the "stale process
|
||||
// still holds the port" test below goes green-to-red (that case is the 2026-07-17
|
||||
// Oracle incident: orphan answered auth.ok=true while serving the OLD version).
|
||||
test("postFlightOk: rejects a healthy-looking probe that serves the WRONG version (orphan case)", () => {
|
||||
assert.equal(postFlightOk({ auth: { ok: true }, version: "3.21.1" }, "v3.22.1"), false);
|
||||
});
|
||||
|
||||
test("postFlightOk: accepts auth.ok + exact target version, tolerating the leading v", () => {
|
||||
assert.equal(postFlightOk({ auth: { ok: true }, version: "3.22.1" }, "v3.22.1"), true);
|
||||
assert.equal(postFlightOk({ auth: { ok: true }, version: "3.22.1" }, "3.22.1"), true);
|
||||
});
|
||||
|
||||
test("postFlightOk: auth failure rejects regardless of version", () => {
|
||||
assert.equal(postFlightOk({ auth: { ok: false }, version: "3.22.1" }, "v3.22.1"), false);
|
||||
assert.equal(postFlightOk({ version: "3.22.1" }, "v3.22.1"), false);
|
||||
assert.equal(postFlightOk(null, "v3.22.1"), false);
|
||||
});
|
||||
|
||||
test("postFlightOk: unknown/empty target degrades to the auth-only check (never blocks)", () => {
|
||||
assert.equal(postFlightOk({ auth: { ok: true }, version: "3.22.1" }, ""), true);
|
||||
assert.equal(postFlightOk({ auth: { ok: true }, version: "3.22.1" }, undefined), true);
|
||||
});
|
||||
|
||||
test("upgrade --dry-run prints plan, no side effects", async () => {
|
||||
const result = await runUpgrade({
|
||||
dryRun: true,
|
||||
|
||||
Reference in New Issue
Block a user