Skip to content

test(#60): 共享 test-factory(sqlite 真迁移替身)替换 core-api/module-sdk/hello 全部假 D1 - #62

Merged
HandyWote merged 3 commits into
m0/devfrom
fix/task-b
Sep 8, 2026
Merged

test(#60): 共享 test-factory(sqlite 真迁移替身)替换 core-api/module-sdk/hello 全部假 D1#62
HandyWote merged 3 commits into
m0/devfrom
fix/task-b

Conversation

@HandyWote

Copy link
Copy Markdown
Contributor

背景

issue #60 P1 主体:把「假 D1 无 schema 概念」这一测试两张皮(审核报告 §2.1 T1/T8)一次性消灭。

手搓假 D1 用 sql.includes('FROM module_registry') 命中即返回手造行run() 对未识别 SQL 一律 {success:true}、从不加载真实 migrations——所以 #56 的幻影列 registered_at 能在「单测全绿」下把线上打到 500;storage.testMemoryStatement 恒用 params[0] 当 moduleId 过滤,SDK SQL 漏 WHERE module_id = ? 时替身替被测代码「背锅」过滤,测试绿而真机跨模块数据泄漏。

本 PR 用 Node 内置 node:sqlite(Node≥22,零新依赖)加载真实 migrations 真建表 + 最小 D1 适配器替换全部假 D1,测试改走 app.request 路由级集成。

改动

文件 改动
services/core-api/test/test-factory.ts(新) createCoreDb()node:sqlite 内存库 + 顺序执行 migrations/core/*.sql(0001/0002/0003)真建表;~90 行 D1 适配器对齐真 D1(all(){results,success,meta}run()meta.changes/last_row_idfirst() 无行 null 且支持 first('col')、行转普通对象、datetime('now') 文本语义)
services/core-api/test/node-builtins.d.ts(新) node:sqlite/node:fs/node:url 最小类型声明(core-api 是 Workers 目标,不引 @types/node,避免污染全局类型)
services/core-api/test/registry.test.ts 删手搓 makeDb;种子/断言走真 SQL;补 2 条守护用例
services/core-api/test/setup.test.ts 删可记账内存 stub;激活链路真写 instance_config/setup_tokens/users/audit_log;补 3 条守护用例
services/core-api/test/token.test.ts makeDb;门禁查真 module_registry;修 G1「已停用模块启停后可再取」为同一真库 0→1 翻转;补守护用例
services/core-api/test/auth-routes.test.ts no-op CORE_DB 换真库;callback JIT 建档真 INSERT users,同 issuer+sub 二次 callback 断言复用同一行(UNIQUE 真生效);补守护用例
packages/module-sdk/test/test-factory.ts(新) 独立小工厂(与 core-api 版互不 import,避免包间耦合):加载 modules/hello/migrations/hello/0001_module_kv.sql 真建 module_kv
packages/module-sdk/test/storage.test.ts MemoryStatement/MemoryDatabase/likeToSource(-193 行);LIKE/ESCAPE 由真 SQLite 裁决;补 T8 守护用例
modules/hello/test/hello.test.ts 假 D1 换真 module_kv(复用 module-sdk 工厂,hello 本就依赖该包)

零新增运行时依赖;未改任何 src/**(真库未暴露源码 SQL/schema 冲突);未碰 deploy/**docs/**

守护用例(「查询列↔建表列」错位即红,已实证)

  • registry/setup/token/auth-routescolumns(table) 与迁移建表列逐一相等 + SELECT * 行键集 == columns() + 真约束守护(users UNIQUE(issuer,sub)manifest_json NOT NULLsetup_tokens PK)。
  • storage(T8 核心):直插 ('mod-a','k','a'),('mod-b','k','b')moduleId='mod-a'list() 必须只回 ['k']get('k') 必须为 'a'——SQL 漏 WHERE module_id 即红。
  • 实证(临时改 src 后还原,未留痕):
    • listModules SELECT 注入幻影列 registered_atregistry.test 3 用例红(no such column: registered_at);
    • storage.ts 去掉 listSqlWHERE module_id = ?storage.test 2 用例红(含 T8 守护用例)。

验收对照(issue #60

标准 本 PR 状态
fake factory 统一供给;D1 替身 = sqlite 加载真实 migrations ✅ core-api 四套 → 1 个 createCoreDb();module-sdk/hello 各自独立小工厂;全部加载真迁移
集成为主:测试走真实入口(app.fetch 路由级) ✅ 全部 D1 相关用例经 app.request 走 Hono 路由 + 真实 SQL
真实业务行为 + 边界行为 ✅ 审计(真 audit_log)、一次性 token 消费/重放、JIT 建档复用、启停同库翻转、LIKE/ESCAPE 字面化、UNIQUE/PK/NOT NULL 失败态
测试 = 可执行的预期描述(禁恒真/自证) ✅ 本 PR 触及用例清零子串包含/自证;修 G1 一处(token 同库翻转)
「查询列↔建表列」错位类 bug 在 CI 即红 ✅ 每处守护用例 + 实证
pnpm -r typecheck && pnpm -r test && pnpm -r build 全绿 ✅ 见下

范围说明:审核 §2.1 其余项(T2 manifest list 解析、T3 已由 #59 落地、T4/T5 r2/wrangler fake、T6 x-request-id、T7 verifyModuleToken、T9 sanitizeNext)与 G1 其余空洞断言属 #60 的其它 P1/P2 项,不在本 PR 范围。

验证(rebase 到 origin/m0/dev 后重跑)

pnpm -r typecheck   # 7/7 Done
pnpm -r test        # 8 packages 全绿:contracts 23 / ui 2 / module-sdk 35 / shell 39 / deploy 37 / core-api 64 / hello 10
pnpm -r build       # 8/8 Done(含 apps/shell vite build)

真实发现(不修,留档)

  1. setup_tokens.tokenNOT NULLmigrations/core/0002_setup_oauth.sql):token TEXT PRIMARY KEY 未声明 NOT NULL,SQLite 历史行为允许 TEXT 主键存 NULL。当前源码不会写 NULL,故非现网故障;但真 schema 约束弱于意图,建议后续迁移补 NOT NULL(改既有迁移有风险,未在本 PR 动)。
  2. setup_tokens.used_by 列存在但 consumeSetupToken 从不写入——死列(非冲突)。

Ref #60

审核 T1:core-api 四套假 D1 无 schema 概念,SQL 子串匹配命中即回手造行,
放过 #56 幻影列类错误。新建 test-factory 用 Node 内置 node:sqlite(零新依赖)
加载 migrations/core/*.sql 真建表,D1 适配器对齐真 D1 形状
(all() 回 results 数组、run() 回 meta.changes/last_row_id、datetime 文本语义、
first() 无行 null、行对象普通原型)。

registry.test.ts 首先换真库并立守护范式:
- 种子用户/模块走真 SQL,断言直查真表
- 守护:module_registry 行结构 == 建表列(幻影列/漏列即红)
- 守护:真 schema 约束(users UNIQUE(issuer,sub)、manifest_json NOT NULL)

Ref #60

Signed-off-by: HandyWote <huangyinghui01@corp.netease.com>
- setup.test:删可记账内存 stub,激活链路走真 instance_config/setup_tokens/
  users/audit_log;断言 used_at 为 SQLite datetime 文本(非 ISO)
- token.test:删 makeDb 子串匹配 stub;门禁查真 module_registry;
  修审核 G1『已停用模块在启停后可再取』——改为同一真库 enabled 0→1 翻转
- auth-routes.test:no-op CORE_DB 换真库,callback JIT 建档真 INSERT users 表,
  同 issuer+sub 二次 callback 断言复用同一行(UNIQUE 真生效)
- 每处补『查询列↔建表列』守护用例(错位即红,已实证注入幻影列必失败)

Ref #60

Signed-off-by: HandyWote <huangyinghui01@corp.netease.com>
审核 T8:storage.test 的 MemoryStatement 恒用 params[0] 当 moduleId 过滤,
SDK SQL 漏 WHERE module_id = ? 时假替身仍替被测代码『背锅』过滤 → 测试绿、
真机跨模块数据泄漏。改为真 SQLite 加载 modules 统一迁移
modules/hello/migrations/hello/0001_module_kv.sql 真建表。

- packages/module-sdk/test/test-factory.ts:独立小工厂(与 core-api 版互不 import)
- storage.test:删 MemoryStatement/MemoryDatabase/likeToSource,LIKE/ESCAPE 由
  真 SQLite 裁决;新增 T8 守护(同 key 两模块直插后 list/get 只回本模块,
  漏 WHERE 即红——已实证注入必失败)+ PK 真约束 + 列结构守护
- hello.test:假 D1 换真 module_kv,计数落库断言直查真表

Ref #60

Signed-off-by: HandyWote <huangyinghui01@corp.netease.com>
@HandyWote
HandyWote merged commit 06ce90e into m0/dev Sep 8, 2026
1 check passed
@HandyWote
HandyWote deleted the fix/task-b branch September 8, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant