mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 20:27:56 +00:00
515 lines
21 KiB
Python
515 lines
21 KiB
Python
"""The managed update: its remote, its target and the branch it may not rewrite.
|
|
|
|
Split verbatim out of ``tests/test_git_ops_recovery.py`` by theme. This module owns the
|
|
passive status that does not ensure a remote, the fetch and dependency sync that are panic
|
|
tracked and killed on timeout, the manifest remote name the target uses, the dev branch the
|
|
preparation preserves, and the pinned checkout a stand keeps across restarts.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
|
|
|
|
import supervisor.git_ops as git_ops
|
|
|
|
|
|
def test_compute_managed_update_status_passive_does_not_ensure_remote(monkeypatch):
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_read_managed_repo_meta",
|
|
lambda: {
|
|
"managed_remote_name": "managed",
|
|
"managed_remote_branch": "ouroboros",
|
|
},
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"ensure_official_update_remote",
|
|
lambda: (_ for _ in ()).throw(AssertionError("passive status mutated remotes")),
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_resolve_managed_update_target",
|
|
lambda *_args: ("", "", "no cached official tags"),
|
|
)
|
|
|
|
def fake_git_capture(cmd):
|
|
if cmd[:3] == ["git", "remote", "get-url"]:
|
|
return 0, "https://github.com/razzant/ouroboros", ""
|
|
if cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
|
|
return 0, "ouroboros", ""
|
|
if cmd == ["git", "rev-parse", "HEAD"]:
|
|
return 0, "abc123", ""
|
|
if cmd == ["git", "--no-optional-locks", "status", "--porcelain"]:
|
|
return 0, "", ""
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops, "git_capture", fake_git_capture)
|
|
|
|
status = git_ops.compute_managed_update_status(fetch=False)
|
|
|
|
assert status["managed"] is True
|
|
assert "official_status_requires_check" in status["warnings"]
|
|
|
|
def test_official_fetch_timeout_kills_the_process_tree(monkeypatch):
|
|
import ouroboros.platform_layer as platform_layer
|
|
from ouroboros.tools import shell
|
|
|
|
calls = []
|
|
|
|
class FakeProcess:
|
|
returncode = 1
|
|
|
|
def __init__(self):
|
|
self.communicates = 0
|
|
|
|
def communicate(self, input=None, timeout=None):
|
|
assert self in shell._active_subprocesses
|
|
self.communicates += 1
|
|
if self.communicates == 1:
|
|
raise subprocess.TimeoutExpired(["git", "fetch"], timeout)
|
|
return "", "still running"
|
|
|
|
proc = FakeProcess()
|
|
monkeypatch.setattr(git_ops.subprocess, "Popen", lambda *args, **kwargs: proc)
|
|
monkeypatch.setattr(
|
|
platform_layer,
|
|
"kill_process_tree",
|
|
lambda child: calls.append(child),
|
|
)
|
|
|
|
rc, out, error = git_ops.git_fetch_bounded("managed", timeout=0.01)
|
|
|
|
assert rc == git_ops.FETCH_TIMEOUT_RC
|
|
assert out == ""
|
|
assert "exceeded" in error
|
|
assert calls == [proc]
|
|
assert proc not in shell._active_subprocesses
|
|
|
|
def test_dependency_sync_is_panic_tracked_and_killed_on_timeout(monkeypatch, tmp_path):
|
|
import ouroboros.platform_layer as platform_layer
|
|
from ouroboros.tools import shell
|
|
|
|
# The timeout branch LOGS through git_ops.DRIVE_ROOT; unbound, this test is
|
|
# one process-global drift away from appending to the LIVE supervisor log
|
|
# (observed: nondeterministic live writes during full-battery serial runs).
|
|
monkeypatch.setattr(git_ops, "DRIVE_ROOT", tmp_path / "data")
|
|
(tmp_path / "data" / "logs").mkdir(parents=True)
|
|
# This case deliberately exercises the PRODUCTION install path, so it drops
|
|
# the test-boundary marker the suite sets (see the boundary test below).
|
|
monkeypatch.delenv("OUROBOROS_PYTEST_ACTIVE", raising=False)
|
|
|
|
killed = []
|
|
|
|
class HungProcess:
|
|
returncode = 1
|
|
|
|
def __init__(self):
|
|
self.waits = 0
|
|
|
|
def wait(self, timeout=None):
|
|
assert self in shell._active_subprocesses
|
|
self.waits += 1
|
|
if self.waits == 1:
|
|
raise subprocess.TimeoutExpired(["pip", "install"], timeout)
|
|
return -9
|
|
|
|
proc = HungProcess()
|
|
monkeypatch.setattr(git_ops.subprocess, "Popen", lambda *_a, **_k: proc)
|
|
monkeypatch.setattr(platform_layer, "kill_process_tree", lambda value: killed.append(value))
|
|
|
|
ok, _message = git_ops.sync_runtime_dependencies("managed_update_test")
|
|
|
|
assert ok is False
|
|
assert killed == [proc]
|
|
assert proc not in shell._active_subprocesses
|
|
|
|
def test_managed_update_target_uses_manifest_remote_name(monkeypatch):
|
|
import ouroboros.update_channels as update_channels
|
|
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_read_managed_repo_meta",
|
|
lambda: {
|
|
"managed_remote_name": "official",
|
|
"managed_remote_branch": "ouroboros",
|
|
},
|
|
)
|
|
monkeypatch.setattr(update_channels, "get_update_branch", lambda settings=None: "main")
|
|
|
|
remote_name, remote_branch, target_ref = git_ops._managed_update_target()
|
|
|
|
assert remote_name == "official"
|
|
assert remote_branch == "main"
|
|
assert target_ref == "official/main"
|
|
|
|
def test_prepare_managed_update_preserves_dev_branch_not_current_head(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(git_ops, "DRIVE_ROOT", tmp_path / "data")
|
|
monkeypatch.setattr(git_ops, "_read_managed_repo_meta", lambda: {"managed_remote_name": "managed"})
|
|
monkeypatch.setattr(git_ops, "_managed_update_target", lambda: ("managed", "main", "managed/main"))
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_resolve_managed_update_target",
|
|
lambda *_args: ("refs/ouroboros-managed/tags/v6.87.5", "remote-sha", ""),
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_collect_repo_sync_state",
|
|
lambda: {"current_branch": "ouroboros", "dirty_lines": [], "unpushed_lines": [], "warnings": []},
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_create_rescue_snapshot",
|
|
lambda **_kwargs: {
|
|
"path": str(tmp_path / "data" / "archive" / "rescue" / "x"),
|
|
"untracked": {"copied_files": 0, "skipped_files": 0, "truncated": False},
|
|
},
|
|
)
|
|
intent_writes = []
|
|
monkeypatch.setattr(git_ops, "_write_update_intent", lambda payload: intent_writes.append(payload))
|
|
monkeypatch.setattr(git_ops, "append_jsonl", lambda _path, _payload: None)
|
|
|
|
capture_calls = []
|
|
|
|
def fake_git_capture(cmd):
|
|
capture_calls.append(cmd)
|
|
if cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
|
|
return 0, "ouroboros", ""
|
|
if cmd == ["git", "rev-parse", "--verify", "HEAD"]:
|
|
return 0, "base-sha", ""
|
|
if cmd == ["git", "rev-parse", "--verify", "managed/main^{commit}"]:
|
|
return 0, "remote-sha", ""
|
|
if cmd == ["git", "rev-list", "--left-right", "--count", "ouroboros...remote-sha"]:
|
|
return 0, "1 0", ""
|
|
if cmd[:2] == ["git", "branch"] and cmd[-1] == "ouroboros":
|
|
return 0, "", ""
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops, "git_capture", fake_git_capture)
|
|
|
|
ok, payload = git_ops.prepare_managed_update(
|
|
"replace", expected_base_sha="base-sha", expected_target_sha="remote-sha",
|
|
arm_intent=False,
|
|
)
|
|
|
|
assert ok is True
|
|
assert payload["keep_branch"].startswith("local-keep-")
|
|
assert payload["update_intent"]["target_sha"] == "remote-sha"
|
|
assert intent_writes == []
|
|
assert any(cmd[:2] == ["git", "branch"] and cmd[-1] == "ouroboros" for cmd in capture_calls)
|
|
|
|
def test_prepare_managed_update_blocks_when_ahead_check_fails(monkeypatch, tmp_path):
|
|
monkeypatch.setattr(git_ops, "DRIVE_ROOT", tmp_path / "data")
|
|
monkeypatch.setattr(git_ops, "_read_managed_repo_meta", lambda: {"managed_remote_name": "managed"})
|
|
monkeypatch.setattr(git_ops, "_managed_update_target", lambda: ("managed", "main", "managed/main"))
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_resolve_managed_update_target",
|
|
lambda *_args: ("refs/ouroboros-managed/tags/v6.87.5", "remote-sha", ""),
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_collect_repo_sync_state",
|
|
lambda: {"current_branch": "ouroboros", "dirty_lines": [], "unpushed_lines": [], "warnings": []},
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_create_rescue_snapshot",
|
|
lambda **_kwargs: {
|
|
"path": str(tmp_path / "data" / "archive" / "rescue" / "x"),
|
|
"untracked": {"copied_files": 0, "skipped_files": 0, "truncated": False},
|
|
},
|
|
)
|
|
|
|
def fake_git_capture(cmd):
|
|
if cmd[:3] == ["git", "remote", "get-url"]:
|
|
return 0, "https://github.com/razzant/ouroboros", ""
|
|
if cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
|
|
return 0, "ouroboros", ""
|
|
if cmd == ["git", "rev-parse", "--verify", "HEAD"]:
|
|
return 0, "base-sha", ""
|
|
if cmd == ["git", "rev-parse", "--verify", "managed/main^{commit}"]:
|
|
return 0, "remote-sha", ""
|
|
if cmd == ["git", "rev-list", "--left-right", "--count", "ouroboros...remote-sha"]:
|
|
return 128, "", "bad revision"
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops, "git_capture", fake_git_capture)
|
|
|
|
ok, payload = git_ops.prepare_managed_update(
|
|
"replace", expected_base_sha="base-sha", expected_target_sha="remote-sha"
|
|
)
|
|
|
|
assert ok is False
|
|
assert "Could not compare local branch with managed update target" in payload["error"]
|
|
|
|
def test_safe_restart_fallback_does_not_rewrite_dev_branch(monkeypatch):
|
|
checkout_calls = []
|
|
|
|
def fake_checkout(branch, reason="unspecified", unsynced_policy="ignore"):
|
|
checkout_calls.append((branch, reason, unsynced_policy))
|
|
return True, "ok"
|
|
|
|
import_results = [
|
|
{"ok": False, "stdout": "", "stderr": "broken dev", "returncode": 1},
|
|
{"ok": True, "stdout": "import_ok", "stderr": "", "returncode": 0},
|
|
]
|
|
|
|
monkeypatch.setattr(git_ops, "checkout_and_reset", fake_checkout)
|
|
monkeypatch.setattr(git_ops, "sync_runtime_dependencies", lambda reason: (True, reason))
|
|
monkeypatch.setattr(git_ops, "import_test", lambda: import_results.pop(0))
|
|
monkeypatch.setattr(git_ops, "append_jsonl", lambda _path, _payload: None)
|
|
|
|
ok, message = git_ops.safe_restart(reason="owner_restart", unsynced_policy="rescue_and_reset")
|
|
|
|
assert ok is True
|
|
assert message == "OK: fell back to ouroboros-stable"
|
|
assert checkout_calls == [
|
|
("ouroboros", "owner_restart", "rescue_and_reset"),
|
|
("ouroboros-stable", "owner_restart_fallback_stable", "rescue_and_reset"),
|
|
]
|
|
|
|
def test_a_stand_can_keep_its_pinned_checkout_across_restarts(monkeypatch):
|
|
"""OUROBOROS_DISABLE_MANAGED_UPDATES=1 is the lever for running a stand.
|
|
|
|
A test stand launched against a PINNED checkout had that checkout moved under
|
|
the operator mid-test: the launcher-managed path resets the repo onto the
|
|
managed dev branch on every start (reflog "checkout: moving from <sha> to
|
|
ouroboros", version 6.89.0 -> 6.87.5). server.py already had a local-dev
|
|
branch that skips the BOOTSTRAP reset, but bootstrap is only one of three
|
|
callers — the owner restart and the agent restart reset the tree too. The
|
|
lever therefore sits at `safe_restart`, the choke point all three share, and
|
|
keeps the parts that are not a tree move: deps sync and the import test.
|
|
"""
|
|
monkeypatch.setenv("OUROBOROS_DISABLE_MANAGED_UPDATES", "1")
|
|
|
|
def fail_checkout(*_args, **_kwargs):
|
|
raise AssertionError("a stand with managed updates disabled must not be checked out")
|
|
|
|
events = []
|
|
deps = []
|
|
monkeypatch.setattr(git_ops, "checkout_and_reset", fail_checkout)
|
|
monkeypatch.setattr(git_ops, "sync_runtime_dependencies",
|
|
lambda reason: deps.append(reason) or (True, reason))
|
|
monkeypatch.setattr(git_ops, "import_test",
|
|
lambda: {"ok": True, "stdout": "", "stderr": "", "returncode": 0})
|
|
monkeypatch.setattr(git_ops, "append_jsonl", lambda _path, payload: events.append(payload))
|
|
|
|
ok, message = git_ops.safe_restart(reason="bootstrap", unsynced_policy="rescue_and_reset")
|
|
assert ok is True
|
|
assert "managed checkout disabled" in message
|
|
assert deps == ["bootstrap"], "the deps sync is not a tree move and must still run"
|
|
assert [e["type"] for e in events] == ["managed_checkout_disabled"], \
|
|
"a suppressed checkout is disclosed, never silent"
|
|
|
|
# A broken tree still fails closed — the lever pins the checkout, it does not
|
|
# promise the pinned checkout imports.
|
|
monkeypatch.setattr(git_ops, "import_test",
|
|
lambda: {"ok": False, "stdout": "", "stderr": "boom", "returncode": 1})
|
|
ok_broken, message_broken = git_ops.safe_restart(reason="owner_restart")
|
|
assert ok_broken is False
|
|
assert "Import test failed" in message_broken
|
|
|
|
# Without the lever nothing changes: the ordinary managed path still runs.
|
|
monkeypatch.delenv("OUROBOROS_DISABLE_MANAGED_UPDATES")
|
|
checkouts = []
|
|
monkeypatch.setattr(git_ops, "checkout_and_reset",
|
|
lambda branch, reason="unspecified", unsynced_policy="ignore":
|
|
checkouts.append(branch) or (True, "ok"))
|
|
monkeypatch.setattr(git_ops, "import_test",
|
|
lambda: {"ok": True, "stdout": "", "stderr": "", "returncode": 0})
|
|
assert git_ops.safe_restart(reason="bootstrap")[0] is True
|
|
assert checkouts == [git_ops.BRANCH_DEV]
|
|
|
|
def test_configure_remote_adds_origin_even_when_managed_remote_exists(monkeypatch):
|
|
calls = []
|
|
|
|
monkeypatch.setattr(git_ops, "_has_remote", lambda name=None: name in (None, "managed"))
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"git_capture",
|
|
lambda cmd: calls.append(cmd) or (0, "", ""),
|
|
)
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_configure_credential_helper",
|
|
lambda repo_slug, token: calls.append(("helper", repo_slug, token)),
|
|
)
|
|
|
|
ok, message = git_ops.configure_remote("razzant/ouroboros", "ghp_test")
|
|
|
|
assert ok
|
|
assert message == "ok"
|
|
assert ["git", "remote", "add", "origin", "https://github.com/razzant/ouroboros.git"] in calls
|
|
|
|
def test_collect_repo_sync_state_prefers_managed_remote(monkeypatch):
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_read_managed_repo_meta",
|
|
lambda: {
|
|
"managed_remote_name": "managed",
|
|
"managed_remote_branch": "ouroboros",
|
|
},
|
|
)
|
|
def fake_git_capture(cmd, *, timeout=None):
|
|
if cmd == ["git", "rev-parse", "--abbrev-ref", "HEAD"]:
|
|
return 0, "ouroboros", ""
|
|
if cmd == ["git", "status", "--porcelain"]:
|
|
return 0, "", ""
|
|
if cmd == ["git", "remote"]:
|
|
return 0, "managed", ""
|
|
if cmd == ["git", "log", "--oneline", "managed/ouroboros..HEAD"]:
|
|
return 0, "abc123 local commit\n", ""
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops, "git_capture", fake_git_capture)
|
|
|
|
state = git_ops._collect_repo_sync_state()
|
|
|
|
assert state["current_branch"] == "ouroboros"
|
|
assert state["unpushed_lines"] == ["abc123 local commit"]
|
|
|
|
def test_checkout_and_reset_keeps_bundled_sha_on_first_managed_bootstrap(monkeypatch, tmp_path):
|
|
git_dir = tmp_path / ".git"
|
|
git_dir.mkdir()
|
|
(git_dir / git_ops.BOOTSTRAP_PIN_MARKER_NAME).write_text("pending\n", encoding="utf-8")
|
|
|
|
monkeypatch.setattr(git_ops, "REPO_DIR", tmp_path)
|
|
monkeypatch.setattr(git_ops, "_has_remote", lambda name=None: name in (None, "managed"))
|
|
monkeypatch.setattr(
|
|
git_ops,
|
|
"_read_managed_repo_meta",
|
|
lambda: {
|
|
"managed_remote_name": "managed",
|
|
"managed_remote_branch": "ouroboros",
|
|
"source_sha": "bundle123",
|
|
},
|
|
)
|
|
monkeypatch.setattr(git_ops, "load_state", lambda: {"current_sha": "bundle123"})
|
|
|
|
saved_state = {}
|
|
monkeypatch.setattr(git_ops, "save_state", lambda state: saved_state.update(state))
|
|
|
|
def fake_git_capture(cmd):
|
|
if cmd == ["git", "rev-parse", "HEAD"]:
|
|
return 0, "bundle123", ""
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops, "git_capture", fake_git_capture)
|
|
|
|
calls = []
|
|
|
|
def fake_run(cmd, cwd=None, capture_output=False, text=False, check=False, env=None):
|
|
calls.append(cmd)
|
|
if cmd == ["git", "rev-parse", "--verify", "ouroboros"]:
|
|
return subprocess.CompletedProcess(cmd, 0, stdout="bundle123\n", stderr="")
|
|
if cmd[:2] == ["git", "checkout"]:
|
|
return subprocess.CompletedProcess(cmd, 0, stdout="", stderr="")
|
|
if cmd[:2] == ["git", "reset"]:
|
|
return subprocess.CompletedProcess(cmd, 0, stdout="", stderr="")
|
|
if cmd[:2] == ["git", "rev-parse"] and cmd[-1] == "HEAD":
|
|
return subprocess.CompletedProcess(cmd, 0, stdout="bundle123\n", stderr="")
|
|
raise AssertionError(cmd)
|
|
|
|
monkeypatch.setattr(git_ops.subprocess, "run", fake_run)
|
|
|
|
ok, message = git_ops.checkout_and_reset("ouroboros", reason="bootstrap", unsynced_policy="ignore")
|
|
|
|
assert ok
|
|
assert message == "ok"
|
|
assert ["git", "fetch", "managed"] not in calls
|
|
assert saved_state["current_sha"] == "bundle123"
|
|
assert not (git_dir / git_ops.BOOTSTRAP_PIN_MARKER_NAME).exists()
|
|
|
|
def test_ensure_official_update_remote_uses_manifest_remote_name(monkeypatch):
|
|
captured = []
|
|
monkeypatch.setattr(git_ops, "_read_managed_repo_meta", lambda: {"managed_remote_name": "official"})
|
|
monkeypatch.setattr(git_ops, "_list_remotes", lambda: [])
|
|
monkeypatch.setattr(git_ops, "git_capture", lambda cmd: captured.append(cmd) or (0, "", ""))
|
|
ok, _msg = git_ops.ensure_official_update_remote()
|
|
assert ok
|
|
assert ["git", "remote", "add", "official", git_ops.OFFICIAL_UPDATE_REMOTE_URL] in captured
|
|
|
|
|
|
def test_ensure_official_update_remote_honors_configured_source_across_cycles(monkeypatch):
|
|
"""W2-F2 (owner №4=A): a configured ``managed_remote_url`` is honored on
|
|
EVERY update fetch — N repin cycles never retarget a fork/mirror/air-gap
|
|
install to the hardcoded official URL."""
|
|
configured = "https://mirror.example.invalid/fork/ouroboros.git"
|
|
captured = []
|
|
monkeypatch.setattr(git_ops, "_read_managed_repo_meta", lambda: {
|
|
"managed_remote_name": "managed",
|
|
"managed_remote_url": configured,
|
|
})
|
|
monkeypatch.setattr(git_ops, "_list_remotes", lambda: ["managed"])
|
|
monkeypatch.setattr(git_ops, "git_capture", lambda cmd: captured.append(cmd) or (0, "", ""))
|
|
for _ in range(3):
|
|
ok, _msg = git_ops.ensure_official_update_remote()
|
|
assert ok
|
|
assert captured == [["git", "remote", "set-url", "managed", configured]] * 3
|
|
assert not any(git_ops.OFFICIAL_UPDATE_REMOTE_URL in cmd for cmd in captured)
|
|
|
|
|
|
def test_ensure_official_update_remote_blank_configured_source_defaults(monkeypatch):
|
|
"""No configured source (or a blank one) keeps the former default: the
|
|
hardcoded official repository URL."""
|
|
captured = []
|
|
monkeypatch.setattr(git_ops, "_read_managed_repo_meta", lambda: {"managed_remote_url": " "})
|
|
monkeypatch.setattr(git_ops, "_list_remotes", lambda: ["managed"])
|
|
monkeypatch.setattr(git_ops, "git_capture", lambda cmd: captured.append(cmd) or (0, "", ""))
|
|
ok, _msg = git_ops.ensure_official_update_remote()
|
|
assert ok
|
|
assert captured == [
|
|
["git", "remote", "set-url", "managed", git_ops.OFFICIAL_UPDATE_REMOTE_URL]
|
|
]
|
|
assert git_ops.managed_update_remote_url({"managed_remote_url": " "}) == (
|
|
git_ops.OFFICIAL_UPDATE_REMOTE_URL)
|
|
assert git_ops.managed_update_remote_url({}) == git_ops.OFFICIAL_UPDATE_REMOTE_URL
|
|
|
|
|
|
def test_dependency_sync_never_installs_into_an_interpreter_under_test(monkeypatch, tmp_path):
|
|
"""The ONE chokepoint refuses installs for every caller, not just bootstrap."""
|
|
import server
|
|
|
|
monkeypatch.setattr(git_ops, "DRIVE_ROOT", tmp_path / "data")
|
|
(tmp_path / "data" / "logs").mkdir(parents=True)
|
|
spawned = []
|
|
monkeypatch.setattr(git_ops.subprocess, "Popen",
|
|
lambda *a, **k: spawned.append(a) or _NeverRun())
|
|
monkeypatch.setenv("OUROBOROS_PYTEST_ACTIVE", "1")
|
|
|
|
assert git_ops.sync_runtime_dependencies("bootstrap_local_dev") == (True, "pytest:suppressed")
|
|
assert git_ops.sync_runtime_dependencies("managed_update_pre_restart") == (True, "pytest:suppressed")
|
|
assert spawned == [], "a test-boundary run reached the pip call site"
|
|
|
|
# The server bootstrap keeps calling the shared chokepoint: the suppression is
|
|
# a property of the dependency sync, never of one caller's local-dev branch.
|
|
calls = []
|
|
monkeypatch.setattr(server, "REPO_DIR", tmp_path / "repo")
|
|
monkeypatch.setattr(server, "DATA_DIR", tmp_path / "data")
|
|
monkeypatch.setattr(server, "_LAUNCHER_MANAGED", False)
|
|
monkeypatch.setattr(server, "setup_remote_if_configured", lambda *args: None)
|
|
|
|
class _Module:
|
|
def init(self, **_kwargs):
|
|
return None
|
|
|
|
def ensure_repo_present(self):
|
|
return None
|
|
|
|
def sync_runtime_dependencies(self, reason):
|
|
calls.append(reason)
|
|
return git_ops.sync_runtime_dependencies(reason)
|
|
|
|
def import_test(self):
|
|
return {"ok": True}
|
|
|
|
assert server._bootstrap_supervisor_repo({}, _Module())[0]
|
|
assert calls == ["bootstrap_local_dev"]
|
|
assert spawned == []
|
|
|
|
|
|
class _NeverRun:
|
|
def wait(self, timeout=None): # pragma: no cover - the boundary must precede this
|
|
raise AssertionError("the suppressed path must not wait on a pip process")
|