refactor-1

This commit is contained in:
2026-03-15 21:46:50 +02:00
parent 24d682adf1
commit c0b378c424
25 changed files with 4839 additions and 3136 deletions

View File

@@ -15,12 +15,12 @@ import pytest
REPO_ROOT = Path(__file__).resolve().parents[1]
def _docker_available() -> bool:
if shutil.which("docker") is None:
def _runtime_available(runtime: str) -> bool:
if shutil.which(runtime) is None:
return False
result = subprocess.run(
["docker", "info"],
[runtime, "info"],
capture_output=True,
text=True,
check=False,
@@ -28,16 +28,36 @@ def _docker_available() -> bool:
return result.returncode == 0
def _require_container_e2e() -> None:
def _container_runtime() -> str | None:
preferred = os.environ.get("FLOW_E2E_CONTAINER_RUNTIME")
candidates = [preferred] if preferred else ["podman", "docker"]
for runtime in candidates:
if not runtime:
continue
if _runtime_available(runtime):
return runtime
return None
def _require_container_e2e() -> str:
if os.environ.get("FLOW_RUN_E2E_CONTAINER") != "1":
pytest.skip("Set FLOW_RUN_E2E_CONTAINER=1 to run container e2e tests")
if not _docker_available():
pytest.skip("Docker is required for container e2e tests")
runtime = _container_runtime()
if runtime is None:
pytest.skip("Podman or Docker is required for container e2e tests")
return runtime
@pytest.fixture(scope="module")
def e2e_image(tmp_path_factory):
_require_container_e2e()
def e2e_runtime():
return _require_container_e2e()
@pytest.fixture(scope="module")
def e2e_image(tmp_path_factory, e2e_runtime):
runtime = e2e_runtime
context_dir = tmp_path_factory.mktemp("flow-e2e-docker-context")
dockerfile = context_dir / "Dockerfile"
@@ -53,7 +73,7 @@ def e2e_image(tmp_path_factory):
tag = f"flow-e2e-{uuid.uuid4().hex[:10]}"
subprocess.run(
["docker", "build", "-t", tag, str(context_dir)],
[runtime, "build", "-t", tag, str(context_dir)],
check=True,
capture_output=True,
text=True,
@@ -62,13 +82,13 @@ def e2e_image(tmp_path_factory):
try:
yield tag
finally:
subprocess.run(["docker", "rmi", "-f", tag], capture_output=True, text=True, check=False)
subprocess.run([runtime, "rmi", "-f", tag], capture_output=True, text=True, check=False)
def _run_in_container(image_tag: str, script: str) -> subprocess.CompletedProcess:
def _run_in_container(runtime: str, image_tag: str, script: str) -> subprocess.CompletedProcess:
return subprocess.run(
[
"docker",
runtime,
"run",
"--rm",
"-v",
@@ -89,7 +109,7 @@ def _assert_ok(run: subprocess.CompletedProcess) -> None:
raise AssertionError(f"Container e2e failed:\nSTDOUT:\n{run.stdout}\nSTDERR:\n{run.stderr}")
def test_e2e_link_and_undo_with_root_targets(e2e_image):
def test_e2e_link_and_undo_with_root_targets(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -116,10 +136,10 @@ test ! -L "$HOME/.zshrc"
grep -q '^# before$' "$HOME/.zshrc"
test ! -e /tmp/flow-e2e-root-target
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))
def test_e2e_dry_run_force_is_read_only_in_both_flag_orders(e2e_image):
def test_e2e_dry_run_force_is_read_only_in_both_flag_orders(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -150,10 +170,10 @@ assert "last_transaction" not in data, data
PY
fi
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))
def test_e2e_unmanaged_conflict_without_force_is_non_destructive(e2e_image):
def test_e2e_unmanaged_conflict_without_force_is_non_destructive(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -177,10 +197,10 @@ test -f "$HOME/.zshrc"
test ! -L "$HOME/.zshrc"
grep -q '^# user-file$' "$HOME/.zshrc"
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))
def test_e2e_managed_drift_requires_force(e2e_image):
def test_e2e_managed_drift_requires_force(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -208,10 +228,10 @@ test -f "$HOME/.zshrc"
test ! -L "$HOME/.zshrc"
grep -q '^# drifted-manual$' "$HOME/.zshrc"
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))
def test_e2e_directory_conflict_is_atomic_even_with_force(e2e_image):
def test_e2e_directory_conflict_is_atomic_even_with_force(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -236,10 +256,10 @@ test "$rc" -ne 0
test -d "$HOME/.zshrc"
test ! -e "$HOME/.gitconfig"
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))
def test_e2e_undo_after_failed_followup_link_restores_last_transaction(e2e_image):
def test_e2e_undo_after_failed_followup_link_restores_last_transaction(e2e_runtime, e2e_image):
script = r"""
set -euo pipefail
export HOME=/home/flow
@@ -273,4 +293,4 @@ test -f "$HOME/.a"
test ! -L "$HOME/.a"
grep -q '^# pre-a$' "$HOME/.a"
"""
_assert_ok(_run_in_container(e2e_image, script))
_assert_ok(_run_in_container(e2e_runtime, e2e_image, script))