From 11d10c2239b6b0f8f5d061e5970ef59e554d3d57 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Oct 2026 09:09:38 +0000 Subject: [PATCH 1/3] test(plugin-pinyin-search): seed the boot-reconcile history in batched bulkCreate calls The fixture wrote its 2,500-row history with one awaited driver.create per row. Batched bulkCreate (500 rows, SQLite's compound-SELECT ceiling) cuts the seed to five statements. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix --- .../src/boot-reconcile.integration.test.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts index 79bac40971d..f646449da3c 100644 --- a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts +++ b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts @@ -37,6 +37,8 @@ const SYSTEM = { isSystem: true } as const; const HISTORIC = '2026-01-01T00:00:00.000Z'; const ROWS = 2_500; const PAGE = 1_000; +/** SQLite's compound-SELECT ceiling: the most rows one `bulkCreate` can carry. */ +const INSERT_BATCH = 500; const PROBE_OBJECT = { name: PROBE, @@ -98,9 +100,19 @@ class FixturePlugin implements Plugin { }; } - /** A write that bypasses every hook and the audit stamp: an import, a migration. */ + /** + * A write that bypasses every hook and the audit stamp: an import, a migration. + * Batched `bulkCreate`, not one awaited `create` per row (#25749): 2,500 + * single-row autocommit inserts timed these cases out under CI load. A batch + * is one `… UNION ALL SELECT …` statement on SQLite, which refuses more than + * 500 terms ("too many terms in compound SELECT"), hence the slices. The + * driver keeps the given `created_at`/`updated_at`, so the history stays older + * than any watermark. + */ async directInsert(rows: Array>): Promise { - for (const row of rows) await this.driver.create(PROBE, row); + for (let i = 0; i < rows.length; i += INSERT_BATCH) { + await this.driver.bulkCreate(PROBE, rows.slice(i, i + INSERT_BATCH)); + } } async row(id: string): Promise | null> { From 6e4642ec6ae0540a1d9bafffb8335936fcd5745d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Oct 2026 09:18:25 +0000 Subject: [PATCH 2/3] test(plugin-pinyin-search): give the boot-reconcile suite a 30 s budget With the seed batched, the remaining cost under load is the real-kernel boots and the 2,500-row reconcile walks the cases exist to measure. On a 4-core box with 20 busy loops they alone took 6.8 s and 9.9 s, past vitest's 5 s default. The budget sits on the one describe that boots the kernel; the package config stays on vitest's defaults. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix --- .../src/boot-reconcile.integration.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts index f646449da3c..53ef7e4b360 100644 --- a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts +++ b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts @@ -179,7 +179,12 @@ function history(): Array> { })); } -describe('#25634 the boot reconcile reads what changed since its last completed walk', () => { +// [#25749] Each case pays for real-kernel boots over a SQLite file (two in +// most) and at least one full 2,500-row reconcile walk; the forced-rebuild +// case walks twice. Idle, the slowest case takes about 1 s. On a 4-core box +// with 20 busy loops the boots and walks alone took 6.8 s and 9.9 s (seed +// excluded), past vitest's 5 s default, so the suite carries its own budget. +describe('#25634 the boot reconcile reads what changed since its last completed walk', { timeout: 30_000 }, () => { it('a first boot walks every row; an unchanged second boot reads none — and a receipt sits in sys_migration', async () => { const first = await boot({ before: (f) => f.directInsert(history()) }); await first.plugin.whenReconciled(); From d1f610e4d15750c8c8e8f50ac073e67975a23ba9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Oct 2026 09:32:42 +0000 Subject: [PATCH 3/3] test(plugin-pinyin-search): correct the measured walk time in the budget comment The forced-rebuild case measured 10,288 ms with a 222 ms seed, so the boots and walks alone took 10.1 s, not 9.9 s. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01T5digj2EfFsbXihqJEo1ix --- .../plugin-pinyin-search/src/boot-reconcile.integration.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts index 53ef7e4b360..d3a8d49529f 100644 --- a/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts +++ b/packages/plugins/plugin-pinyin-search/src/boot-reconcile.integration.test.ts @@ -182,7 +182,7 @@ function history(): Array> { // [#25749] Each case pays for real-kernel boots over a SQLite file (two in // most) and at least one full 2,500-row reconcile walk; the forced-rebuild // case walks twice. Idle, the slowest case takes about 1 s. On a 4-core box -// with 20 busy loops the boots and walks alone took 6.8 s and 9.9 s (seed +// with 20 busy loops the boots and walks alone took 6.8 s and 10.1 s (seed // excluded), past vitest's 5 s default, so the suite carries its own budget. describe('#25634 the boot reconcile reads what changed since its last completed walk', { timeout: 30_000 }, () => { it('a first boot walks every row; an unchanged second boot reads none — and a receipt sits in sys_migration', async () => {