115 lines
5.4 KiB
Python
115 lines
5.4 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import json
|
|
import pathlib
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
|
|
ROOT = pathlib.Path(__file__).resolve().parents[2]
|
|
RUNNER = ROOT / "scripts" / "test-backend-isolated.sh"
|
|
|
|
|
|
class BackendIsolationRunnerTests(unittest.TestCase):
|
|
def test_c01_startup_adds_masks_without_replacing_wallet_and_bus_isolation(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
temp = pathlib.Path(temporary)
|
|
fake_bin = temp / 'bin'
|
|
fake_bin.mkdir()
|
|
executable = fake_bin / 'fixture-binary'
|
|
executable.write_text('#!/bin/sh\nexit 0\n')
|
|
executable.chmod(0o700)
|
|
cargo = fake_bin / 'cargo'
|
|
cargo.write_text(
|
|
'#!/usr/bin/python3\nimport json, os, sys\n'
|
|
'assert "--no-run" in sys.argv\n'
|
|
'print(json.dumps({"reason":"compiler-artifact","profile":{"test":True},'
|
|
'"executable":os.environ["FIXTURE_BINARY"]}))\n')
|
|
cargo.chmod(0o700)
|
|
sudo = fake_bin / 'sudo'
|
|
sudo.write_text(
|
|
'#!/usr/bin/python3\nimport json, os, sys\n'
|
|
'if sys.argv[1:] == ["-n", "true"]: raise SystemExit(0)\n'
|
|
'assert sys.argv[1:3] == ["-n", "systemd-run"]\n'
|
|
'with open(os.environ["FIXTURE_LOG"], "w") as f: json.dump(sys.argv[1:], f)\n')
|
|
sudo.chmod(0o700)
|
|
log = temp / 'systemd-arguments.json'
|
|
subprocess.run(['bash', str(RUNNER), 'fixture-only', '--ignored'], check=True,
|
|
env={**os.environ, 'PATH': f'{fake_bin}:' + os.environ['PATH'],
|
|
'ARCHY_TEST_ISOLATOR': 'systemd', 'ARCHY_TEST_C01_STARTUP': '1',
|
|
'ARCHY_TEST_C01_BINARY': str(executable), 'ARCHY_TEST_THREADS': '1',
|
|
'FIXTURE_BINARY': str(executable), 'FIXTURE_LOG': str(log),
|
|
'RUST_MIN_STACK': '16777216'})
|
|
args = json.loads(log.read_text())
|
|
masks = [arg for arg in args if arg.startswith('--property=TemporaryFileSystem=')]
|
|
self.assertEqual(len(masks), 1)
|
|
for directory in ('/run', '/var/lib/archipelago', '/var/lib/containers', '/root', '/opt/archipelago', '/etc/archipelago'):
|
|
self.assertIn(directory + ':rw', masks[0].split('=', 2)[2].split())
|
|
for argument in ('--property=PrivateNetwork=yes', '--property=PrivateDevices=yes',
|
|
'--property=ProtectSystem=strict', '--property=NoNewPrivileges=yes',
|
|
'--setenv=ARCHY_TEST_ISOLATED=1', '--setenv=RUST_MIN_STACK=16777216',
|
|
'--setenv=ARCHY_TEST_C01_STARTUP=1', '--test-threads=1'):
|
|
self.assertIn(argument, args)
|
|
self.assertIn('--setenv=ARCHY_TEST_C01_BINARY=' + str(executable), args)
|
|
|
|
def test_c01_startup_refuses_an_unsupported_isolator_before_compiling(self):
|
|
result = subprocess.run(['bash', str(RUNNER)], capture_output=True, text=True,
|
|
env={**os.environ, 'ARCHY_TEST_ISOLATOR': 'podman', 'ARCHY_TEST_C01_STARTUP': '1'})
|
|
self.assertEqual(result.returncode, 2)
|
|
self.assertIn('requires the systemd fixture namespace', result.stderr)
|
|
|
|
def test_podman_mode_separates_build_and_networkless_execution(self):
|
|
with tempfile.TemporaryDirectory() as temporary:
|
|
temp = pathlib.Path(temporary)
|
|
fake_bin = temp / "bin"
|
|
fake_bin.mkdir()
|
|
log = temp / "podman.log"
|
|
podman = fake_bin / "podman"
|
|
podman.write_text(
|
|
"#!/usr/bin/env bash\n"
|
|
"printf '%s\\0' \"$@\" >> \"$PODMAN_TEST_LOG\"\n"
|
|
"printf '\\n' >> \"$PODMAN_TEST_LOG\"\n"
|
|
"if [[ \" $* \" == *' cargo test '* ]]; then\n"
|
|
" printf '%s\\n' '{\"reason\":\"compiler-artifact\",\"profile\":{\"test\":true},\"executable\":\"/workspace/core/target/debug/archy-test\"}'\n"
|
|
"fi\n"
|
|
)
|
|
podman.chmod(0o700)
|
|
cargo_home = temp / "cargo"
|
|
env = os.environ.copy()
|
|
env.update(
|
|
{
|
|
"PATH": f"{fake_bin}:{env['PATH']}",
|
|
"PODMAN_TEST_LOG": str(log),
|
|
"ARCHY_TEST_ISOLATOR": "podman",
|
|
"ARCHY_TEST_REPO": str(ROOT),
|
|
"ARCHY_TEST_IMAGE": "example.invalid/ci@sha256:test",
|
|
"ARCHY_TEST_CARGO_HOME": str(cargo_home),
|
|
}
|
|
)
|
|
|
|
subprocess.run([str(RUNNER)], env=env, check=True)
|
|
invocations = [
|
|
line.replace("\0", " ") for line in log.read_text().splitlines()
|
|
]
|
|
self.assertEqual(len(invocations), 2)
|
|
self.assertIn("--network=pasta", invocations[0])
|
|
self.assertIn(f"{ROOT}:/workspace:rw,Z", invocations[0])
|
|
self.assertIn("--network=none", invocations[1])
|
|
self.assertIn(f"{ROOT}:/workspace:ro,Z", invocations[1])
|
|
self.assertIn("ARCHY_TEST_ISOLATED=1", invocations[1])
|
|
|
|
def test_unknown_isolator_fails_closed(self):
|
|
result = subprocess.run(
|
|
[str(RUNNER)],
|
|
env={**os.environ, "ARCHY_TEST_ISOLATOR": "unknown"},
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
self.assertEqual(result.returncode, 2)
|
|
self.assertIn("must be systemd or podman", result.stderr)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|