Skip to content

test(runtime,dogfood): 批次 0 —— 两个真依赖测试后端迁到 sqlite :memory: - #5715

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-5704-batch0-real-dep-migration
Aug 6, 2026
Merged

test(runtime,dogfood): 批次 0 —— 两个真依赖测试后端迁到 sqlite :memory:#5715
os-zhuang merged 1 commit into
mainfrom
claude/issue-5704-batch0-real-dep-migration

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Part of #5704 (Batch 0)

(不是 Fixes —— 该程序跨批次持续开放,收口在 41 文件清零之后。)

前提复核(先做的事)

Survey(#5704 的 Phase 1 交付评论,基线 a58c0b5)距派发约 1 小时,先在 origin/main (eb26126) 上逐条核对,全部仍然成立:

  • read-coercion-conformance.test.tsDRIVERS 数组确实已经有一条绿的 SqlDriver :memory: 臂,driver-memory 是第二条。
  • datasource-autoconnect.test.ts 确实有 3 处真 import('@objectstack/driver-memory') + new InMemoryDriver(...)(boot()、credentials 用例、bootBound())。
  • ADR-0062 D1 …(#4083) describe 块原样存在。
  • 依赖面也确认无需改动:@objectstack/runtime@objectstack/dogfood 都已声明 @objectstack/driver-sql,better-sqlite3 由 driver-sql 的 optionalDependency 提供。零 package.json 改动。

改了什么

1. packages/qa/dogfood/test/read-coercion-conformance.test.ts

删掉 driver-memory 条目与 import,SQL 臂原样保留。文件抬头的覆盖声明同步改写 —— 原文写的是「against the framework's own SQL + memory drivers」,留着就不真了。

顺带把「为什么不亏」写进注释:SQLite 才是真把 boolean 存成整数的那个驱动,读回强制转换这条不变式本来就由它承载;一个从来不需要转换的 mingo store 只可能恒绿。

2. packages/runtime/src/datasource-autoconnect.test.ts

主体:3 处默认驱动统一走新的 makeDefaultDriver(),构造仓库的规范形态(与 examples/app-crmcli db clean 同款):

new SqlDriver({ client: 'better-sqlite3', connection: { filename: ':memory:' }, useNullAsDefault: true })

声明面的 datasource 也从 driver: 'memory' 改为 driver: 'sqlite' + config: { filename: ':memory:' } —— 否则联邦池仍然是 driver-memory,D1 块的改写就落空了。

schema 按真实 DDL 路径处理,而不是放松断言:schemaMode: 'external' 在驱动层禁止 DDL(ADR-0015,ObjectStack 是那个库的客人),所以 ext_note 物理表改为通过 raw execute() 建出来,正对应「真实远端库里这张表本来就在」。driver-memory 下不存在这一步 —— mingo store 首次写入即物化集合,未声明的表和已声明的表长得一模一样。把它显式化正是这次迁移买到的保真度,不是绕过。

3. ADR-0062 D1 …(#4083) 块 —— 按 PM 裁定 Q3-B 改写

未删除(删了就丢掉 D1 验收),未搬进 driver-memory 自己的 suite(工厂层 #4083 钉点已由 service-datasource 测试独立覆盖,搬过去是覆盖重复)。

memory-driver.json / driver.flush?.() / 2 秒 autosave 定时器这三样是 driver-memory 文件适配器的实现细节;D1 要的是运行时属性「联邦内存池不落盘、重启为空」。改写后:

  • :memory: 后端不在宿主留下任何文件(.objectstack/** 不存在) —— 两次 boot 各断言一次(原来只断言了第一次);
  • 新一轮 boot 的池里ext_note 表都不存在,而不只是没有行。这比原断言更直接:一个「重新加载了上一轮快照」的池不可能长这样。

反向验证 —— 方向与派发单预判一致(应当保持绿,红则说明配置误指文件)

改后该块保持绿。为了证明新断言不是空转,主动制造派发单点名的那个错误 —— 把 autoconn_extfilename':memory:' 改成 .objectstack/data/ext-note.sqlite(即 #4083 的形状在 SQL 后端上的复刻):

  1. 只改 filename → 在 expect(existsSync(STATE_DIR)).toBe(false) 处红(expected true to be false);
  2. 再临时注掉两处 existsSync 断言,让执行走到第二次 boot → 在 expect(await hasExtNoteTable(second)).toBe(false) 处红。

两条新断言各自独立见红,随后完整还原、复跑 11/11 绿。

验证(真实输出)

# packages/runtime
 Test Files  98 passed (98)
      Tests  1436 passed (1436)

# packages/qa/dogfood
 Test Files  85 passed | 1 skipped (86)
      Tests  513 passed | 3 skipped (516)

# 迁移文件本身
 Test Files  1 passed (1)
      Tests  11 passed (11)      # 与迁移前基线同数

# typecheck(两包)
packages/runtime typecheck: Done
packages/qa/dogfood typecheck: Done

# eslint(两个改动文件)exit 0,无输出

check-nul-bytes: OK (scanned 5614 tracked text file(s); ... no raw ASCII control bytes).
✓ query-options-erasure ratchet holds: 84 unswept non-test site(s) ... none new.
  test surface: 267 site(s) in 51 file(s) — at the ceiling      # 天花板未升
check-driver-conformance: OK — 25 covered cell(s), 0 in the DEBT ledger, 0 exempt.
check-engine-double-contract: OK — 27 pinned, 65 in the DEBT ledger, 1 exempt.

Changeset:测试行为改动,不面向用户,按派发约定用 skip-changeset该 label 我无权添加,请 PM 代打。

留给后续批次的两件事(本 PR 不做)

  1. packages/qa/dogfood@objectstack/driver-memory devDependency 现已无人使用(全包内仅剩本文件的散文提及)。清理属于 driver-memory 测试面替代:项目内测试后端迁到 sqlite :memory:(#5499 重启条件 · memory 半边,维护者 2026-08-06 立项) #5704 收口阶段的依赖声明面,不在本批次的两文件范围内,故未动 —— 也正是 survey 说的「grep driver-memory 系统性高估」那个度量陷阱的一个实例。
  2. packages/runtime 的 driver-memory 依赖必须保留:sandbox/undeclared-field-write-driver-split.integration.test.ts(Q2 待裁)与 standalone-stack.test.ts(已判域外)仍在真用。

范围外发现

已另开 #5714(未指派、未打标,交 PM 分诊):datasource 的 pool 声明在 sqlite / sqlite-wasm 驱动臂被静默丢弃(pg / mysql 生效),examples/app-crmCrmDatasource 是现网标本。核对连接池行为时发现,已用工厂真实构造实测确认;修法涉及公开契约形状(:memory: 下照着接反而会引入静默数据丢失),故只报事实不带方案。


Generated by Claude Code

…ds to sqlite `:memory:` (#5704 batch 0)

Batch 0 of the driver-memory test-surface replacement program (#5704, whose
memory-side restart condition is #5499). These are the only two files the Phase 1
survey classified as class A "真依赖" and that carry no pending ruling:

- `packages/qa/dogfood/test/read-coercion-conformance.test.ts` — drop the
  driver-memory arm from `DRIVERS`; the SqlDriver `:memory:` arm was already
  present and green. SQLite is the driver that actually stores booleans as
  integers, so it is the arm that carries the read-coercion invariant.
- `packages/runtime/src/datasource-autoconnect.test.ts` — the host default
  driver (3 sites) and the declared datasources move to
  `@objectstack/driver-sql` + better-sqlite3 `:memory:`, the repo's canonical
  ephemeral store (examples/app-crm, `cli db clean`).

The `ADR-0062 D1 … (#4083)` block is rewritten, not deleted and not relocated
(PM ruling Q3-B on #5704): its acceptance target is the runtime property "a
federated in-memory pool leaves nothing on the host and a restart starts empty",
not driver-memory's file adapter. `memory-driver.json`, `flush()` and the
autosave timer were adapter specifics; the replacement asserts that a fresh pool
holds no `ext_note` TABLE at all and that nothing lands under `.objectstack/`.

`schemaMode: 'external'` forbids DDL through the driver, so the federated table
is now created out-of-band via raw `execute()` — a mingo store materialised the
collection on first write, which is precisely the fidelity the migration buys.

No runtime source changes; test-behavior only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WyvqvKMG6asi9aXjKE6xtx
@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 6, 2026 1:51am

Request Review

@github-actions github-actions Bot added the size/m label Aug 6, 2026
@os-zhuang os-zhuang added tests skip-changeset PR has no user-facing published change; bypasses the changeset gate labels Aug 6, 2026 — with Claude
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

Copy link
Copy Markdown
Contributor Author

更正正文一处:skip-changeset label 已由仓库自动化自行打上(当前 labels:size/m / tests / skip-changeset),不需要 PM 代打。正文里那句「该 label 我无权添加,请 PM 代打」写于开单之前,以本条为准。

其余不变。


Generated by Claude Code

Copy link
Copy Markdown
Contributor Author

CI 红旗说明(无需修复,#5562/#5655 同款第三例):失败的 Check Changeset(01:51:24)来自 PR-opened 事件、载荷冻结于 skip-changeset 标签落上之前;标签事件触发的两次同名 run(01:51:44)均已 skipped 取代之。不重跑旧 run。其余 CI(Test Core / Dogfood / Temporal / typecheck / ESLint)在跑。


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 6, 2026 02:21
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 6, 2026
Merged via the queue into main with commit 3de5ec8 Aug 6, 2026
30 of 31 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-5704-batch0-real-dep-migration branch August 6, 2026 02:33
This was referenced Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants