mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-21 00:38:14 +08:00
126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const os = require('node:os');
|
|
const path = require('node:path');
|
|
const { DatabaseSync } = require('node:sqlite');
|
|
const { test } = require('node:test');
|
|
|
|
const {
|
|
migrateLocalSqlitePath,
|
|
openLocalSqliteRuntimeDatabase,
|
|
} = require('../dist');
|
|
const {
|
|
openLocalSqliteMcpReadDatabase,
|
|
} = require('@qinglong/local-sqlite/mcp-read-database');
|
|
const {
|
|
LocalSqliteTaskRunOutcomeWindowReader,
|
|
} = require('@qinglong/local-sqlite/task-run-outcome-window');
|
|
|
|
function run(id, projectId, taskId, status, createdAtMs) {
|
|
return {
|
|
id,
|
|
projectId,
|
|
taskId,
|
|
taskRevision: 'revision-1',
|
|
taskName: id,
|
|
triggerType: 'manual',
|
|
executionOrigin: 'manual',
|
|
executionOwner: 'runtime',
|
|
triggeredBy: 'test',
|
|
status,
|
|
version: 0,
|
|
eventSequence: 0,
|
|
priority: 0,
|
|
createdAtMs,
|
|
};
|
|
}
|
|
|
|
test('reads one fixed Project Task outcome window through the existing indexed SQLite authority', async (t) => {
|
|
assert.equal(typeof LocalSqliteTaskRunOutcomeWindowReader, 'function');
|
|
assert.equal(
|
|
require('@qinglong/local-sqlite').LocalSqliteTaskRunOutcomeWindowReader,
|
|
undefined,
|
|
);
|
|
const directory = fs.mkdtempSync(
|
|
path.join(os.tmpdir(), 'ql3-outcome-window-'),
|
|
);
|
|
t.after(() => fs.rmSync(directory, { recursive: true, force: true }));
|
|
const options = {
|
|
databasePath: path.join(directory, 'qinglong3.sqlite'),
|
|
profile: 'edge',
|
|
};
|
|
await migrateLocalSqlitePath(options);
|
|
const runtime = await openLocalSqliteRuntimeDatabase(options);
|
|
await runtime.runRepository.transaction(async (transaction) => {
|
|
for (const value of [
|
|
run('run-old-success', 'default', 'task-a', 'succeeded', 10),
|
|
run('run-failure', 'default', 'task-a', 'failed', 20),
|
|
run('run-running', 'default', 'task-a', 'running', 30),
|
|
run('run-other-task', 'default', 'task-b', 'failed', 40),
|
|
run('run-other-project', 'other', 'task-a', 'failed', 50),
|
|
]) {
|
|
await transaction.insertRun(value);
|
|
}
|
|
});
|
|
await runtime.close();
|
|
|
|
const database = await openLocalSqliteMcpReadDatabase(options);
|
|
t.after(() => database.close());
|
|
const rows = await database.runs.listRecentRunsByTask({
|
|
projectId: 'default',
|
|
taskId: 'task-a',
|
|
limit: 3,
|
|
});
|
|
assert.deepEqual(rows, [
|
|
{
|
|
id: 'run-running',
|
|
projectId: 'default',
|
|
taskId: 'task-a',
|
|
status: 'running',
|
|
createdAtMs: 30,
|
|
},
|
|
{
|
|
id: 'run-failure',
|
|
projectId: 'default',
|
|
taskId: 'task-a',
|
|
status: 'failed',
|
|
createdAtMs: 20,
|
|
},
|
|
{
|
|
id: 'run-old-success',
|
|
projectId: 'default',
|
|
taskId: 'task-a',
|
|
status: 'succeeded',
|
|
createdAtMs: 10,
|
|
},
|
|
]);
|
|
await assert.rejects(
|
|
database.runs.listRecentRunsByTask({
|
|
projectId: 'default',
|
|
taskId: 'task-a',
|
|
limit: 66,
|
|
}),
|
|
TypeError,
|
|
);
|
|
|
|
await database.close();
|
|
const client = new DatabaseSync(options.databasePath, { readOnly: true });
|
|
t.after(() => {
|
|
if (client.isOpen) client.close();
|
|
});
|
|
const plan = client
|
|
.prepare(
|
|
`EXPLAIN QUERY PLAN
|
|
SELECT "id", "project_id", "task_id", "status", "created_at_ms"
|
|
FROM "Runs"
|
|
WHERE "project_id" = ? AND "task_id" = ?
|
|
ORDER BY "created_at_ms" DESC, "id" DESC
|
|
LIMIT ?`,
|
|
)
|
|
.all('default', 'task-a', 65);
|
|
assert.match(
|
|
plan.map((entry) => entry.detail).join('\n'),
|
|
/ql3_local_runs_task_created_idx/u,
|
|
);
|
|
});
|