49 lines
2.4 KiB
Python
49 lines
2.4 KiB
Python
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
import subprocess
|
||
|
|
import sys
|
||
|
|
import tempfile
|
||
|
|
import unittest
|
||
|
|
from unittest.mock import patch
|
||
|
|
from console.catalog import upload
|
||
|
|
from console.settings import Settings
|
||
|
|
from console.store import Store
|
||
|
|
|
||
|
|
|
||
|
|
@unittest.skipUnless(sys.platform == "linux", "worker dispatcher runs on Linux")
|
||
|
|
class WorkerFinalizationTests(unittest.TestCase):
|
||
|
|
def test_unmount_failure_changes_both_record_and_archived_summary(self):
|
||
|
|
from console.worker import Worker
|
||
|
|
with tempfile.TemporaryDirectory() as temp:
|
||
|
|
settings = Settings(Path(temp), [])
|
||
|
|
store = Store(settings)
|
||
|
|
script = upload(store, b"print('test')\n", "test.py")
|
||
|
|
run = store.queue(script, "test-request", "127.0.0.1")
|
||
|
|
store.claim()
|
||
|
|
worker = Worker(settings, {})
|
||
|
|
directory = settings.runs / run["id"]
|
||
|
|
real_popen = subprocess.Popen
|
||
|
|
def command(value, target):
|
||
|
|
(target / "work").mkdir()
|
||
|
|
(target / "work/result.txt").write_text("test output")
|
||
|
|
return ["create"], {}
|
||
|
|
def fake_docker(*args, **kwargs):
|
||
|
|
if args[0] == "inspect":
|
||
|
|
return json.dumps([{"Config": {"Labels": {"xas.console": "dedicated"}},
|
||
|
|
"State": {"ExitCode": 0, "Running": False}}])
|
||
|
|
return "owned-test-container"
|
||
|
|
def process(*args, **kwargs):
|
||
|
|
return real_popen([sys.executable, "-c", "import sys;sys.stdin.readline();print('output')"], **kwargs)
|
||
|
|
with patch.object(worker, "command", command), patch("console.worker.docker", fake_docker), \
|
||
|
|
patch("console.worker.subprocess.Popen", process), \
|
||
|
|
patch("console.worker.workspace.mounts", return_value=[directory / "work"]), \
|
||
|
|
patch("console.worker.workspace.remove", side_effect=OSError("simulated unmount failure")):
|
||
|
|
worker.execute(run)
|
||
|
|
result = store.run(run["id"])
|
||
|
|
self.assertEqual(result["state"], "interrupted")
|
||
|
|
summary = next(a for a in result["artifacts"] if a["name"] == "summary.json")
|
||
|
|
archived = json.loads((directory / "artifacts" / summary["id"]).read_text())
|
||
|
|
self.assertEqual(archived["state"], result["state"])
|
||
|
|
self.assertEqual(archived["message"], result["message"])
|
||
|
|
self.assertTrue(worker.stopping)
|