Handle two-frame Ego4D bbox tails and preserve worker errors
This commit is contained in:
@@ -98,6 +98,47 @@ class MultiGPUExtractionTests(unittest.TestCase):
|
||||
self.assertEqual((self.root / "gpu2.log").read_text().strip(), "2 2")
|
||||
self.assertEqual((self.root / "gpu5.log").read_text().strip(), "5 2")
|
||||
|
||||
def test_failure_tail_keeps_traceback_and_long_diagnostics_but_progress_is_short(self):
|
||||
path = self.root / "worker.log"
|
||||
message = ("ValueError: Ego4D annotation frame exceeds source clip: " + self.names[0]
|
||||
+ "; source_frames=8998; " + "diagnostic " * 100 + "first_10=[8998, 8999]")
|
||||
traceback = "Traceback (most recent call last):\n File 'extract.py', line 200\n" + message
|
||||
path.write_text("old progress\n" * 10000 + traceback + "\n")
|
||||
self.assertEqual(launch.log_tail(path, failure=True), traceback)
|
||||
self.assertLessEqual(len(launch.log_tail(path)), 300)
|
||||
path.write_text(message + "\n")
|
||||
self.assertEqual(launch.log_tail(path, failure=True), message)
|
||||
self.assertEqual(launch.log_tail(self.root / "missing.log", failure=True), "starting")
|
||||
|
||||
def test_failure_diagnostics_survive_both_startup_and_polling_errors(self):
|
||||
message = f"clip={self.names[0]}; source_frames=8998; " + "detail " * 100 + "outliers=[8998, 8999]"
|
||||
for startup in (True, False):
|
||||
with self.subTest(startup=startup):
|
||||
folder = self.root / str(startup)
|
||||
folder.mkdir()
|
||||
# Simulate a flushed failing worker at startup or in the poll
|
||||
# loop without scheduler-dependent sleep/timing assertions.
|
||||
process = SimpleNamespace(returncode=1)
|
||||
process.poll = lambda: 1
|
||||
process.wait = lambda **kwargs: 1
|
||||
process.pid = None # Stub only; must never be passed to a real signal call.
|
||||
|
||||
def start(command, **kwargs):
|
||||
kwargs["stdout"].write(("Traceback (most recent call last):\nValueError: " + message + "\n").encode())
|
||||
kwargs["stdout"].flush()
|
||||
if not startup:
|
||||
polls = iter([None, 1, 1])
|
||||
process.poll = lambda: next(polls, 1)
|
||||
return process
|
||||
|
||||
args = SimpleNamespace(cpu_threads=1, startup_delay=0., status_interval=.01)
|
||||
plans = [{"gpu": 7, "samples": [self.names[0]], "command": ["unused"]}]
|
||||
with patch("extract_ego4d_local_multigpu.subprocess.Popen", side_effect=start), \
|
||||
contextlib.redirect_stdout(io.StringIO()), self.assertRaises(RuntimeError) as raised:
|
||||
launch.run_workers(plans, args, folder)
|
||||
self.assertIn(message, str(raised.exception))
|
||||
self.assertIn("Traceback (most recent call last):", str(raised.exception))
|
||||
|
||||
def test_failing_worker_stops_only_its_launched_peers(self):
|
||||
args = SimpleNamespace(cpu_threads=1, startup_delay=0., status_interval=.01)
|
||||
plans = [{"gpu": 0, "samples": ["dummy"], "command": [sys.executable, "-c", "import time; time.sleep(60)"]},
|
||||
|
||||
Reference in New Issue
Block a user