Files
qinglong/test/back/ql3PostgresHaEvidenceAudit.test.cjs
T

111 lines
3.5 KiB
JavaScript

const assert = require('node:assert/strict');
const { test } = require('node:test');
const {
EXPECTED_LIMITATIONS,
auditPostgresHaEvidence,
} = require('../../scripts/ql3-postgres-ha-evidence-audit.cjs');
function fixture() {
const gates = { passed: true };
for (let index = 0; index < 100; index += 1) gates[`gate${index}`] = true;
return {
schemaVersion: 1,
fixture: 'qinglong/postgresql-ha-contract@v1',
postgres: {
image: 'postgres:18',
imageId: `sha256:${'a'.repeat(64)}`,
repoDigests: [`postgres@sha256:${'b'.repeat(64)}`],
architecture: 'arm64',
version: '18.4',
versionNumber: 180004,
},
replication: {
mode: 'physical-streaming',
synchronousCommit: 'remote_apply',
synchronousStandbyBeforePartition: {
state: 'streaming',
syncState: 'sync',
},
initialPrimaryTimeline: 1,
promotedPrimaryTimeline: 2,
oldPrimaryFenced: true,
promotedWritable: true,
},
controlReplicas: {
beforePromotion: [{}, {}],
afterPromotion: [{}, {}],
oldAvailabilityAfterFailure: [
{ availability: 'unavailable' },
{ availability: 'unavailable' },
],
oldActivationsRecoveredInPlace: false,
freshActivationsReady: 2,
},
durability: { unexpectedDomainSideEffects: 0 },
transactionWindows: {
ambiguousCommit: {
transparentReplayAllowed: false,
durableRowsAfterPromotion: 1,
},
writeBeforeCommit: { durableRowsAfterPromotion: 0 },
},
networkPartition: {
promotionRejectedWhileOldPrimaryWritable: true,
commitClientObservedFailure: true,
acknowledgedWriteLost: false,
replicatedToPromotionCandidate: 0,
promotedPrimaryRows: 0,
unacknowledgedLocalCommitDiscarded: true,
},
oldPrimaryRejoin: {
method: 'pg_rewind --write-recovery-conf',
rewindExitStatus: 0,
inRecovery: true,
streaming: true,
synchronousState: 'sync',
rejoinedAsWritablePrimary: false,
},
timeline: [
'primary_ready',
'standby_streaming',
'synchronous_remote_apply_ready',
'replication_partition_and_promotion_guard_verified',
'old_primary_fenced_and_admission_withdrawn',
'standby_promoted_old_primary_rejoined_endpoint_switched',
'two_fresh_control_replicas_ready',
].map((state, atMs) => ({ state, atMs })),
gates,
limitations: [...EXPECTED_LIMITATIONS],
};
}
test('accepts complete PostgreSQL HA evidence', () => {
assert.deepEqual(auditPostgresHaEvidence(fixture()), {
compatible: true,
findings: [],
});
});
test('rejects false gates, promotion drift and hidden private material', () => {
const report = fixture();
report.gates.oldPrimaryFencedBeforePromotion = false;
report.replication.promotedPrimaryTimeline = 1;
report.privateValue = 'postgresql://private-credential';
const result = auditPostgresHaEvidence(report);
assert.equal(result.compatible, false);
assert.ok(result.findings.includes('GATE_FAILED'));
assert.ok(result.findings.includes('PROMOTION_TIMELINE_INVALID'));
assert.ok(result.findings.includes('PRIVATE_MATERIAL_PRESENT'));
});
test('rejects reordered timeline and limitations drift', () => {
const report = fixture();
report.timeline.reverse();
report.limitations.pop();
const result = auditPostgresHaEvidence(report);
assert.equal(result.compatible, false);
assert.ok(result.findings.includes('LIMITATIONS_DRIFTED'));
assert.ok(result.findings.some((finding) => finding.startsWith('TIMELINE_')));
});