mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 00:38:14 +08:00
125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const { DatabaseSync } = require('node:sqlite');
|
|
const { test } = require('node:test');
|
|
|
|
const {
|
|
ToolResultKeyCatalogConflictError,
|
|
ToolResultKeyCatalogUnavailableError,
|
|
createToolResultKeyCatalogBootstrapCommand,
|
|
createToolResultKeyRotationCommand,
|
|
toolResultKeyMaterialProof,
|
|
} = require('@qinglong/runtime-core/tool-result-key-catalog');
|
|
const {
|
|
LocalSqliteToolResultKeyCatalogRepository,
|
|
} = require('@qinglong/local-sqlite/tool-result-key-catalog');
|
|
const { migrateLocalSqliteDatabase } = require('../dist/migration/migration');
|
|
const { LocalSqliteOperationAuthority } = require('../dist/authority/operationAuthority');
|
|
|
|
async function harness() {
|
|
const client = new DatabaseSync(':memory:');
|
|
client.exec('PRAGMA foreign_keys = ON');
|
|
await migrateLocalSqliteDatabase(client);
|
|
const authority = new LocalSqliteOperationAuthority(client);
|
|
return {
|
|
client,
|
|
repository: new LocalSqliteToolResultKeyCatalogRepository(authority),
|
|
close: () => authority.close(),
|
|
};
|
|
}
|
|
|
|
function bootstrapCommand() {
|
|
return createToolResultKeyCatalogBootstrapCommand({
|
|
keyId: 'tool-result-key-001',
|
|
materialProof: toolResultKeyMaterialProof(
|
|
'tool-result-key-001',
|
|
Buffer.alloc(32, 1),
|
|
),
|
|
mutationId: 'tool-result-key-bootstrap-001',
|
|
});
|
|
}
|
|
|
|
test('appends, exactly replays and reads the latest SQLite key generation', async () => {
|
|
const current = await harness();
|
|
try {
|
|
assert.equal(await current.repository.findCurrent(), null);
|
|
const bootstrap = bootstrapCommand();
|
|
const first = await current.repository.append(bootstrap);
|
|
assert.equal(first.status, 'created');
|
|
assert.equal(first.catalog.generation, 1);
|
|
assert.deepEqual(await current.repository.append(bootstrap), {
|
|
status: 'existing',
|
|
catalog: first.catalog,
|
|
});
|
|
|
|
const rotation = createToolResultKeyRotationCommand(first.catalog, {
|
|
keyId: 'tool-result-key-002',
|
|
materialProof: toolResultKeyMaterialProof(
|
|
'tool-result-key-002',
|
|
Buffer.alloc(32, 2),
|
|
),
|
|
mutationId: 'tool-result-key-rotate-002',
|
|
});
|
|
const second = await current.repository.append(rotation);
|
|
assert.equal(second.status, 'created');
|
|
assert.equal(second.catalog.generation, 2);
|
|
assert.deepEqual(await current.repository.findCurrent(), second.catalog);
|
|
assert.equal(
|
|
current.client
|
|
.prepare(
|
|
`SELECT COUNT(*) AS count
|
|
FROM "ToolResultKeyCatalogGenerations"`,
|
|
)
|
|
.get().count,
|
|
2,
|
|
);
|
|
|
|
await assert.rejects(
|
|
current.repository.append(
|
|
createToolResultKeyRotationCommand(first.catalog, {
|
|
keyId: 'tool-result-key-stale',
|
|
materialProof: toolResultKeyMaterialProof(
|
|
'tool-result-key-stale',
|
|
Buffer.alloc(32, 3),
|
|
),
|
|
mutationId: 'tool-result-key-stale-003',
|
|
}),
|
|
),
|
|
ToolResultKeyCatalogConflictError,
|
|
);
|
|
} finally {
|
|
await current.close();
|
|
}
|
|
});
|
|
|
|
test('fails closed when the durable SQLite catalog projection drifts', async () => {
|
|
const current = await harness();
|
|
try {
|
|
await current.repository.append(bootstrapCommand());
|
|
current.client
|
|
.prepare(
|
|
`UPDATE "ToolResultKeyCatalogGenerations"
|
|
SET command_digest = ?
|
|
WHERE generation = 1`,
|
|
)
|
|
.run('c'.repeat(64));
|
|
await assert.rejects(
|
|
current.repository.findCurrent(),
|
|
ToolResultKeyCatalogUnavailableError,
|
|
);
|
|
} finally {
|
|
await current.close();
|
|
}
|
|
});
|
|
|
|
test('publishes SQLite catalog mutation only through its explicit subpath', () => {
|
|
const root = require('@qinglong/local-sqlite');
|
|
const runtime = require('@qinglong/local-sqlite/runtime');
|
|
const authority = require('@qinglong/local-sqlite/tool-result-key-catalog');
|
|
assert.equal(root.LocalSqliteToolResultKeyCatalogRepository, undefined);
|
|
assert.equal(runtime.LocalSqliteToolResultKeyCatalogRepository, undefined);
|
|
assert.equal(
|
|
typeof authority.LocalSqliteToolResultKeyCatalogRepository,
|
|
'function',
|
|
);
|
|
});
|