task-loop-store-stress.test.mjs
131 lines 3.8 KB
Raw
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor ⚠ breaking 10 days ago
1 /**
2 * Tier 4 — STRESS: Large instance filter and list caps.
3 *
4 * @see docs/TASK-LOOP-STORE-CONTRACT-2G-c.md §6
5 */
6 import { describe, it, beforeEach, afterEach } from 'node:test';
7 import assert from 'node:assert/strict';
8 import fs from 'node:fs';
9 import path from 'node:path';
10 import { fileURLToPath } from 'node:url';
11 import { saveFlowStore } from '../lib/flow/flow-store.mjs';
12 import { listTaskLoops, MAX_TASK_LOOP_SUMMARIES } from '../lib/task/task-loop-store.mjs';
13 import { listTasks } from '../lib/task/task-store.mjs';
14
15 const __dirname = path.dirname(fileURLToPath(import.meta.url));
16 const tmpRoot = path.join(__dirname, 'fixtures', 'tmp-task-loop-stress');
17 const vaultId = 'vault-loop-stress';
18
19 describe('Task loop store — stress', () => {
20 beforeEach(() => {
21 fs.rmSync(tmpRoot, { recursive: true, force: true });
22 fs.mkdirSync(tmpRoot, { recursive: true });
23 });
24
25 afterEach(() => {
26 fs.rmSync(tmpRoot, { recursive: true, force: true });
27 });
28
29 it('listTaskLoops caps at MAX_TASK_LOOP_SUMMARIES with truncated flag', () => {
30 const dataDir = path.join(tmpRoot, 'data');
31 fs.mkdirSync(dataDir, { recursive: true });
32
33 const loops = [];
34 for (let i = 0; i < MAX_TASK_LOOP_SUMMARIES + 50; i += 1) {
35 loops.push({
36 schema: 'knowtation.task_loop/v0',
37 loop_id: `loop_stress_${String(i).padStart(4, '0')}`,
38 kind: 'personal',
39 scope: 'personal',
40 status: 'active',
41 title: `Stress loop ${i}`,
42 workspace_id: 'ws-personal',
43 recurrence: { kind: 'manual' },
44 timezone: 'UTC',
45 flow_id: null,
46 boundary_policy: 'observe_only',
47 memory_links: [],
48 created: '2026-06-01T00:00:00Z',
49 updated: '2026-06-01T00:00:00Z',
50 truncated: false,
51 });
52 }
53
54 saveFlowStore(dataDir, {
55 vaults: {
56 [vaultId]: {
57 flows: [],
58 steps: [],
59 runs: [],
60 candidates: [],
61 projections: [],
62 tasks: [],
63 task_loops: loops,
64 orchestrator_graphs: [],
65 },
66 },
67 });
68
69 const result = listTaskLoops(dataDir, vaultId, {
70 visibleScopes: new Set(['personal']),
71 filterScopes: new Set(['personal']),
72 effectiveScope: 'personal',
73 limit: MAX_TASK_LOOP_SUMMARIES,
74 });
75
76 assert.equal(result.loops.length, MAX_TASK_LOOP_SUMMARIES);
77 assert.equal(result.truncated, true);
78 });
79
80 it('listTasks filters 500 loop instances by loop_ref efficiently', () => {
81 const dataDir = path.join(tmpRoot, 'data-instances');
82 fs.mkdirSync(dataDir, { recursive: true });
83
84 const tasks = [];
85 for (let i = 0; i < 500; i += 1) {
86 tasks.push({
87 schema: 'knowtation.task/v0',
88 task_id: `task_loop_inst_${String(i).padStart(4, '0')}`,
89 kind: 'personal',
90 scope: 'personal',
91 status: 'pending',
92 title: `Instance ${i}`,
93 workspace_id: 'ws-personal',
94 due_at: null,
95 run_ref: null,
96 loop_ref: 'loop_school_trip',
97 occurrence_key: `2026-W${String(i % 52).padStart(2, '0')}`,
98 occurrence_at: null,
99 series_status_snapshot: 'active',
100 artifact_links: [],
101 created: '2026-06-01T00:00:00Z',
102 updated: '2026-06-01T00:00:00Z',
103 truncated: false,
104 });
105 }
106
107 saveFlowStore(dataDir, {
108 vaults: {
109 [vaultId]: {
110 flows: [],
111 steps: [],
112 runs: [],
113 candidates: [],
114 projections: [],
115 tasks,
116 task_loops: [],
117 orchestrator_graphs: [],
118 },
119 },
120 });
121
122 const result = listTasks(dataDir, vaultId, {
123 visibleScopes: new Set(['personal']),
124 filterScopes: new Set(['personal']),
125 effectiveScope: 'personal',
126 loopRef: 'loop_school_trip',
127 });
128
129 assert.equal(result.tasks.length, 500);
130 });
131 });
File History 1 commit
sha256:b5f647cb9c409f563d4671fe3fc05ddea01fabfed9b41fc11cb923588e1c1baf mirror: GitHub Phase A durable MCP OAuth (#270) Human minor 10 days ago