fix: route portal canary through isolated edge tunnel
Memind CI / Test, build, and release guards (push) Has been cancelled
Memind CI / Test, build, and release guards (push) Has been cancelled
This commit is contained in:
@@ -6,6 +6,25 @@ import test from 'node:test';
|
||||
|
||||
const ROOT = path.resolve(new URL('..', import.meta.url).pathname);
|
||||
const CANARY_RELEASE = path.join(ROOT, 'scripts', 'release-portal-canary-prod.sh');
|
||||
const CANARY_ROLLBACK = path.join(ROOT, 'scripts', 'rollback-portal-canary-prod.sh');
|
||||
|
||||
function heredocBody(source, opener, closer) {
|
||||
const start = source.indexOf(opener);
|
||||
assert.ok(start >= 0, `missing heredoc opener: ${opener}`);
|
||||
const bodyStart = source.indexOf('\n', start) + 1;
|
||||
const end = source.indexOf(`\n${closer}\n`, bodyStart);
|
||||
assert.ok(bodyStart > 0 && end >= bodyStart, `missing heredoc closer: ${closer}`);
|
||||
return source.slice(bodyStart, end);
|
||||
}
|
||||
|
||||
function assertShellParses(source, label) {
|
||||
const result = spawnSync('bash', ['-n'], {
|
||||
cwd: ROOT,
|
||||
encoding: 'utf8',
|
||||
input: source,
|
||||
});
|
||||
assert.equal(result.status, 0, `${label} failed bash -n:\n${result.stderr}`);
|
||||
}
|
||||
|
||||
test('production release verifies gate report before any 103 connection', async () => {
|
||||
const source = await fs.readFile(
|
||||
@@ -96,28 +115,61 @@ test('production canary keeps stable 8081 live and switches only after verified
|
||||
const source = await fs.readFile(CANARY_RELEASE, 'utf8');
|
||||
const fullBackup = source.indexOf('Create and verify the full stable backup');
|
||||
const persistBackup = source.indexOf('Create and verify the persisted-data backup');
|
||||
const edgeBackup = source.indexOf('Create and verify the active 105 nginx routing backup');
|
||||
const goosedStart = source.indexOf('Start an isolated goosed candidate on 18015');
|
||||
const candidateStart = source.indexOf('Start the passive candidate Portal on 18081');
|
||||
const proxyStart = source.indexOf('Start the fail-closed identity router on 18080');
|
||||
const tunnelSwitch = source.indexOf('Switch only the reverse tunnel');
|
||||
const proxyStart = source.indexOf('Start the fail-closed identity router on 18082');
|
||||
const tunnelStart = source.indexOf('Start the isolated 105 reverse tunnel on 19082');
|
||||
const edgeSwitch = source.indexOf(
|
||||
'Switch the committed 105 nginx upstreams to the isolated canary tunnel',
|
||||
);
|
||||
const fallbackProbe = source.indexOf('route-probe?username=john');
|
||||
assert.ok(fullBackup > 0);
|
||||
assert.ok(persistBackup > fullBackup);
|
||||
assert.ok(goosedStart > persistBackup);
|
||||
assert.ok(edgeBackup > persistBackup);
|
||||
assert.ok(goosedStart > edgeBackup);
|
||||
assert.ok(candidateStart > goosedStart);
|
||||
assert.ok(proxyStart > candidateStart);
|
||||
assert.ok(tunnelSwitch > proxyStart);
|
||||
assert.ok(fallbackProbe > tunnelSwitch);
|
||||
assert.match(source, /write_tunnel_plist 8081/);
|
||||
assert.ok(tunnelStart > proxyStart);
|
||||
assert.ok(edgeSwitch > tunnelStart);
|
||||
assert.ok(fallbackProbe > edgeSwitch);
|
||||
assert.match(source, /restore_edge_to_stable/);
|
||||
assert.match(source, /proxy_pass http:\/\/58\.38\.22\.103:8081;/);
|
||||
assert.match(source, /proxy_pass http:\/\/127\.0\.0\.1:\$\{CANARY_TUNNEL_REMOTE_PORT\};/);
|
||||
assert.match(source, /nginx -t/);
|
||||
assert.match(source, /CANARY_PROXY_PORT=18082/);
|
||||
assert.match(source, /CANARY_TUNNEL_REMOTE_PORT=19082/);
|
||||
assert.match(source, /CANARY_USERNAMES="john"/);
|
||||
assert.match(source, /CANARY_WECHAT_USER_IDS="wx_ul610et8"/);
|
||||
assert.match(source, /route-probe\?\$\{probe_query\}/);
|
||||
assert.match(source, /candidate_healthy/);
|
||||
assert.match(source, /MEMIND_CANARY_RELEASE_ID/);
|
||||
assert.match(
|
||||
source,
|
||||
/if restore_edge_to_stable >\/dev\/null 2>&1; then\s+stop_candidate_services/,
|
||||
);
|
||||
assert.match(source, /keeping canary services running/);
|
||||
assert.match(source, /--resolve wechat\.m\.tkmind\.cn:443:127\.0\.0\.1/);
|
||||
assert.doesNotMatch(source, /lsof -tiTCP:8081/);
|
||||
assert.doesNotMatch(source, /bootout.*cn\.tkmind\.memind-portal/);
|
||||
});
|
||||
|
||||
test('canary release and rollback remote shells remain syntactically valid', async () => {
|
||||
const releaseSource = await fs.readFile(CANARY_RELEASE, 'utf8');
|
||||
const rollbackSource = await fs.readFile(CANARY_ROLLBACK, 'utf8');
|
||||
const releaseRemote = heredocBody(releaseSource, "<<'REMOTE_SCRIPT'", 'REMOTE_SCRIPT');
|
||||
const rollbackRemote = heredocBody(rollbackSource, "<<'REMOTE'", 'REMOTE');
|
||||
const edgeSwitch = heredocBody(releaseRemote, '<<EDGE_SWITCH', 'EDGE_SWITCH')
|
||||
.replaceAll('\\$', '$');
|
||||
const edgeRollback = heredocBody(rollbackRemote, '<<EDGE_ROLLBACK', 'EDGE_ROLLBACK')
|
||||
.replaceAll('\\$', '$');
|
||||
|
||||
assertShellParses(releaseRemote, 'release remote shell');
|
||||
assertShellParses(rollbackRemote, 'rollback remote shell');
|
||||
assertShellParses(edgeSwitch, '105 edge switch shell');
|
||||
assertShellParses(edgeRollback, '105 edge rollback shell');
|
||||
});
|
||||
|
||||
test('release readiness ignores only the generated canary artifact cover path', async () => {
|
||||
const source = await fs.readFile(
|
||||
path.join(ROOT, 'scripts', 'check-release-ready.sh'),
|
||||
|
||||
Reference in New Issue
Block a user