加密后的密文是 bytes。在内存存储里,它来回转换毫无问题,单元测试全绿。到了 Postgres,那一列是 JSON,而 bytes 不是 JSON 可序列化的类型。密钥存储就在这个边界上炸了——一个内存测试从未跨过的边界。
![]()
这是 HivePlane v0.2.0 现场测试里反复出现的模式。难的部分不是逻辑,是数据模型和边界。每一个缺陷,都是一个在 Python 里好好的值,下一步就崩了,崩在某个持久化接缝上。
把每个值沿着它经过的每一道持久化边界追踪一遍,因为 bug 就住在你的单元测试再往前一步的地方。
一个接缝类型,一个缺陷
D-5 是最干净的例子。加密密钥库把密文存成 bytes,内存存储里来回转换完美,单元测试通过。Postgres 里那一列是 JSON,bytes 不可 JSON 序列化。密钥存储炸在持久化边界上——内存测试唯一没走到的地方。
修复不在模型里,在边界上:去 Postgres 的路上把密文 base64 编码,回来再解码。模型保持 bytes,接缝学会翻译。用内存存储的那个单元测试依然通过——也依然证明不了接缝的任何事。
内存存储和 Postgres 存储共享的是接口,不是序列化。一个在内存里能来回转换的值,可能在 JSON 列上失败。把值追踪过内存测试从不跨越的那道边界。
第二个来源撞碎了第一个
D-7 是 id 与唯一性的混淆。reconcile 加载器用 id 作为 desired_specs 的键。单个来源没问题。第二个来源应用同样的期望状态时,撞上了主键冲突——因为那一行已经存在,而这个键假设只有一个来源。唯一性约束和 id 是同一个字段,却表达着不同的含义。
修复是复合键加幂等 upsert:(source_id, workload_id)。第二个来源是第二行,不是一次碰撞。这个 bug 只在你有两个来源时出现,所以单来源的现场测试从没抓到它。
D-8 是状态与记录的混淆,现在想起来还是好笑。GET /tools/disabled 返回的列表里包含了已启用的工具。kill-switch 记录存在于表里,但工具实际上并没有被禁用。端点报告的是记录,不是状态。一份"已禁用工具"列表里混着已启用的工具,比没有列表更糟——它训练操作员忽略这份列表。
修复:端点报告状态,由记录和当前工具状态共同推导,而不是只看记录。一条后来被撤销的禁用记录是历史,不是当前事实。
D-9 是数据库在教我 API 设计。删除一个带有 runs 的 workload 返回了 500——一个原始的外键约束违规,以内部错误的形式浮出水面。调用方拿到服务器错误,操作员拿不到任何原因。修复是返回 409,并说明"workload 有 N 个 runs;先删除 runs 或级联删除"。约束违规是面向用户的情况,不是服务器故障。数据库和 API 之间的接缝,就是 500 变成 409 的地方。
573 是那个本可能造成灾难性后果的问题。一份备份清单把 alembic_head 钉在 0034,而实际 schema head 是 0035。恢复会成功——清单说 schema 匹配——恢复到一个比清单超前一个迁移的数据库上。恢复验证的是清单的声明,不是世界的真相。
修复:恢复时用实际 schema head 对照清单验证,不匹配就拒绝。一份对自己 head 撒谎的清单,是一份把你恢复到系统错误版本的备份。
把每个值追踪过每一道持久化边界:二进制对 JSON、全局键对租户范围、id 对唯一性、状态对记录、外键对 409、清单 head 对 schema head。停在接缝处的单元测试会通过;bug 住在再往前一道边界的地方。带 Postgres 的测试——CI 里跑数据库的那些——才是能抓到它的测试。约束违规是用户情况,不是服务器故障:数据库和 API 之间的接缝,就是 500 变成带原因的 409 的地方。
v0.2.0 现场测试对真实技术栈、真实 PostgreSQL 零跳过运行——36/36 场景,67/67 容器测试——缺陷台账(D-1…D-11)就是证据:接缝,而不是逻辑,才是工作量所在。
挑一个你系统里的值,从模型追踪到 Postgres 列,再追踪到 API 响应。它在哪里改变了形状?那就是你下一个 bug 所在——也是你的单元测试停下的地方。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.