@pleri/olam-cli 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/image-presence.test.d.ts +2 -0
- package/dist/__tests__/image-presence.test.d.ts.map +1 -0
- package/dist/__tests__/image-presence.test.js +44 -0
- package/dist/__tests__/image-presence.test.js.map +1 -0
- package/dist/__tests__/protocol-version.test.d.ts +2 -0
- package/dist/__tests__/protocol-version.test.d.ts.map +1 -0
- package/dist/__tests__/protocol-version.test.js +170 -0
- package/dist/__tests__/protocol-version.test.js.map +1 -0
- package/dist/__tests__/registry-allowlist.test.d.ts +2 -0
- package/dist/__tests__/registry-allowlist.test.d.ts.map +1 -0
- package/dist/__tests__/registry-allowlist.test.js +129 -0
- package/dist/__tests__/registry-allowlist.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.all-three.test.d.ts +19 -0
- package/dist/commands/__tests__/upgrade.all-three.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.all-three.test.js +92 -0
- package/dist/commands/__tests__/upgrade.all-three.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.history.test.d.ts +15 -0
- package/dist/commands/__tests__/upgrade.history.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.history.test.js +199 -0
- package/dist/commands/__tests__/upgrade.history.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.lock.test.d.ts +15 -0
- package/dist/commands/__tests__/upgrade.lock.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.lock.test.js +253 -0
- package/dist/commands/__tests__/upgrade.lock.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts +21 -0
- package/dist/commands/__tests__/upgrade.olam-tag.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.olam-tag.test.js +127 -0
- package/dist/commands/__tests__/upgrade.olam-tag.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.poll.test.d.ts +14 -0
- package/dist/commands/__tests__/upgrade.poll.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.poll.test.js +136 -0
- package/dist/commands/__tests__/upgrade.poll.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.recreate.test.d.ts +17 -0
- package/dist/commands/__tests__/upgrade.recreate.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.recreate.test.js +95 -0
- package/dist/commands/__tests__/upgrade.recreate.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.rollback.test.d.ts +12 -0
- package/dist/commands/__tests__/upgrade.rollback.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.rollback.test.js +275 -0
- package/dist/commands/__tests__/upgrade.rollback.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts +12 -0
- package/dist/commands/__tests__/upgrade.sha-capture.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.sha-capture.test.js +63 -0
- package/dist/commands/__tests__/upgrade.sha-capture.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.smoke.test.d.ts +19 -0
- package/dist/commands/__tests__/upgrade.smoke.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.smoke.test.js +101 -0
- package/dist/commands/__tests__/upgrade.smoke.test.js.map +1 -0
- package/dist/commands/__tests__/upgrade.swap.test.d.ts +19 -0
- package/dist/commands/__tests__/upgrade.swap.test.d.ts.map +1 -0
- package/dist/commands/__tests__/upgrade.swap.test.js +333 -0
- package/dist/commands/__tests__/upgrade.swap.test.js.map +1 -0
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +31 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/upgrade-history.d.ts +17 -0
- package/dist/commands/upgrade-history.d.ts.map +1 -0
- package/dist/commands/upgrade-history.js +40 -0
- package/dist/commands/upgrade-history.js.map +1 -0
- package/dist/commands/upgrade-lock.d.ts +102 -0
- package/dist/commands/upgrade-lock.d.ts.map +1 -0
- package/dist/commands/upgrade-lock.js +225 -0
- package/dist/commands/upgrade-lock.js.map +1 -0
- package/dist/commands/upgrade-log.d.ts +86 -0
- package/dist/commands/upgrade-log.d.ts.map +1 -0
- package/dist/commands/upgrade-log.js +146 -0
- package/dist/commands/upgrade-log.js.map +1 -0
- package/dist/commands/upgrade.d.ts +265 -0
- package/dist/commands/upgrade.d.ts.map +1 -1
- package/dist/commands/upgrade.js +849 -13
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/image-presence.d.ts +40 -0
- package/dist/image-presence.d.ts.map +1 -0
- package/dist/image-presence.js +39 -0
- package/dist/image-presence.js.map +1 -0
- package/dist/index.js +1043 -167
- package/dist/index.js.map +1 -1
- package/dist/protocol-version.d.ts +79 -0
- package/dist/protocol-version.d.ts.map +1 -0
- package/dist/protocol-version.js +133 -0
- package/dist/protocol-version.js.map +1 -0
- package/dist/registry-allowlist.d.ts +47 -0
- package/dist/registry-allowlist.d.ts.map +1 -0
- package/dist/registry-allowlist.js +67 -0
- package/dist/registry-allowlist.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2b — verifies B1 (--rollback) + B2 (--force) + B3 (--no-cache) + B4 (drift refusal).
|
|
3
|
+
*
|
|
4
|
+
* Mix of:
|
|
5
|
+
* - vi.spyOn unit tests for the parseUpgradeOpts shape (B1/B2/B3 flags).
|
|
6
|
+
* - Real docker integration tests for performRollbackSwap + checkRollbackSetExists.
|
|
7
|
+
* - Source-text invariants for the drift refusal at swap boundary (B4).
|
|
8
|
+
*
|
|
9
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.rollback.test.ts`
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
13
|
+
import * as fs from 'node:fs';
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import { parseUpgradeOpts, performRollbackSwap, checkRollbackSetExists, imageExists, } from '../upgrade.js';
|
|
16
|
+
function dockerAvailable() {
|
|
17
|
+
const result = spawnSync('docker', ['version', '--format', '{{.Server.Version}}'], {
|
|
18
|
+
encoding: 'utf-8',
|
|
19
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
20
|
+
});
|
|
21
|
+
return result.status === 0;
|
|
22
|
+
}
|
|
23
|
+
const HAS_DOCKER = dockerAvailable();
|
|
24
|
+
function findRepoRoot(start) {
|
|
25
|
+
let dir = start;
|
|
26
|
+
for (let i = 0; i < 10; i++) {
|
|
27
|
+
if (fs.existsSync(path.join(dir, 'packages', 'host-cp', 'compose.yaml')))
|
|
28
|
+
return dir;
|
|
29
|
+
const parent = path.dirname(dir);
|
|
30
|
+
if (parent === dir)
|
|
31
|
+
break;
|
|
32
|
+
dir = parent;
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`Could not find repo root from ${start}`);
|
|
35
|
+
}
|
|
36
|
+
const REPO_ROOT = findRepoRoot(process.cwd());
|
|
37
|
+
const FIXTURE_DIR = path.join(REPO_ROOT, 'tests', 'fixtures', 'atomic-swap');
|
|
38
|
+
const UPGRADE_TS = path.join(REPO_ROOT, 'packages', 'cli', 'src', 'commands', 'upgrade.ts');
|
|
39
|
+
const TAG_PREFIX = `olam-test-rollback-${process.pid}`;
|
|
40
|
+
const TEST_PLAN = [
|
|
41
|
+
{
|
|
42
|
+
transient: `${TAG_PREFIX}-a:olam-next`,
|
|
43
|
+
canonical: `${TAG_PREFIX}-a:local`,
|
|
44
|
+
rollback: `${TAG_PREFIX}-a:olam-rollback`,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
transient: `${TAG_PREFIX}-b:olam-next`,
|
|
48
|
+
canonical: `${TAG_PREFIX}-b:latest`,
|
|
49
|
+
rollback: `${TAG_PREFIX}-b:olam-rollback`,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
transient: `${TAG_PREFIX}-c:olam-next`,
|
|
53
|
+
canonical: `${TAG_PREFIX}-c:latest`,
|
|
54
|
+
rollback: `${TAG_PREFIX}-c:olam-rollback`,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
const ALL_TEST_TAGS = TEST_PLAN.flatMap((p) => [p.transient, p.canonical, p.rollback]);
|
|
58
|
+
function buildFixtureImage(tag, labelValue) {
|
|
59
|
+
const result = spawnSync('docker', [
|
|
60
|
+
'build',
|
|
61
|
+
'--quiet',
|
|
62
|
+
'--build-arg', `LABEL_VAL=${labelValue}`,
|
|
63
|
+
'--tag', tag,
|
|
64
|
+
'--file', path.join(FIXTURE_DIR, 'Dockerfile.template'),
|
|
65
|
+
FIXTURE_DIR,
|
|
66
|
+
], { stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf-8' });
|
|
67
|
+
return result.status === 0;
|
|
68
|
+
}
|
|
69
|
+
function bakedSha(tag) {
|
|
70
|
+
const result = spawnSync('docker', ['inspect', '--format', '{{index .Config.Labels "olam_build_sha"}}', tag], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
71
|
+
if (result.status !== 0)
|
|
72
|
+
return null;
|
|
73
|
+
return (result.stdout ?? '').trim();
|
|
74
|
+
}
|
|
75
|
+
function cleanupTestImages() {
|
|
76
|
+
for (const tag of ALL_TEST_TAGS) {
|
|
77
|
+
spawnSync('docker', ['rmi', '-f', tag], { stdio: ['ignore', 'ignore', 'ignore'] });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
beforeAll(() => {
|
|
81
|
+
if (!HAS_DOCKER)
|
|
82
|
+
return;
|
|
83
|
+
cleanupTestImages();
|
|
84
|
+
}, 30_000);
|
|
85
|
+
afterAll(() => {
|
|
86
|
+
if (!HAS_DOCKER)
|
|
87
|
+
return;
|
|
88
|
+
cleanupTestImages();
|
|
89
|
+
}, 30_000);
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
if (!HAS_DOCKER)
|
|
92
|
+
return;
|
|
93
|
+
cleanupTestImages();
|
|
94
|
+
});
|
|
95
|
+
// ── B1 — parseUpgradeOpts surface ──────────────────────────────────
|
|
96
|
+
describe('parseUpgradeOpts — Phase 2b flags', () => {
|
|
97
|
+
it('parses --rollback / --force / --no-cache correctly', () => {
|
|
98
|
+
const opts = parseUpgradeOpts({
|
|
99
|
+
yes: true,
|
|
100
|
+
rollback: true,
|
|
101
|
+
force: true,
|
|
102
|
+
noCache: true,
|
|
103
|
+
});
|
|
104
|
+
expect(opts.rollback).toBe(true);
|
|
105
|
+
expect(opts.force).toBe(true);
|
|
106
|
+
expect(opts.noCache).toBe(true);
|
|
107
|
+
expect(opts.yes).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it('defaults Phase 2b flags to false when absent', () => {
|
|
110
|
+
const opts = parseUpgradeOpts({ yes: true });
|
|
111
|
+
expect(opts.rollback).toBe(false);
|
|
112
|
+
expect(opts.force).toBe(false);
|
|
113
|
+
expect(opts.noCache).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
// ── B1 — checkRollbackSetExists pre-flight ──────────────────────────
|
|
117
|
+
describe('checkRollbackSetExists — pre-flight (real docker)', () => {
|
|
118
|
+
it.skipIf(!HAS_DOCKER)('returns null when ALL three :olam-rollback tags exist', () => {
|
|
119
|
+
const SHA = '1111111111111111111111111111111111111111';
|
|
120
|
+
for (const p of TEST_PLAN) {
|
|
121
|
+
expect(buildFixtureImage(p.rollback, SHA)).toBe(true);
|
|
122
|
+
}
|
|
123
|
+
expect(checkRollbackSetExists(TEST_PLAN)).toBeNull();
|
|
124
|
+
}, 60_000);
|
|
125
|
+
it.skipIf(!HAS_DOCKER)('returns missing tag list when any :olam-rollback is absent', () => {
|
|
126
|
+
const SHA = '2222222222222222222222222222222222222222';
|
|
127
|
+
// Build only first 2 rollback tags; third is missing.
|
|
128
|
+
expect(buildFixtureImage(TEST_PLAN[0].rollback, SHA)).toBe(true);
|
|
129
|
+
expect(buildFixtureImage(TEST_PLAN[1].rollback, SHA)).toBe(true);
|
|
130
|
+
const missing = checkRollbackSetExists(TEST_PLAN);
|
|
131
|
+
expect(missing).not.toBeNull();
|
|
132
|
+
expect(missing).toContain(TEST_PLAN[2].rollback);
|
|
133
|
+
}, 60_000);
|
|
134
|
+
it.skipIf(!HAS_DOCKER)('returns ALL three when no :olam-rollback exists (first-upgrade case)', () => {
|
|
135
|
+
const missing = checkRollbackSetExists(TEST_PLAN);
|
|
136
|
+
expect(missing).not.toBeNull();
|
|
137
|
+
for (const p of TEST_PLAN) {
|
|
138
|
+
expect(missing).toContain(p.rollback);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
describe('imageExists', () => {
|
|
143
|
+
it.skipIf(!HAS_DOCKER)('returns true for an existing image', () => {
|
|
144
|
+
const SHA = '3333333333333333333333333333333333333333';
|
|
145
|
+
expect(buildFixtureImage(TEST_PLAN[0].canonical, SHA)).toBe(true);
|
|
146
|
+
expect(imageExists(TEST_PLAN[0].canonical)).toBe(true);
|
|
147
|
+
}, 60_000);
|
|
148
|
+
it.skipIf(!HAS_DOCKER)('returns false for a non-existent image', () => {
|
|
149
|
+
expect(imageExists(`${TAG_PREFIX}-does-not-exist:nope`)).toBe(false);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
// ── B1 — performRollbackSwap (the inverse swap) ───────────────────
|
|
153
|
+
describe('performRollbackSwap — inverse atomic 3-tag swap (real docker)', () => {
|
|
154
|
+
it.skipIf(!HAS_DOCKER)('restores canonical from :olam-rollback for all three images', () => {
|
|
155
|
+
const PRIOR_SHA = '4444444444444444444444444444444444444444';
|
|
156
|
+
const BROKEN_SHA = '5555555555555555555555555555555555555555';
|
|
157
|
+
// Setup: canonical at BROKEN_SHA (current broken state); :olam-rollback
|
|
158
|
+
// at PRIOR_SHA (last-good captured by previous successful upgrade).
|
|
159
|
+
for (const p of TEST_PLAN) {
|
|
160
|
+
expect(buildFixtureImage(p.canonical, BROKEN_SHA)).toBe(true);
|
|
161
|
+
expect(buildFixtureImage(p.rollback, PRIOR_SHA)).toBe(true);
|
|
162
|
+
}
|
|
163
|
+
const result = performRollbackSwap(TEST_PLAN);
|
|
164
|
+
expect(result.ok).toBe(true);
|
|
165
|
+
expect(result.results.length).toBe(3);
|
|
166
|
+
for (const r of result.results) {
|
|
167
|
+
expect(r.ok).toBe(true);
|
|
168
|
+
}
|
|
169
|
+
expect(result.summary).toContain('Rolled back');
|
|
170
|
+
// Post-state: canonical now at PRIOR_SHA (from :olam-rollback).
|
|
171
|
+
for (const p of TEST_PLAN) {
|
|
172
|
+
expect(bakedSha(p.canonical)).toBe(PRIOR_SHA);
|
|
173
|
+
// :olam-rollback unchanged (rollback is non-destructive on the source).
|
|
174
|
+
expect(bakedSha(p.rollback)).toBe(PRIOR_SHA);
|
|
175
|
+
}
|
|
176
|
+
}, 60_000);
|
|
177
|
+
it.skipIf(!HAS_DOCKER)('partial-failure: returns ok=false when any :olam-rollback is missing', () => {
|
|
178
|
+
const PRIOR_SHA = '6666666666666666666666666666666666666666';
|
|
179
|
+
// Setup: only first :olam-rollback exists.
|
|
180
|
+
expect(buildFixtureImage(TEST_PLAN[0].rollback, PRIOR_SHA)).toBe(true);
|
|
181
|
+
const result = performRollbackSwap(TEST_PLAN);
|
|
182
|
+
expect(result.ok).toBe(false);
|
|
183
|
+
expect(result.summary).toContain('PARTIAL rollback');
|
|
184
|
+
expect(result.results[0].ok).toBe(true); // first succeeded
|
|
185
|
+
expect(result.results[1].ok).toBe(false); // second failed (no source)
|
|
186
|
+
expect(result.results[2].ok).toBe(false);
|
|
187
|
+
}, 60_000);
|
|
188
|
+
});
|
|
189
|
+
// ── B4 — drift refusal at swap boundary (source-text) ──────────────
|
|
190
|
+
describe('Phase 2b — drift refusal at swap boundary (B4)', () => {
|
|
191
|
+
let body;
|
|
192
|
+
it('reads upgrade.ts source', () => {
|
|
193
|
+
body = fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
194
|
+
});
|
|
195
|
+
it('captures HEAD SHA at swap boundary AFTER the build loop', () => {
|
|
196
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
197
|
+
// The drift check must call captureHeadSha AFTER the build loop completes.
|
|
198
|
+
const buildLoopIdx = body.indexOf('for (const step of buildScripts');
|
|
199
|
+
const driftCheckIdx = body.indexOf('swapBoundarySha = captureHeadSha');
|
|
200
|
+
expect(buildLoopIdx).toBeGreaterThan(0);
|
|
201
|
+
expect(driftCheckIdx).toBeGreaterThan(buildLoopIdx);
|
|
202
|
+
});
|
|
203
|
+
it('refuses with exit 1 when HEAD drifted and --force is NOT set', () => {
|
|
204
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
205
|
+
const driftMatch = body.match(/HEAD drifted during build window:[\s\S]*?process\.exitCode\s*=\s*1/);
|
|
206
|
+
expect(driftMatch).not.toBeNull();
|
|
207
|
+
expect(driftMatch[0]).toContain('--force');
|
|
208
|
+
});
|
|
209
|
+
it('drift check guarded by !opts.force (B2 bypass)', () => {
|
|
210
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
211
|
+
expect(body).toMatch(/swapBoundarySha\s*!==\s*_targetSha\s*&&\s*!opts\.force/);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
// ── B3 — --no-cache passthrough (source-text) ──────────────────────
|
|
215
|
+
describe('Phase 2b — --no-cache passthrough (B3)', () => {
|
|
216
|
+
let body;
|
|
217
|
+
it('reads upgrade.ts source', () => {
|
|
218
|
+
body = fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
219
|
+
});
|
|
220
|
+
it('forwards DOCKER_BUILD_NO_CACHE=1 to build script env when opts.noCache', () => {
|
|
221
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
222
|
+
expect(body).toMatch(/if\s*\(opts\.noCache\)\s*\{\s*olamTagEnv\.DOCKER_BUILD_NO_CACHE\s*=\s*['"]1['"]/);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
// ── handleRollback wired into commander (source-text) ──────────────
|
|
226
|
+
describe('Phase 2b — handleRollback wired in handleUpgrade dispatch', () => {
|
|
227
|
+
let body;
|
|
228
|
+
it('reads upgrade.ts source', () => {
|
|
229
|
+
body = fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
230
|
+
});
|
|
231
|
+
it('handleUpgrade early-returns to handleRollback when opts.rollback', () => {
|
|
232
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
233
|
+
// Look for the dispatch in handleUpgrade.
|
|
234
|
+
const handleUpgradeStart = body.indexOf('async function handleUpgrade(');
|
|
235
|
+
const dispatchMatch = body.slice(handleUpgradeStart).match(/if\s*\(opts\.rollback\)\s*\{\s*return\s+await\s+handleRollback\(\);?\s*\}/);
|
|
236
|
+
expect(dispatchMatch).not.toBeNull();
|
|
237
|
+
});
|
|
238
|
+
it('handleRollback acquires the same upgrade lock as the upgrade path', () => {
|
|
239
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
240
|
+
const fnStart = body.indexOf('async function handleRollback');
|
|
241
|
+
expect(fnStart).toBeGreaterThan(0);
|
|
242
|
+
const fnBody = body.slice(fnStart, fnStart + 3000); // 3KB window covers the function
|
|
243
|
+
expect(fnBody).toMatch(/acquireLock\(/);
|
|
244
|
+
expect(fnBody).toMatch(/releaseLock\(/);
|
|
245
|
+
});
|
|
246
|
+
it('handleRollback pre-flights checkRollbackSetExists before any retag', () => {
|
|
247
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
248
|
+
const fnStart = body.indexOf('async function handleRollback');
|
|
249
|
+
const fnBody = body.slice(fnStart, fnStart + 3000);
|
|
250
|
+
const preflightIdx = fnBody.indexOf('checkRollbackSetExists');
|
|
251
|
+
const swapIdx = fnBody.indexOf('performRollbackSwap');
|
|
252
|
+
expect(preflightIdx).toBeGreaterThan(0);
|
|
253
|
+
expect(swapIdx).toBeGreaterThan(preflightIdx);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
// ── commander registration (source-text) ───────────────────────────
|
|
257
|
+
describe('registerUpgrade — Phase 2b flags exposed', () => {
|
|
258
|
+
let body;
|
|
259
|
+
it('reads upgrade.ts source', () => {
|
|
260
|
+
body = fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
261
|
+
});
|
|
262
|
+
it('declares --rollback option', () => {
|
|
263
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
264
|
+
expect(body).toMatch(/\.option\(\s*['"]--rollback['"]/);
|
|
265
|
+
});
|
|
266
|
+
it('declares --force option', () => {
|
|
267
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
268
|
+
expect(body).toMatch(/\.option\(\s*['"]--force['"]/);
|
|
269
|
+
});
|
|
270
|
+
it('declares --no-cache option', () => {
|
|
271
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
272
|
+
expect(body).toMatch(/\.option\(\s*['"]--no-cache['"]/);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
//# sourceMappingURL=upgrade.rollback.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.rollback.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.rollback.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for `olam upgrade` HEAD SHA capture (Phase 2a — A2).
|
|
3
|
+
*
|
|
4
|
+
* Verifies:
|
|
5
|
+
* - captureHeadSha returns a 40-char lowercase-hex SHA for a real git repo.
|
|
6
|
+
* - captureHeadSha returns null when `git rev-parse HEAD` fails (non-repo cwd).
|
|
7
|
+
* - abbreviateSha returns the first 8 chars.
|
|
8
|
+
*
|
|
9
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.sha-capture.test.ts`
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=upgrade.sha-capture.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.sha-capture.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.sha-capture.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for `olam upgrade` HEAD SHA capture (Phase 2a — A2).
|
|
3
|
+
*
|
|
4
|
+
* Verifies:
|
|
5
|
+
* - captureHeadSha returns a 40-char lowercase-hex SHA for a real git repo.
|
|
6
|
+
* - captureHeadSha returns null when `git rev-parse HEAD` fails (non-repo cwd).
|
|
7
|
+
* - abbreviateSha returns the first 8 chars.
|
|
8
|
+
*
|
|
9
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.sha-capture.test.ts`
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as os from 'node:os';
|
|
14
|
+
import * as path from 'node:path';
|
|
15
|
+
import { spawnSync } from 'node:child_process';
|
|
16
|
+
import { captureHeadSha, abbreviateSha } from '../upgrade.js';
|
|
17
|
+
let tmpDir;
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'olam-sha-test-'));
|
|
20
|
+
});
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
try {
|
|
23
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// best effort
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
describe('captureHeadSha — happy path', () => {
|
|
30
|
+
it('returns a 40-char lowercase-hex SHA for a fresh git repo with a commit', () => {
|
|
31
|
+
spawnSync('git', ['init', '--initial-branch=main', '-q'], { cwd: tmpDir });
|
|
32
|
+
spawnSync('git', ['config', 'user.email', 'test@example.com'], { cwd: tmpDir });
|
|
33
|
+
spawnSync('git', ['config', 'user.name', 'Test'], { cwd: tmpDir });
|
|
34
|
+
fs.writeFileSync(path.join(tmpDir, 'README.md'), 'test');
|
|
35
|
+
spawnSync('git', ['add', '.'], { cwd: tmpDir });
|
|
36
|
+
spawnSync('git', ['commit', '-m', 'init', '-q', '--no-gpg-sign'], { cwd: tmpDir });
|
|
37
|
+
const sha = captureHeadSha(tmpDir);
|
|
38
|
+
expect(sha).not.toBeNull();
|
|
39
|
+
expect(sha).toMatch(/^[0-9a-f]{40}$/);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe('captureHeadSha — failure modes', () => {
|
|
43
|
+
it('returns null in a non-git directory', () => {
|
|
44
|
+
expect(captureHeadSha(tmpDir)).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
it('returns null when cwd does not exist', () => {
|
|
47
|
+
const ghost = path.join(tmpDir, 'does-not-exist');
|
|
48
|
+
expect(captureHeadSha(ghost)).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
it('returns null in a git repo with no commits', () => {
|
|
51
|
+
spawnSync('git', ['init', '--initial-branch=main', '-q'], { cwd: tmpDir });
|
|
52
|
+
expect(captureHeadSha(tmpDir)).toBeNull();
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('abbreviateSha', () => {
|
|
56
|
+
it('returns the first 8 chars of a 40-char SHA', () => {
|
|
57
|
+
expect(abbreviateSha('1234567890abcdef1234567890abcdef12345678')).toBe('12345678');
|
|
58
|
+
});
|
|
59
|
+
it('returns the input unchanged when shorter than 8 chars', () => {
|
|
60
|
+
expect(abbreviateSha('abc')).toBe('abc');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
//# sourceMappingURL=upgrade.sha-capture.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.sha-capture.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.sha-capture.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2a A5 — verifies smokeImage logic.
|
|
3
|
+
*
|
|
4
|
+
* Two layers:
|
|
5
|
+
* 1. Source-text invariant: smokeImage helper is invoked from
|
|
6
|
+
* handleUpgrade with the correct image-tag list + target SHA.
|
|
7
|
+
* 2. Real docker integration: smokeImage against a non-existent image
|
|
8
|
+
* returns ok=false with a meaningful error (validates the docker
|
|
9
|
+
* create + inspect failure path).
|
|
10
|
+
*
|
|
11
|
+
* Fixture-built images (FROM scratch + label) are deferred to manual smoke
|
|
12
|
+
* via tests/integration/upgrade-smoke.sh — building from macOS /var/folders
|
|
13
|
+
* tmpdir hits xattr permission errors on Docker Desktop and isn't reliable
|
|
14
|
+
* for CI.
|
|
15
|
+
*
|
|
16
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.smoke.test.ts`
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=upgrade.smoke.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.smoke.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.smoke.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2a A5 — verifies smokeImage logic.
|
|
3
|
+
*
|
|
4
|
+
* Two layers:
|
|
5
|
+
* 1. Source-text invariant: smokeImage helper is invoked from
|
|
6
|
+
* handleUpgrade with the correct image-tag list + target SHA.
|
|
7
|
+
* 2. Real docker integration: smokeImage against a non-existent image
|
|
8
|
+
* returns ok=false with a meaningful error (validates the docker
|
|
9
|
+
* create + inspect failure path).
|
|
10
|
+
*
|
|
11
|
+
* Fixture-built images (FROM scratch + label) are deferred to manual smoke
|
|
12
|
+
* via tests/integration/upgrade-smoke.sh — building from macOS /var/folders
|
|
13
|
+
* tmpdir hits xattr permission errors on Docker Desktop and isn't reliable
|
|
14
|
+
* for CI.
|
|
15
|
+
*
|
|
16
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.smoke.test.ts`
|
|
17
|
+
*/
|
|
18
|
+
import { describe, it, expect } from 'vitest';
|
|
19
|
+
import { spawnSync } from 'node:child_process';
|
|
20
|
+
import * as fs from 'node:fs';
|
|
21
|
+
import * as path from 'node:path';
|
|
22
|
+
import { smokeImage } from '../upgrade.js';
|
|
23
|
+
function dockerAvailable() {
|
|
24
|
+
const result = spawnSync('docker', ['version', '--format', '{{.Server.Version}}'], {
|
|
25
|
+
encoding: 'utf-8',
|
|
26
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
27
|
+
});
|
|
28
|
+
return result.status === 0;
|
|
29
|
+
}
|
|
30
|
+
const HAS_DOCKER = dockerAvailable();
|
|
31
|
+
function findRepoRoot(start) {
|
|
32
|
+
let dir = start;
|
|
33
|
+
for (let i = 0; i < 10; i++) {
|
|
34
|
+
if (fs.existsSync(path.join(dir, 'packages', 'host-cp', 'compose.yaml')))
|
|
35
|
+
return dir;
|
|
36
|
+
const parent = path.dirname(dir);
|
|
37
|
+
if (parent === dir)
|
|
38
|
+
break;
|
|
39
|
+
dir = parent;
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Could not find repo root from ${start}`);
|
|
42
|
+
}
|
|
43
|
+
const REPO_ROOT = findRepoRoot(process.cwd());
|
|
44
|
+
const UPGRADE_TS = path.join(REPO_ROOT, 'packages', 'cli', 'src', 'commands', 'upgrade.ts');
|
|
45
|
+
describe('smokeImage — failure-path integration (real docker)', () => {
|
|
46
|
+
it.skipIf(!HAS_DOCKER)('returns ok=false for a non-existent image', () => {
|
|
47
|
+
const result = smokeImage('olam-smoke-does-not-exist:nope', '1234567890abcdef1234567890abcdef12345678');
|
|
48
|
+
expect(result.ok).toBe(false);
|
|
49
|
+
expect(result.error).toBeTruthy();
|
|
50
|
+
// Error should reference the docker daemon's response.
|
|
51
|
+
expect(result.error?.toLowerCase()).toMatch(/docker (create|inspect) failed|no such image|repository|pull access denied/);
|
|
52
|
+
});
|
|
53
|
+
it('exposes the image name in the result for downstream UX', () => {
|
|
54
|
+
const result = smokeImage('olam-smoke-does-not-exist:nope', '0'.repeat(40));
|
|
55
|
+
expect(result.image).toBe('olam-smoke-does-not-exist:nope');
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe('Phase 2a A5 — smoke wired into handleUpgrade', () => {
|
|
59
|
+
let body;
|
|
60
|
+
it('reads upgrade.ts source', () => {
|
|
61
|
+
body = fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
62
|
+
expect(body.length).toBeGreaterThan(1000);
|
|
63
|
+
});
|
|
64
|
+
it('declares the three :olam-next image tags for smoking', () => {
|
|
65
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
66
|
+
expect(body).toContain('olam-auth:olam-next');
|
|
67
|
+
expect(body).toContain('olam-devbox:olam-next');
|
|
68
|
+
expect(body).toContain('olam-host-cp:olam-next');
|
|
69
|
+
});
|
|
70
|
+
it('runs smoke after the build loop (smoke must come AFTER buildScripts)', () => {
|
|
71
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
72
|
+
const buildLoopIdx = body.indexOf('for (const step of buildScripts');
|
|
73
|
+
const smokeIdx = body.indexOf('smokeImages');
|
|
74
|
+
expect(buildLoopIdx).toBeGreaterThan(0);
|
|
75
|
+
expect(smokeIdx).toBeGreaterThan(buildLoopIdx);
|
|
76
|
+
});
|
|
77
|
+
it('aborts with exit 1 on smoke failure (canonical tags untouched)', () => {
|
|
78
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
79
|
+
// Expect "Canonical tags … untouched" message + process.exitCode = 1
|
|
80
|
+
// co-located in the smoke-failure branch.
|
|
81
|
+
const match = body.match(/Smoke failed[\s\S]*?process\.exitCode\s*=\s*1/);
|
|
82
|
+
expect(match).not.toBeNull();
|
|
83
|
+
expect(match[0]).toContain('Canonical tags');
|
|
84
|
+
});
|
|
85
|
+
it('passes _targetSha to smokeImage (sticky-after-pull capture from A2)', () => {
|
|
86
|
+
body ??= fs.readFileSync(UPGRADE_TS, 'utf-8');
|
|
87
|
+
expect(body).toMatch(/smokeImage\(\s*\w+\s*,\s*_targetSha\s*\)/);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe('SmokeResult shape', () => {
|
|
91
|
+
it('returns the SmokeResult contract for non-existent images', () => {
|
|
92
|
+
const result = smokeImage('olam-smoke-does-not-exist:nope', '0'.repeat(40));
|
|
93
|
+
// Result MUST have image, ok, bakedSha keys; error is optional but present
|
|
94
|
+
// on failure.
|
|
95
|
+
expect(result).toHaveProperty('image');
|
|
96
|
+
expect(result).toHaveProperty('ok');
|
|
97
|
+
expect(result).toHaveProperty('bakedSha');
|
|
98
|
+
expect(result.ok).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=upgrade.smoke.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.smoke.test.js","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.smoke.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,SAAS,eAAe;IACtB,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,qBAAqB,CAAC,EAAE;QACjF,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;KACpC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,GAAG,eAAe,EAAE,CAAC;AAErC,SAAS,YAAY,CAAC,KAAa;IACjC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACrF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAE5F,QAAQ,CAAC,qDAAqD,EAAE,GAAG,EAAE;IACnE,EAAE,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,UAAU,CAAC,gCAAgC,EAAE,0CAA0C,CAAC,CAAC;QACxG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,uDAAuD;QACvD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,4EAA4E,CAAC,CAAC;IAC5H,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,UAAU,CAAC,gCAAgC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,IAAI,IAAY,CAAC;IAEjB,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC7C,MAAM,CAAC,YAAY,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,qEAAqE;QACrE,0CAA0C;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;QAC1E,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,IAAI,KAAK,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,MAAM,GAAG,UAAU,CAAC,gCAAgC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,2EAA2E;QAC3E,cAAc;QACd,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase 2a A6 — atomic 6-tag swap integration tests (real docker).
|
|
3
|
+
*
|
|
4
|
+
* Validates the load-bearing rollback contract:
|
|
5
|
+
* 1. Happy path: swap leaves canonical pointing at :olam-next images;
|
|
6
|
+
* :olam-rollback preserves the previous canonical SHAs.
|
|
7
|
+
* 2. First-upgrade tolerance: missing canonical → rollback-save fails
|
|
8
|
+
* non-fatally; canonical-advance still succeeds.
|
|
9
|
+
* 3. Canonical-advance fatality: missing :olam-next → fatal abort;
|
|
10
|
+
* partialAdvance flag set; summary references --rollback recovery.
|
|
11
|
+
* 4. SIGKILL-recovery checkpoint: :olam-rollback is fully populated
|
|
12
|
+
* BEFORE any canonical-advance touches the canonical tags.
|
|
13
|
+
*
|
|
14
|
+
* Skipped automatically when docker is unavailable (e.g. CI without daemon).
|
|
15
|
+
*
|
|
16
|
+
* Run: `cd packages/cli && npx vitest run src/commands/__tests__/upgrade.swap.test.ts`
|
|
17
|
+
*/
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=upgrade.swap.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upgrade.swap.test.d.ts","sourceRoot":"","sources":["../../../src/commands/__tests__/upgrade.swap.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG"}
|