feat(ql3): establish 3.0 incubation baseline

This commit is contained in:
whyour
2026-08-12 00:25:26 +08:00
parent 4bf92dcfeb
commit c699c32461
2817 changed files with 779642 additions and 653 deletions
@@ -0,0 +1,106 @@
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 {
LocalOwnerPepperCatalogFullError,
LocalOwnerPepperGenerationConflictError,
LocalOwnerPepperMutationConflictError,
} = require('@qinglong/runtime-core/local-owner-pepper');
const {
openLocalSqliteBootstrapDatabase,
} = require('../dist/storage/bootstrap');
const { migrateLocalSqlitePath } = require('../dist/migration/migration');
function fixture(t) {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'ql3-pepper-catalog-'));
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
return path.join(directory, 'qinglong3.sqlite');
}
function registration(index, overrides = {}) {
return {
mutationId: `018f4f58-7d5a-4d82-8f7d-5da12f05c0${String(index).padStart(2, '0')}`,
pepperKeyId: `owner-key-${index}`,
materialDigest: index.toString(16).padStart(64, '0'),
backupDigest: (index + 16).toString(16).padStart(64, '0'),
registeredAtMs: 100 + index,
...overrides,
};
}
test('registers, activates and rotates with one append-only generation winner', async (t) => {
const databasePath = fixture(t);
const options = { databasePath, profile: 'edge' };
await migrateLocalSqlitePath(options);
const first = await openLocalSqliteBootstrapDatabase(options);
const second = await openLocalSqliteBootstrapDatabase(options);
t.after(() => Promise.all([first.close(), second.close()]));
const key1 = registration(1);
assert.equal((await first.ownerPepper.register(key1)).status, 'inserted');
assert.equal((await second.ownerPepper.register(key1)).status, 'existing');
const activation1 = {
mutationId: '018f4f58-7d5a-4d82-8f7d-5da12f05d001',
pepperKeyId: key1.pepperKeyId,
expectedGeneration: 0,
activatedAtMs: 200,
};
assert.equal(
(await first.ownerPepper.activate(activation1)).activation.generation,
1,
);
assert.equal(
(await second.ownerPepper.activate(activation1)).status,
'existing',
);
const key2 = registration(2);
const key3 = registration(3);
await first.ownerPepper.register(key2);
await first.ownerPepper.register(key3);
const contenders = [key2, key3].map((key, index) =>
[first, second][index].ownerPepper.activate({
mutationId: `018f4f58-7d5a-4d82-8f7d-5da12f05d00${index + 2}`,
pepperKeyId: key.pepperKeyId,
expectedGeneration: 1,
expectedActivePepperKeyId: key1.pepperKeyId,
activatedAtMs: 300 + index,
}),
);
const settled = await Promise.allSettled(contenders);
assert.equal(settled.filter(({ status }) => status === 'fulfilled').length, 1);
const rejection = settled.find(({ status }) => status === 'rejected');
assert.ok(rejection.reason instanceof LocalOwnerPepperGenerationConflictError);
const active = await first.ownerPepper.resolveActive();
assert.equal(active.generation, 2);
assert.equal((await first.ownerPepper.resolveKey(key1.pepperKeyId)).state, 'retired');
assert.equal(
(await first.ownerPepper.resolveKey(active.activePepperKeyId)).state,
'active',
);
});
test('rejects semantic mutation drift and caps the catalog at eight keys', async (t) => {
const databasePath = fixture(t);
const options = { databasePath, profile: 'standalone' };
await migrateLocalSqlitePath(options);
const database = await openLocalSqliteBootstrapDatabase(options);
t.after(() => database.close());
const first = registration(1);
await database.ownerPepper.register(first);
await assert.rejects(
database.ownerPepper.register({ ...first, backupDigest: 'f'.repeat(64) }),
LocalOwnerPepperMutationConflictError,
);
for (let index = 2; index <= 8; index += 1) {
await database.ownerPepper.register(registration(index));
}
await assert.rejects(
database.ownerPepper.register(registration(9)),
LocalOwnerPepperCatalogFullError,
);
});