tests/test_bootstrap_arch.py
back to source
import os
import subprocess
import unittest
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BOOTSTRAP = os.path.join(ROOT, "boot", "bootstrap.sh").replace("\\", "/")
def sh(snippet, env=None):
"""Source bootstrap.sh with main suppressed, then run snippet."""
full = 'NUMOS_SOURCE_ONLY=1 . "%s"; %s' % (BOOTSTRAP, snippet)
merged = dict(os.environ)
merged["NUMOS_SOURCE_ONLY"] = "1"
merged["NUMOS_LIB"] = os.path.dirname(BOOTSTRAP) + "/lib"
if env:
merged.update(env)
proc = subprocess.run(["bash", "-c", full], capture_output=True, text=True, env=merged)
return proc.returncode, proc.stdout.strip(), proc.stderr.strip()
class TestArchResolution(unittest.TestCase):
def test_amd64_resolves_to_x86_64(self):
code, out, _ = sh("numos_detect_arch", {"NUMOS_FAKE_UNAME_M": "amd64"})
self.assertEqual(code, 0)
self.assertEqual(out, "x86_64")
def test_arm64_resolves_to_aarch64(self):
_, out, _ = sh("numos_detect_arch", {"NUMOS_FAKE_UNAME_M": "arm64"})
self.assertEqual(out, "aarch64")
def test_armv7l_resolves_to_arm(self):
_, out, _ = sh("numos_detect_arch", {"NUMOS_FAKE_UNAME_M": "armv7l"})
self.assertEqual(out, "arm")
def test_riscv64_resolves_to_itself(self):
_, out, _ = sh("numos_detect_arch", {"NUMOS_FAKE_UNAME_M": "riscv64"})
self.assertEqual(out, "riscv64")
def test_unknown_arch_halts_with_named_reason(self):
code, _, err = sh("numos_detect_arch", {"NUMOS_FAKE_UNAME_M": "vax"})
self.assertNotEqual(code, 0)
self.assertIn("numos: HALT:", err)
self.assertIn("vax", err)
class TestArtifactSelection(unittest.TestCase):
def test_arch_with_static_build_selects_static(self):
_, out, _ = sh("numos_select_artifact x86_64")
self.assertEqual(out, "static numinit-x86_64")
def test_arch_without_static_build_falls_back_to_busybox(self):
_, out, _ = sh("numos_select_artifact loongarch64")
self.assertEqual(out, "fallback busybox-static-loongarch64")
class TestSourcingDiscipline(unittest.TestCase):
def test_sourcing_does_not_run_main(self):
code, out, _ = sh("echo SOURCED_CLEAN")
self.assertEqual(code, 0)
self.assertIn("SOURCED_CLEAN", out)
def test_script_has_no_bashisms(self):
with open(os.path.join(ROOT, "boot", "bootstrap.sh")) as handle:
body = handle.read()
for bashism in ("[[", "declare ", "local ", "${!", "function "):
self.assertNotIn(bashism, body)
def test_default_numos_lib_expansion_via_dirname(self):
"""Test that the default NUMOS_LIB expansion (via dirname $0) works when executed directly.
This exercises the line: NUMOS_LIB="${NUMOS_LIB:-$(dirname "$0")/lib}"
When the script is executed directly, $0 is the script path, so dirname yields the boot directory.
This test ensures the arch table is found via the default path, not via env override.
"""
# Create environment without NUMOS_LIB (ensure we test the default expansion, not env override)
merged = dict(os.environ)
merged.pop("NUMOS_LIB", None)
merged["NUMOS_FAKE_UNAME_M"] = "amd64"
# Execute the script directly (not sourced) from repo root
# When $0 is the full path to bootstrap.sh, dirname "$0" yields the boot directory
proc = subprocess.run(
["bash", BOOTSTRAP],
capture_output=True,
text=True,
env=merged,
cwd=ROOT
)
# Script should succeed and report x86_64 as the detected arch
self.assertEqual(proc.returncode, 0,
f"Script failed: {proc.stderr}")
self.assertIn("x86_64", proc.stdout,
f"Expected 'x86_64' in output but got: {proc.stdout}")
if __name__ == "__main__":
unittest.main()