97 lines
2.9 KiB
Python
97 lines
2.9 KiB
Python
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[3]
|
|
SCRIPT = ROOT / "scripts/ci/bootstrap-host-runner-tools.sh"
|
|
REQUIRED = ("node", "npm", "git", "curl", "bash", "timeout", "python3", "ssh")
|
|
|
|
|
|
def _write_command(path: Path, body: str = "exit 0\n") -> None:
|
|
path.write_text("#!/bin/sh\n" + body, encoding="utf-8")
|
|
path.chmod(0o755)
|
|
|
|
|
|
def _fake_tool_path(directory: Path, *, include_npm: bool) -> None:
|
|
for command in REQUIRED:
|
|
if command != "npm" or include_npm:
|
|
_write_command(directory / command)
|
|
_write_command(directory / "docker")
|
|
|
|
|
|
def _run(directory: Path) -> subprocess.CompletedProcess[str]:
|
|
env = os.environ.copy()
|
|
env["PATH"] = str(directory)
|
|
return subprocess.run(
|
|
["/bin/bash", str(SCRIPT)],
|
|
check=False,
|
|
text=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
env=env,
|
|
)
|
|
|
|
|
|
def test_ready_runner_skips_package_install() -> None:
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
directory = Path(temp)
|
|
_fake_tool_path(directory, include_npm=True)
|
|
|
|
completed = _run(directory)
|
|
|
|
assert completed.returncode == 0
|
|
assert "host_runner_tools_ready=1 bootstrap_install_performed=0" in completed.stdout
|
|
|
|
|
|
def test_missing_tool_without_apk_fails_closed() -> None:
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
directory = Path(temp)
|
|
_fake_tool_path(directory, include_npm=False)
|
|
|
|
completed = _run(directory)
|
|
|
|
assert completed.returncode == 1
|
|
assert "host_runner_tools_missing=npm" in completed.stdout
|
|
assert "BLOCKER host_runner_tools_missing_and_apk_unavailable" in completed.stdout
|
|
|
|
|
|
def test_missing_tool_uses_apk_once_and_revalidates() -> None:
|
|
with tempfile.TemporaryDirectory() as temp:
|
|
directory = Path(temp)
|
|
_fake_tool_path(directory, include_npm=False)
|
|
apk_log = directory / "apk.log"
|
|
_write_command(
|
|
directory / "apk",
|
|
'printf "%s\\n" "$*" > "$APK_LOG"\n'
|
|
'printf "#!/bin/sh\\nexit 0\\n" > "$FAKE_BIN/npm"\n'
|
|
'/bin/chmod +x "$FAKE_BIN/npm"\n',
|
|
)
|
|
env = os.environ.copy()
|
|
env.update(
|
|
{
|
|
"PATH": str(directory),
|
|
"APK_LOG": str(apk_log),
|
|
"FAKE_BIN": str(directory),
|
|
}
|
|
)
|
|
|
|
completed = subprocess.run(
|
|
["/bin/bash", str(SCRIPT)],
|
|
check=False,
|
|
text=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
env=env,
|
|
)
|
|
|
|
install_args = apk_log.read_text(encoding="utf-8")
|
|
|
|
assert completed.returncode == 0
|
|
assert "bootstrap_install_performed=1" in completed.stdout
|
|
assert install_args.startswith("add --no-cache ")
|
|
assert "docker-cli-buildx" in install_args
|