import os from pathlib import Path import sys import tempfile from datetime import datetime, timedelta, timezone import unittest ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT / 'app')) import worker_assignment_runner as runner from runtime_security import ensure_private_directory @unittest.skipUnless(sys.platform.startswith('linux'), 'requires Linux renameat2') class LinuxWorkerRunnerHandoffTests(unittest.TestCase): def create_root(self, temporary, generation): work = ensure_private_directory(os.path.join(temporary, 'work'), reject_reparse=True) started = datetime.now(timezone.utc) assignment = { 'reservation': {'reservation_id': 17}, 'deadlines': {}, 'compatibility': {}, 'scan_kwargs': {}, 'event_scan_options': {}, 'queue_policy': {}, 'limits': {}, 'scan_policy': {}, 'execution_snapshot': {}, 'execution_snapshot_sha256': 'a' * 64, 'execution_plan': {}, } value = runner.build_runner_input( assignment, generation=generation, slot_id=0, scan_started_at=started.isoformat(timespec='milliseconds').replace('+00:00', 'Z'), scan_deadline_at=(started + timedelta(seconds=60)).isoformat( timespec='milliseconds', ).replace('+00:00', 'Z'), ) name = runner.runner_root_name(0, 17, generation) paths, _digest = runner.create_runner_root(work, name, value) return work, name, paths def test_timeout_generation_moves_atomically_to_janitor_namespace(self): with tempfile.TemporaryDirectory() as temporary: work, name, paths = self.create_root(temporary, 'a' * 32) reference = runner.transfer_runner_to_janitor(work, name, 'a' * 32) self.assertEqual(reference, f'abandoned/{name}') self.assertFalse(os.path.exists(paths['root'])) self.assertTrue(os.path.isdir(os.path.join(work, *reference.split('/')))) def test_retry_handoff_is_idempotent_after_durable_move(self): with tempfile.TemporaryDirectory() as temporary: work, name, _paths = self.create_root(temporary, 'b' * 32) first = runner.transfer_runner_to_janitor(work, name, 'b' * 32) second = runner.transfer_runner_to_janitor(work, name, 'b' * 32) self.assertEqual(first, second) def test_existing_destination_never_replaces_another_generation_tree(self): with tempfile.TemporaryDirectory() as temporary: work, name, paths = self.create_root(temporary, 'c' * 32) abandoned = ensure_private_directory( os.path.join(work, 'abandoned'), reject_reparse=True, ) os.makedirs(os.path.join(abandoned, name)) with self.assertRaises(runner.RunnerProtocolError): runner.transfer_runner_to_janitor(work, name, 'c' * 32) self.assertTrue(os.path.isdir(paths['root'])) if __name__ == '__main__': unittest.main()