Story 6
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||
|
||||
import processing_logger
|
||||
from data_export import DataExporter
|
||||
from result_updater import ResultUpdater
|
||||
from scratch_manager import ScratchManager
|
||||
|
||||
|
||||
class Story06ProcessingLoggerTests(unittest.TestCase):
|
||||
def test_insert_log_executes_correct_sql(self):
|
||||
cursor = MagicMock()
|
||||
processing_logger.insert_log(
|
||||
cursor,
|
||||
video_id=42,
|
||||
model_version="v1.0.0",
|
||||
frame_count=8,
|
||||
confidence_score=0.82,
|
||||
routing_decision="MATCH",
|
||||
frame_confidences=[0.80, 0.82, 0.85],
|
||||
)
|
||||
cursor.execute.assert_called_once()
|
||||
sql, params = cursor.execute.call_args[0]
|
||||
self.assertIn("INSERT INTO processing_logs", sql)
|
||||
self.assertEqual(params[0], 42) # video_id
|
||||
self.assertEqual(params[1], "v1.0.0") # model_version
|
||||
self.assertEqual(params[2], 8) # frame_count
|
||||
self.assertAlmostEqual(params[3], 0.82) # confidence_score
|
||||
scores = json.loads(params[4]) # confidence_scores JSON
|
||||
self.assertEqual(scores, [0.80, 0.82, 0.85])
|
||||
self.assertEqual(params[5], "MATCH") # routing_decision
|
||||
|
||||
def test_insert_log_null_frame_confidences(self):
|
||||
cursor = MagicMock()
|
||||
processing_logger.insert_log(cursor, 1, "v0", 0, None, "SKIP")
|
||||
_, params = cursor.execute.call_args[0]
|
||||
self.assertIsNone(params[4]) # confidence_scores column
|
||||
|
||||
|
||||
class Story06ResultUpdaterTests(unittest.TestCase):
|
||||
def _make_db(self, rowcount=1):
|
||||
cursor = MagicMock()
|
||||
cursor.rowcount = rowcount
|
||||
conn = MagicMock()
|
||||
conn.cursor.return_value = cursor
|
||||
db = MagicMock()
|
||||
db.transaction.return_value.__enter__ = MagicMock(return_value=conn)
|
||||
db.transaction.return_value.__exit__ = MagicMock(return_value=False)
|
||||
return db, cursor
|
||||
|
||||
def test_persist_returns_true_when_update_succeeds(self):
|
||||
db, cursor = self._make_db(rowcount=1)
|
||||
updater = ResultUpdater(db, model_version="v1.0.0")
|
||||
result = updater.persist(
|
||||
video_id=7, frame_count=5, confidence=0.9,
|
||||
routing="MATCH", frame_confidences=[0.9],
|
||||
)
|
||||
self.assertTrue(result)
|
||||
|
||||
def test_persist_returns_false_on_state_guard_miss(self):
|
||||
db, cursor = self._make_db(rowcount=0)
|
||||
updater = ResultUpdater(db, model_version="v1.0.0")
|
||||
result = updater.persist(
|
||||
video_id=7, frame_count=5, confidence=0.9,
|
||||
routing="MATCH", frame_confidences=[0.9],
|
||||
)
|
||||
self.assertFalse(result)
|
||||
|
||||
def test_persist_calls_insert_log_after_update(self):
|
||||
db, cursor = self._make_db(rowcount=1)
|
||||
updater = ResultUpdater(db, model_version="v1.0.0")
|
||||
updater.persist(video_id=7, frame_count=5, confidence=0.9,
|
||||
routing="MATCH", frame_confidences=[0.9])
|
||||
# cursor.execute called twice: UPDATE videos + INSERT processing_logs
|
||||
self.assertEqual(cursor.execute.call_count, 2)
|
||||
|
||||
|
||||
class Story06DataExporterTests(unittest.TestCase):
|
||||
def test_jsonl_flush_writes_valid_records(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
exporter = DataExporter(
|
||||
output_path=tmpdir, model_version="v1",
|
||||
export_format="jsonl", batch_size=100,
|
||||
)
|
||||
exporter.add({"video_id": 1, "routing": "MATCH", "video_confidence": 0.9,
|
||||
"confidence_scores": [0.9], "sample_count": 1,
|
||||
"file_path": "/a.mp4", "processed_at": "2026-01-01T00:00:00+00:00"})
|
||||
path = exporter.flush()
|
||||
|
||||
self.assertIsNotNone(path)
|
||||
lines = Path(path).read_text(encoding="utf-8").strip().split("\n")
|
||||
self.assertEqual(len(lines), 1)
|
||||
record = json.loads(lines[0])
|
||||
self.assertEqual(record["routing"], "MATCH")
|
||||
self.assertAlmostEqual(record["video_confidence"], 0.9)
|
||||
|
||||
def test_auto_flush_at_batch_size(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
exporter = DataExporter(
|
||||
output_path=tmpdir, model_version="v1",
|
||||
export_format="jsonl", batch_size=2,
|
||||
)
|
||||
exporter.add({"video_id": 1, "routing": "SKIP", "video_confidence": 0.1,
|
||||
"confidence_scores": [], "sample_count": 0,
|
||||
"file_path": "/a.mp4", "processed_at": ""})
|
||||
exporter.add({"video_id": 2, "routing": "MATCH", "video_confidence": 0.9,
|
||||
"confidence_scores": [0.9], "sample_count": 1,
|
||||
"file_path": "/b.mp4", "processed_at": ""})
|
||||
# batch_size=2 → auto-flush triggered on second add
|
||||
self.assertEqual(exporter._buffer, [])
|
||||
|
||||
def test_exclude_frame_confidences_when_disabled(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
exporter = DataExporter(
|
||||
output_path=tmpdir, model_version="v1",
|
||||
export_format="jsonl", batch_size=100,
|
||||
include_frame_confidences=False,
|
||||
)
|
||||
exporter.add({"video_id": 1, "routing": "SKIP", "video_confidence": 0.1,
|
||||
"confidence_scores": [0.1, 0.2], "sample_count": 2,
|
||||
"file_path": "/a.mp4", "processed_at": ""})
|
||||
path = exporter.flush()
|
||||
record = json.loads(Path(path).read_text())
|
||||
self.assertNotIn("confidence_scores", record)
|
||||
|
||||
|
||||
class Story06ScratchManagerCleanupAllTests(unittest.TestCase):
|
||||
def test_cleanup_all_removes_entire_video_directory(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
manager = ScratchManager(base_path=tmpdir, video_id="v42", auto_cleanup=True)
|
||||
frame_dir = manager.ensure_frame_dir()
|
||||
crops_dir = Path(tmpdir) / "v42" / "crops"
|
||||
crops_dir.mkdir(parents=True)
|
||||
(frame_dir / "frame.jpg").write_bytes(b"f")
|
||||
(crops_dir / "crop.jpg").write_bytes(b"c")
|
||||
|
||||
manager.cleanup_all()
|
||||
self.assertFalse((Path(tmpdir) / "v42").exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user