56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Synthetic regression tests for epg_retention.delete_batches()."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
from epg_retention import delete_batches
|
|
|
|
|
|
NOW = 1_800_000_000
|
|
CUTOFF = NOW - 7 * 86_400
|
|
|
|
|
|
def rows(db: sqlite3.Connection) -> list[tuple[int, int]]:
|
|
return db.execute("SELECT _id,endtime FROM scheduletable ORDER BY _id").fetchall()
|
|
|
|
|
|
def run_case(values: list[int], expected: list[int], batch: int = 100) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = Path(tmp) / "test.db"
|
|
db = sqlite3.connect(path, isolation_level=None)
|
|
db.execute("PRAGMA auto_vacuum=FULL")
|
|
db.execute("CREATE TABLE scheduletable(_id INTEGER PRIMARY KEY, endtime INTEGER)")
|
|
db.execute("CREATE INDEX indexschedendtime ON scheduletable(endtime)")
|
|
db.executemany("INSERT INTO scheduletable(endtime) VALUES(?)", [(v,) for v in values])
|
|
first = delete_batches(db, CUTOFF, batch)
|
|
remaining = [v for _, v in rows(db)]
|
|
assert remaining == expected, (remaining, expected)
|
|
assert db.execute("PRAGMA integrity_check").fetchone()[0] == "ok"
|
|
second = delete_batches(db, CUTOFF, batch)
|
|
assert second["deleted"] == 0, second
|
|
assert first["deleted"] == len(values) - len(expected), first
|
|
db.close()
|
|
|
|
|
|
def main() -> None:
|
|
# empty; exact cutoff retained; just-before deleted; recent/future retained
|
|
run_case([], [])
|
|
run_case(
|
|
[NOW - 400 * 86_400, NOW - 30 * 86_400, CUTOFF - 1, CUTOFF, NOW - 1, NOW, NOW + 7 * 86_400],
|
|
[CUTOFF, NOW - 1, NOW, NOW + 7 * 86_400],
|
|
)
|
|
# Multiple transactions and stable ordering across duplicate end times.
|
|
old = [NOW - 365 * 86_400] * 251
|
|
current = [NOW - day * 86_400 for day in range(7)]
|
|
future = [NOW + day * 86_400 for day in range(1, 31)]
|
|
run_case(old + current + future, current + future, batch=100)
|
|
print("PASS: empty, boundary, current/future preservation, multi-batch and idempotence")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|