mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-22 02:27:44 +08:00
feat(ql3): establish 3.0 incubation baseline
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { test } = require('node:test');
|
||||
|
||||
const {
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile,
|
||||
} = require('../dist/legacy-adoption/legacyCrontabDecisionIssuer');
|
||||
|
||||
const DECISION_ID = '019a2b3c-4d5e-7f60-8123-456789abcdef';
|
||||
const PLAN_DIGEST = 'a'.repeat(64);
|
||||
const INVENTORY_DIGEST = 'b'.repeat(64);
|
||||
const DECISION = Object.freeze({
|
||||
rowOrdinal: 1,
|
||||
sourceDigest: 'c'.repeat(64),
|
||||
disposition: 'adopt',
|
||||
reason: 'reviewed_lossless',
|
||||
});
|
||||
|
||||
function fixture(t) {
|
||||
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-review-file-'));
|
||||
fs.chmodSync(directory, 0o700);
|
||||
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
||||
const filePath = path.join(directory, 'review.ndjson');
|
||||
const records = [
|
||||
{
|
||||
schemaVersion: 1,
|
||||
kind: 'qinglong3-legacy-crontab-decision-review-file-header',
|
||||
decisionId: DECISION_ID,
|
||||
profile: 'edge',
|
||||
planDigest: PLAN_DIGEST,
|
||||
inventoryDigest: INVENTORY_DIGEST,
|
||||
},
|
||||
{
|
||||
schemaVersion: 1,
|
||||
kind: 'qinglong3-legacy-crontab-decision-review-file-row',
|
||||
decision: DECISION,
|
||||
},
|
||||
];
|
||||
fs.writeFileSync(
|
||||
filePath,
|
||||
`${records.map((record) => JSON.stringify(record)).join('\n')}\n`,
|
||||
{ mode: 0o600 },
|
||||
);
|
||||
return { directory, filePath };
|
||||
}
|
||||
|
||||
function options(filePath) {
|
||||
return {
|
||||
filePath,
|
||||
expectedDecisionId: DECISION_ID,
|
||||
expectedProfile: 'edge',
|
||||
expectedPlanDigest: PLAN_DIGEST,
|
||||
expectedInventoryDigest: INVENTORY_DIGEST,
|
||||
};
|
||||
}
|
||||
|
||||
test('streams repeatable decisions from one authenticated private descriptor', async (t) => {
|
||||
const value = fixture(t);
|
||||
const result = await withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
options(value.filePath),
|
||||
(scope) => {
|
||||
assert.equal(scope.evidence.decisionCount, 1);
|
||||
assert.match(scope.evidence.fileDigest, /^[0-9a-f]{64}$/);
|
||||
assert.deepEqual([...scope.decisions], [DECISION]);
|
||||
assert.deepEqual([...scope.decisions], [DECISION]);
|
||||
scope.confirmIdentity();
|
||||
return scope.evidence.fileDigest;
|
||||
},
|
||||
);
|
||||
assert.match(result, /^[0-9a-f]{64}$/);
|
||||
});
|
||||
|
||||
test('fails closed on private-path violations and in-flight replacement', async (t) => {
|
||||
const value = fixture(t);
|
||||
fs.chmodSync(value.filePath, 0o640);
|
||||
await assert.rejects(
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
options(value.filePath),
|
||||
() => undefined,
|
||||
),
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
);
|
||||
fs.chmodSync(value.filePath, 0o600);
|
||||
|
||||
const linkPath = path.join(value.directory, 'review-link.ndjson');
|
||||
fs.symlinkSync(value.filePath, linkPath);
|
||||
await assert.rejects(
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
options(linkPath),
|
||||
() => undefined,
|
||||
),
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
options(value.filePath),
|
||||
() => {
|
||||
const replacement = path.join(value.directory, 'replacement.ndjson');
|
||||
fs.copyFileSync(value.filePath, replacement);
|
||||
fs.chmodSync(replacement, 0o600);
|
||||
fs.renameSync(replacement, value.filePath);
|
||||
},
|
||||
),
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects widened records and mismatched review identity', async (t) => {
|
||||
const value = fixture(t);
|
||||
const widened = fs
|
||||
.readFileSync(value.filePath, 'utf8')
|
||||
.replace(
|
||||
'"reason":"reviewed_lossless"',
|
||||
'"reason":"reviewed_lossless","override":true',
|
||||
);
|
||||
fs.writeFileSync(value.filePath, widened, { mode: 0o600 });
|
||||
await assert.rejects(
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
options(value.filePath),
|
||||
() => undefined,
|
||||
),
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
);
|
||||
|
||||
const fresh = fixture(t);
|
||||
await assert.rejects(
|
||||
withPrivateLegacyCrontabAdoptionDecisionReviewFile(
|
||||
{ ...options(fresh.filePath), expectedInventoryDigest: 'd'.repeat(64) },
|
||||
() => undefined,
|
||||
),
|
||||
LegacyCrontabAdoptionDecisionReviewFileError,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user