89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""Validate generated guard programs with Bash's actual parser, without effects."""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import importlib.util
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
CONTROLLER = Path(__file__).resolve().parents[2] / "ops/gitea-deploy-broker"
|
|
RUNNER = '''#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
readonly DEPLOY_RUNNER="deployment-runner"
|
|
stack_recovery=0
|
|
if [ "$stack_recovery" -eq 0 ]; then
|
|
stack_recovery=1
|
|
fi
|
|
unexpected=0
|
|
for name in validation-runner; do
|
|
[ "$name" = "$DEPLOY_RUNNER" ] && continue
|
|
unexpected=1
|
|
done
|
|
'''
|
|
HOST = '''#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
# ITWORX_RUNNER_CAPACITY_V2_BEGIN
|
|
capacity_active=true
|
|
# ITWORX_RUNNER_CAPACITY_V2_END
|
|
runner_healthy=1
|
|
if [ "$runner_healthy" -eq 1 ]; then
|
|
if [ "$sandbox_healthy" -eq 1 ] && \\
|
|
timeout 20 docker start "$RUNNER" "$SECONDARY_RUNNER" >/dev/null 2>&1; then
|
|
:
|
|
fi
|
|
fi
|
|
'''
|
|
|
|
|
|
@pytest.fixture
|
|
def fleet(monkeypatch):
|
|
monkeypatch.syspath_prepend(str(CONTROLLER))
|
|
spec = importlib.util.spec_from_file_location(
|
|
"runner_guard_shell_contract", CONTROLLER / "runner_fleet_specialize.py",
|
|
)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
sys.modules[spec.name] = module
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
@pytest.mark.skipif(os.name != "posix", reason="Real Bash guard validation requires POSIX")
|
|
@pytest.mark.parametrize("kind", ["runner", "host", "host_legacy"])
|
|
def test_complete_generated_guard_passes_real_bash_parser(fleet, kind, monkeypatch):
|
|
bash = shutil.which("bash")
|
|
assert bash is not None, "The deployment qualification requires Bash"
|
|
state_command = "timeout 15 /fixed/controller --state"
|
|
if kind == "runner":
|
|
original = RUNNER
|
|
generated = fleet._patch_runner_guard(
|
|
original, state_command,
|
|
'timeout 10 /fixed/controller --guard-allows-container "$name"',
|
|
)
|
|
else:
|
|
original = HOST
|
|
if kind == "host_legacy":
|
|
original = original.replace(
|
|
"# ITWORX_RUNNER_CAPACITY_V2_BEGIN\ncapacity_active=true\n"
|
|
"# ITWORX_RUNNER_CAPACITY_V2_END\n", "",
|
|
)
|
|
# This isolated fixture represents a single approved legacy source.
|
|
# Live acceptance separately binds the actual unchanged guard hash.
|
|
monkeypatch.setattr(
|
|
fleet, "HOST_GUARD_SOURCE_SHA256",
|
|
hashlib.sha256(original.encode("utf-8")).hexdigest(),
|
|
)
|
|
generated = fleet._patch_host_guard(original, state_command)
|
|
for program in (original, generated):
|
|
# Parse stdin only. No shell program, controller, Docker or guard runs.
|
|
result = subprocess.run(
|
|
[bash, "-n"], input=program.encode("utf-8"),
|
|
capture_output=True, timeout=5, check=False,
|
|
)
|
|
assert result.returncode == 0, "Generated guard failed real Bash syntax validation"
|