feat: add isolated utility export modes

This commit is contained in:
Media
2026-08-12 18:48:03 -05:00
parent b934b69e5a
commit 7e6b916963
11 changed files with 1876 additions and 12 deletions
+72
View File
@@ -89,11 +89,26 @@ class FakeDownloadManager:
self.stopped = False
self.delete_requests = []
self.enqueue_calls = []
self.export_calls = []
self.export_reconciled = False
def enqueue(self, url, submitter, note):
self.enqueue_calls.append((url, submitter, note))
return self.store.reserve_download(url, submitter, note)
def enqueue_export(self, url, mode, submitter, note):
self.export_calls.append((url, mode, submitter, note))
return self.store.reserve_export_job(
url,
mode,
submitter,
note,
max_active=20,
)
def reconcile_export_artifacts(self):
self.export_reconciled = True
def recover_pending_deletions(self):
self.recovered = True
@@ -171,6 +186,7 @@ class ControllerServiceTests(unittest.TestCase):
)
self.service.start()
self.assertFalse(self.downloads.recovered)
self.assertTrue(self.downloads.export_reconciled)
return self.service
def ready_slot(self, slot=1):
@@ -497,6 +513,62 @@ class ControllerServiceTests(unittest.TestCase):
self.assertIn("mqtt_disconnected", health["degraded_reasons"])
self.assertIn("awaiting_player_evidence", health["degraded_reasons"])
def test_utility_export_is_slot_free_and_not_gated_by_player_evidence(self):
self.start_service()
self.assertIn(
"awaiting_player_evidence",
self.service.health()["degraded_reasons"],
)
result = self.service.enqueue_export(
"https://www.youtube.com/playlist?list=utility",
"mp4",
"Alice",
"ProPresenter",
)
self.assertEqual(result["kind"], "export")
self.assertEqual(result["status"], "queued")
self.assertEqual(result["mode"], "mp4")
self.assertIsNotNone(result["job_id"])
self.assertEqual(
self.downloads.export_calls,
[
(
"https://www.youtube.com/playlist?list=utility",
"mp4",
"Alice",
"ProPresenter",
)
],
)
self.assertTrue(
all(slot.media_state == "empty" for slot in self.store.list_slots())
)
self.assertEqual(self.mqtt.json_messages, [])
self.assertEqual(self.mqtt.legacy_messages, [])
jobs = self.service.list_export_jobs(limit=10)
self.assertEqual(len(jobs), 1)
self.assertEqual(jobs[0]["job_id"], result["job_id"])
self.assertEqual(jobs[0]["output_paths"], [])
def test_invalid_utility_mode_is_rejected_without_player_side_effects(self):
self.start_service()
with self.assertRaisesRegex(ValueError, "unsupported utility export mode"):
self.service.enqueue_export(
"https://www.youtube.com/watch?v=one",
"slot1",
None,
None,
)
self.assertTrue(
all(slot.media_state == "empty" for slot in self.store.list_slots())
)
self.assertEqual(self.mqtt.json_messages, [])
self.assertEqual(self.mqtt.legacy_messages, [])
def test_cleanup_waits_for_post_start_player_evidence_but_new_ingest_does_not(self):
self.start_service()
self.service._next_expiry = self.monotonic()