ci(ql3): expose content-free migration failure facts

This commit is contained in:
whyour
2026-08-25 09:51:00 +08:00
parent 82348e9f91
commit 9afcf9413c
2 changed files with 102 additions and 11 deletions
@@ -14,6 +14,7 @@ const {
identity,
identityRegisterCommand,
inputAuthorityEvidenceSource,
migrationFailureEvidence,
} = require('../../scripts/ql3-security-administration-kubernetes-live-contract.cjs');
const values = Object.freeze({
@@ -112,6 +113,57 @@ test('constrains only the exact local-path fixture root without network authorit
assert.doesNotMatch(source, /net|fetch|http/);
});
test('keeps migration failure evidence content-free', () => {
const base = {
complete: false,
failed: true,
pod: {
status: {
phase: 'Failed',
containerStatuses: [
{
name: 'migration',
state: {
terminated: {
exitCode: 1,
reason: 'Error',
message: JSON.stringify({
schemaVersion: 1,
component: 'qinglong3-cluster-migration',
event: 'migration_failed',
name: 'Error',
code: 'EAI_AGAIN',
}),
},
},
},
],
},
},
};
assert.deepEqual(migrationFailureEvidence(base), {
jobComplete: false,
jobFailed: true,
podPhase: 'Failed',
exitCode: 1,
reason: 'Error',
failureMessage: {
schemaVersion: 1,
component: 'qinglong3-cluster-migration',
event: 'migration_failed',
name: 'Error',
code: 'EAI_AGAIN',
},
});
const rejected = structuredClone(base);
rejected.pod.status.containerStatuses[0].state.terminated.message =
JSON.stringify({ code: 'EAI_AGAIN', secret: 'must-not-escape' });
assert.equal(
migrationFailureEvidence(rejected).failureMessage,
'rejected',
);
});
test('live runner remains opt-in, reviewed, cleanup-bound and log-free', () => {
const source = fs.readFileSync(
path.resolve(