feat: initialize XAS test console with native execution
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
import tempfile
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from console.native_executor import inspect, NativeExecutor
|
||||
from console.native_io import SecretFilter
|
||||
from console.artifacts import Collector
|
||||
from console.settings import Settings
|
||||
from console.store import Store
|
||||
|
||||
|
||||
class LifecycleTests(unittest.TestCase):
|
||||
def test_many_old_outputs_do_not_hide_new_native_log(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
root=Path(temp);logs=root/'logs';run=root/'run'
|
||||
logs.mkdir();run.mkdir();(run/'work').mkdir()
|
||||
for number in range(300):(logs/f'{number:04}.log').write_text('old history')
|
||||
collector=Collector(Settings(root,[]),run,lambda:sorted(logs.iterdir()),file_limit=4096)
|
||||
(logs/'new.log').write_text('current progress')
|
||||
chunks=[];collector.finish_follow(chunks.append)
|
||||
self.assertIn(b'current progress',b''.join(chunks))
|
||||
self.assertNotIn(b'old history',b''.join(chunks))
|
||||
self.assertEqual([a['name'] for a in collector.collect()],['new.log'])
|
||||
|
||||
@unittest.skipIf(os.name == "nt", "Linux controlling terminal")
|
||||
def test_menu_has_controlling_terminal(self):
|
||||
import pty
|
||||
import subprocess
|
||||
import sys
|
||||
from console.native_job import acquire_terminal
|
||||
master, slave = pty.openpty()
|
||||
try:
|
||||
result = subprocess.run([sys.executable, "-c", "import os; t=os.open('/dev/tty',os.O_RDWR); os.close(t)"],
|
||||
stdin=slave, stdout=slave, stderr=slave, start_new_session=True, preexec_fn=acquire_terminal, timeout=5)
|
||||
self.assertEqual(result.returncode, 0)
|
||||
finally:
|
||||
os.close(master);os.close(slave)
|
||||
|
||||
def test_systemd_probe_error_is_not_missing_unit(self):
|
||||
result = SimpleNamespace(returncode=1, stdout="", stderr="D-Bus unavailable")
|
||||
with patch("console.native_executor.subprocess.run", return_value=result):
|
||||
with self.assertRaises(OSError):inspect("a" * 32)
|
||||
result.stdout = "LoadState=not-found\n"
|
||||
with patch("console.native_executor.subprocess.run", return_value=result):
|
||||
self.assertIsNone(inspect("a" * 32))
|
||||
|
||||
def test_file_log_secret_split_at_chunk_boundary_is_filtered(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
root = Path(temp)
|
||||
logs, run = root / "logs", root / "run"
|
||||
logs.mkdir();run.mkdir();(run / "work").mkdir()
|
||||
secret = "dummy-fixture-credential-123456"
|
||||
collector = Collector(Settings(root, []), run, [logs], stream_filter_factory=lambda: SecretFilter([secret]))
|
||||
(logs / "x.log").write_bytes(b"x" * 32760 + secret.encode() + b"\n")
|
||||
chunks=[];collector.finish_follow(chunks.append)
|
||||
result=b"".join(chunks)
|
||||
self.assertNotIn(secret.encode(),result)
|
||||
self.assertIn(b"[REDACTED]",result)
|
||||
|
||||
def test_terminal_state_waits_for_confirmed_cleanup(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
settings=Settings(Path(temp),[]);store=Store(settings)
|
||||
script={"id":"b"*32,"name":"fixture","version":1,"sha256":"x","config":{},"source_path":"fixture.py",
|
||||
"kind":"external","source_group":"fixture","language":"python"}
|
||||
run=store.queue(script,"fixture-request","127.0.0.1",execution={"mode":"native"})
|
||||
store.claim()
|
||||
directory=settings.runs/run['id'];directory.mkdir()
|
||||
(directory/'native-result.json').write_text(json.dumps({'exit_code':0,'artifacts':[]}))
|
||||
executor=NativeExecutor(SimpleNamespace(settings=settings,store=store,stopping=False))
|
||||
with patch.object(executor,'wait_stopped',return_value=False):
|
||||
executor.finish(run,{'Result':'success'})
|
||||
self.assertEqual(store.run(run['id'])['state'],'running')
|
||||
self.assertIsNone(store.claim())
|
||||
|
||||
def test_cancelled_before_dispatch_does_not_create_unit(self):
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
settings=Settings(Path(temp),[]);store=Store(settings)
|
||||
script={"id":"b"*32,"name":"fixture","version":1,"sha256":"x","config":{},"source_path":"fixture.py",
|
||||
"kind":"external","source_group":"fixture","language":"python"}
|
||||
run=store.queue(script,"fixture-request","127.0.0.1",execution={"mode":"native"})
|
||||
store.claim();store.cancel(run['id'])
|
||||
executor=NativeExecutor(SimpleNamespace(settings=settings,store=store,stopping=False))
|
||||
with patch('console.native_executor.subprocess.run') as launch:
|
||||
executor.execute(run)
|
||||
launch.assert_not_called()
|
||||
self.assertEqual(store.run(run['id'])['state'],'cancelled')
|
||||
Reference in New Issue
Block a user