feat: add isolated utility export modes
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user