test_sandcastle_run.py (3199B)
1 # This file is in the public domain. 2 3 import json 4 import os 5 import shutil 6 import stat 7 import subprocess 8 import tempfile 9 import unittest 10 from pathlib import Path 11 12 REPOSITORY = Path(__file__).resolve().parents[1] 13 RUN_SCRIPT = REPOSITORY / "sandcastle-run" 14 15 FAKE_PODMAN = r"""#!/usr/bin/env python3 16 import json 17 import os 18 import sys 19 from pathlib import Path 20 21 22 arguments = sys.argv[1:] 23 with Path(os.environ["FAKE_PODMAN_LOG"]).open("a", encoding="utf-8") as log: 24 log.write(json.dumps(arguments) + "\n") 25 26 if arguments[0] == "ps": 27 raise SystemExit(0) 28 if arguments[0] == "run": 29 raise SystemExit(0) 30 raise SystemExit(125) 31 """ 32 33 34 class SandcastleRunTests(unittest.TestCase): 35 def setUp(self): 36 self.temporary = tempfile.TemporaryDirectory() 37 self.root = Path(self.temporary.name) 38 self.repository = self.root / "sandcastle-ng" 39 self.repository.mkdir() 40 shutil.copy2(RUN_SCRIPT, self.repository / "sandcastle-run") 41 42 self.bin_dir = self.root / "bin" 43 self.bin_dir.mkdir() 44 podman = self.bin_dir / "podman" 45 podman.write_text(FAKE_PODMAN, encoding="utf-8") 46 podman.chmod(0o755) 47 self.log = self.root / "podman-log" 48 49 def tearDown(self): 50 self.temporary.cleanup() 51 52 def run_sandcastle(self, **settings): 53 environment = os.environ.copy() 54 environment.update( 55 { 56 "PATH": f"{self.bin_dir}:{environment['PATH']}", 57 "FAKE_PODMAN_LOG": str(self.log), 58 } 59 ) 60 for variable in ( 61 "SANDCASTLE_OVERRIDE_NAME", 62 "SANDCASTLE_SOCKET_DIR", 63 ): 64 environment.pop(variable, None) 65 environment.update(settings) 66 67 self.log.unlink(missing_ok=True) 68 69 result = subprocess.run( 70 [str(self.repository / "sandcastle-run")], 71 env=environment, 72 stdout=subprocess.PIPE, 73 stderr=subprocess.PIPE, 74 text=True, 75 timeout=5, 76 ) 77 self.assertEqual(0, result.returncode, result.stderr) 78 calls = [ 79 json.loads(line) 80 for line in self.log.read_text(encoding="utf-8").splitlines() 81 ] 82 self.assertEqual("ps", calls[0][0]) 83 self.assertEqual("run", calls[1][0]) 84 return calls[1] 85 86 def test_default_uses_sockets_without_publishing_ports(self): 87 arguments = self.run_sandcastle() 88 89 socket_dir = self.repository / "sockets" 90 self.assertTrue(socket_dir.is_dir()) 91 self.assertEqual(0o1777, stat.S_IMODE(socket_dir.stat().st_mode)) 92 self.assertIn(f"{socket_dir}:/sockets:z", arguments) 93 published_ports = [ 94 argument for argument in arguments if argument.startswith("-p=") 95 ] 96 self.assertEqual([], published_ports) 97 98 def test_custom_socket_directory_is_mounted_as_one_argument(self): 99 socket_dir = self.root / "custom socket directory" 100 101 arguments = self.run_sandcastle(SANDCASTLE_SOCKET_DIR=str(socket_dir)) 102 103 self.assertEqual(0o1777, stat.S_IMODE(socket_dir.stat().st_mode)) 104 self.assertIn(f"{socket_dir}:/sockets:z", arguments) 105 106 if __name__ == "__main__": 107 unittest.main()