gap-3 test: assert resume-write behaviour, not the NOT NULL bit
ci / test (push) Successful in 55m32s

- test_column_notnull_probe_sees_gap3_outcome now branches on the
  post-ensure probe: when outcome is relaxed (PG; SQLite 3.53+)
  the resume write must land and read back NULL; on older SQLite
  the ALTER is swallowed and INSERT OR IGNORE drops the row
  (version-dependent boundary, not a migration failure).
- attempt_ledger.py comments updated: ALTER COLUMN DROP NOT NULL
  works on Postgres and SQLite 3.53.0+, swallowed before that.
- PG proof summary section 3.9/8 corrected to the same boundary.
This commit is contained in:
host committed 2026-11-06 05:24:20 +00:00
1 parent 2fcde375a4
commit 37ba6876bf
2 files changed
+36 -16

No files matched your search

@@ -150,14 +150,31 @@ class TestFreshAndMigrations(unittest.TestCase):
self.conn.execute(GAP3_DDL)
flags = _column_notnull(self.conn, "task_attempts")
self.assertTrue(flags["outcome"])
# SQLite 上放宽语句不合法、被 ensure 吞掉:迁移本身
# 不抛错、列集仍齐,但 outcome 保持 NOT NULL(需重建
# 表才能改,见批总结诚实边界;本批只修 PG 路径)。
# 迁移本身不抛错、列集仍齐;真正的不变量是 ensure
# 之后恢复写路与实际的 schema 状态一致,而不是
# outcome 的 NOT NULL 位:outcome 放宽了(PG 上
# ALTER 生效;SQLite 3.53.0 起也支持 ALTER COLUMN
# DROP NOT NULL),resume 风格写行必须能写入并读回
# outcome 为 NULL 的行;outcome 仍 NOT NULL 时(更
# 早的 SQLite:ALTER 不合法、被 try/except 吞掉),
# 该行会被 INSERT OR IGNORE 静默丢弃——版本相关
# 边界,不是迁移失败。
ensure_task_attempts_table(self.conn)
self.assertEqual(set(_columns(self.conn)),
set(UNIFIED_COLUMNS))
self.assertTrue(
_column_notnull(self.conn, "task_attempts")["outcome"])
relaxed = not _column_notnull(
self.conn, "task_attempts")["outcome"]
resume_record(self.conn, "t-gap", 2, "platform_fresh",
"worker_shutdown", -1, "second", None)
self.conn.commit()
row = _row_by_key(self.conn, "t-gap", 2)
if relaxed:
self.assertIsNotNone(row)
self.assertIsNone(row["outcome"])
latest = latest_attempt(self.conn, "t-gap")
self.assertEqual(latest["attempt_no"], 2)
else:
self.assertIsNone(row)
def test_old_shape_migrates_with_rows_intact(self):
self.conn.execute(OLD_DDL)