GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — devstack/scripts/test_localpibox_devstack.py at docs · lpb-stack/devstack Expand file tree/ Copy pathtest_localpibox_devstack.pyMore file actions 278 lines (235 loc) · 11.6 KB / Copy pathtest_localpibox_devstack.pyFile metadata and controls278 lines (235 loc) · 11.6 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 #!/usr/bin/env python3 """scripts/lpb-devstack tests: VERSION bumping (patch/minor/set, commit, missing VERSION) and repo tagging (tag-repos, missing clone).""" from __future__ import annotations from testharness import run_lpbx_suite, _bare_remote, _quiet_console, _load_script, SCRIPTS_DIR import os import json import subprocess from pathlib import Path from contextlib import ExitStack from unittest import mock from localpibox.stack import version as ver_mod from localpibox.stack import workspace as ws_mod from localpibox.stack import release as rel_mod from localpibox.stack import repos as repos_mod ld = _load_script('lpb_devstack', SCRIPTS_DIR / 'lpb-devstack') # ─── lpb-devstack: VERSION bumping ──────────────────────────────────────── def _devstack_root_patch(root, tmpdir): """Point stack version discovery at *root* (context manager). Also neutralizes the dev release gate: without patching repo_path, the gate inspects the *real* workspace (its own module-level roots), so a dirty or unpushed local checkout would make the bump tests fail. """ stack = ExitStack() stack.enter_context(mock.patch.object(ver_mod, "_DEVSTACK_ROOT", root)) stack.enter_context(mock.patch.object(ver_mod, "WORKSPACE_ROOT", tmpdir / "nowhere")) stack.enter_context(mock.patch.object(ver_mod, "_VERSION_FILE", None)) # repo_path() resolves against repos.* at call time — patch its roots so # the gate finds no local clones (tests that need a fake gate repo patch # rel_mod.repo_path directly, which still wins). stack.enter_context(mock.patch.object( repos_mod, "WORKSPACE_ROOT", tmpdir / "nowhere")) stack.enter_context(mock.patch.object( repos_mod, "DEFAULT_AGENT_DIR", str(tmpdir / "agent"))) return stack def test_devstack_bump_patch(tmpdir): root = tmpdir / "devstack" root.mkdir() (root / "VERSION").write_text("0.0.57-lpb-dev\n") with _devstack_root_patch(root, tmpdir): code = ld.cmd_bump(_quiet_console(), no_commit=True) assert code == 0 assert (root / "VERSION").read_text().strip() == "0.0.58-lpb-dev" def test_devstack_bump_minor_and_set(tmpdir): root = tmpdir / "devstack" root.mkdir() (root / "VERSION").write_text("0.0.9-lpb-dev\n") with _devstack_root_patch(root, tmpdir): assert ld.cmd_bump(_quiet_console(), minor=True, no_commit=True) == 0 assert (root / "VERSION").read_text().strip() == "0.1.0-lpb-dev" # explicit --set (same value → no-op, still 0) assert ld.cmd_bump(_quiet_console(), set_version="0.1.0-lpb-dev", no_commit=True) == 0 assert (root / "VERSION").read_text().strip() == "0.1.0-lpb-dev" # invalid --set rejected assert ld.cmd_bump(_quiet_console(), set_version="1.2.3", no_commit=True) == 1 assert (root / "VERSION").read_text().strip() == "0.1.0-lpb-dev" def test_devstack_bump_commits(tmpdir): root = tmpdir / "devstack" root.mkdir() subprocess.run(["git", "init", "-q", str(root)], check=True) subprocess.run(["git", "-C", str(root), "config", "user.email", "t@t"], check=True) subprocess.run(["git", "-C", str(root), "config", "user.name", "t"], check=True) (root / "VERSION").write_text("0.0.57-lpb-dev\n") subprocess.run(["git", "-C", str(root), "add", "."], check=True) subprocess.run(["git", "-C", str(root), "commit", "-qm", "init"], check=True) with _devstack_root_patch(root, tmpdir): code = ld.cmd_bump(_quiet_console()) # commit (no push) assert code == 0 r = subprocess.run( ["git", "-C", str(root), "show", "HEAD:VERSION"], capture_output=True, text=True) assert r.stdout.strip() == "0.0.58-lpb-dev" def test_devstack_bump_missing_version(tmpdir): with mock.patch.object(ver_mod, "_VERSION_FILE", None), \ mock.patch.object(ver_mod, "_DEVSTACK_ROOT", tmpdir / "nope"), \ mock.patch.object(ver_mod, "WORKSPACE_ROOT", tmpdir / "nope2"): assert ld.cmd_bump(_quiet_console(), no_commit=True) == 1 # ─── lpb-devstack: dev release gate (bump requires other repos pushed) ──── def _gate_env(tmpdir, branch="dev"): """Fake stack repo (bare remote + clean clone) + patches so the gate sees only it. Returns (work, patches).""" _remote, work = _bare_remote(tmpdir, "fake-repo", branch) p1 = mock.patch.object(rel_mod, "TAG_REPOS", [("fake-repo", branch, "stable")]) p2 = mock.patch.object(rel_mod, "repo_path", lambda name: work) p1.start() p2.start() return work, [p1, p2] def test_dev_release_gate_clean(tmpdir): _work, patches = _gate_env(tmpdir) try: assert rel_mod.dev_release_gate(_quiet_console()) == 0 finally: for p in patches: p.stop() def test_dev_release_gate_blocks_unpushed(tmpdir): work, patches = _gate_env(tmpdir) try: (work / "g").write_text("local only") subprocess.run(["git", "-C", str(work), "add", "."], check=True) subprocess.run(["git", "-C", str(work), "commit", "-qm", "local"], check=True) cons = _quiet_console() assert rel_mod.dev_release_gate(cons) == 1 assert "unpushed" in cons.err.getvalue() finally: for p in patches: p.stop() def test_dev_release_gate_blocks_uncommitted(tmpdir): work, patches = _gate_env(tmpdir) try: (work / "f").write_text("dirty") cons = _quiet_console() assert rel_mod.dev_release_gate(cons) == 1 assert "uncommitted" in cons.err.getvalue() finally: for p in patches: p.stop() def test_dev_release_gate_blocks_wrong_branch(tmpdir): work, patches = _gate_env(tmpdir) try: subprocess.run(["git", "-C", str(work), "checkout", "-q", "-b", "feature"], check=True) cons = _quiet_console() assert rel_mod.dev_release_gate(cons) == 1 assert "expected dev" in cons.err.getvalue() finally: for p in patches: p.stop() def test_devstack_bump_gate_blocks_and_force_bypasses(tmpdir): root = tmpdir / "devstack" root.mkdir() (root / "VERSION").write_text("0.0.57-lpb-dev\n") work, patches = _gate_env(tmpdir) (work / "g").write_text("local only") subprocess.run(["git", "-C", str(work), "add", "."], check=True) subprocess.run(["git", "-C", str(work), "commit", "-qm", "local"], check=True) try: with _devstack_root_patch(root, tmpdir): # Gate blocks: VERSION must not be written assert ld.cmd_bump(_quiet_console(), no_commit=True) == 1 assert (root / "VERSION").read_text().strip() == "0.0.57-lpb-dev" # --force bypasses the gate assert ld.cmd_bump(_quiet_console(), no_commit=True, force=True) == 0 assert (root / "VERSION").read_text().strip() == "0.0.58-lpb-dev" finally: for p in patches: p.stop() def test_devstack_bump_syncs_pins_before_commit(tmpdir): """bump updates settings.json pins to the NEW version before committing (post-stable-release case: pins sit at the stable tag; without this the pre-commit validate fails and a post-hook sync would target the old version).""" root = tmpdir / "devstack" root.mkdir() (root / "VERSION").write_text("0.0.78-lpb-dev\n") agent = tmpdir / "agent" agent.mkdir(parents=True, exist_ok=True) settings = {"packages": [ "git:github.com/lpb-stack/[email protected]", "git:github.com/lpb-stack/[email protected]", # pi-subagents: upstream npm pin (fork retired) — bump must leave it alone "npm:@tintinweb/[email protected]", ]} (agent / "settings.json").write_text(json.dumps(settings)) with _devstack_root_patch(root, tmpdir), \ mock.patch.object(repos_mod, "DEFAULT_AGENT_DIR", str(agent)), \ mock.patch.object(ws_mod, "_read_settings", lambda ad: json.loads((Path(ad) / "settings.json").read_text())), \ mock.patch.object(ws_mod, "_write_settings", lambda ad, s: (Path(ad) / "settings.json").write_text(json.dumps(s))): code = ld.cmd_bump(_quiet_console(), no_commit=True) assert code == 0 pins = json.loads((agent / "settings.json").read_text()) if isinstance(pins, dict): pins = pins.get("packages", []) git_pins = [p for p in pins if p.startswith("git:")] assert all(p.endswith("@0.0.79-lpb-dev") for p in git_pins) # the upstream npm pin is untouched def test_devstack_bump_missing_settings_is_noop(tmpdir): """No settings.json → pin sync is a no-op, bump still succeeds.""" root = tmpdir / "devstack" root.mkdir() (root / "VERSION").write_text("0.0.57-lpb-dev\n") with _devstack_root_patch(root, tmpdir), \ mock.patch.object(repos_mod, "DEFAULT_AGENT_DIR", str(tmpdir / "no-agent")): assert ld.cmd_bump(_quiet_console(), no_commit=True) == 0 # ─── lpb-devstack: repo tagging ─────────────────────────────────────────── def test_devstack_tag_repos(tmpdir): remote, _src = _bare_remote(tmpdir, "pi", "lpb-dev") # Local workspace clone (cmd_tag_repos tags via the workspace repos) ws = tmpdir / "workspace" / "pi" ws.parent.mkdir(parents=True, exist_ok=True) subprocess.run(["git", "clone", "-q", "--branch", "lpb-dev", str(remote), str(ws)], check=True) env = mock.patch.dict(os.environ, {"LPB_STACK_REMOTE_BASE": str(tmpdir / "remotes")}) patch_repos = mock.patch.object(ld, "TAG_REPOS", [("pi", "lpb-dev", "lpb")]) patch_ws = mock.patch.object(ws_mod, "WORKSPACE_ROOT", tmpdir / "workspace") for p in (env, patch_repos, patch_ws): p.start() try: code = ld.cmd_tag_repos(_quiet_console(), pipeline="dev", version="0.0.58-lpb-dev") assert code == 0 r = subprocess.run( ["git", "ls-remote", str(remote), "refs/tags/0.0.58-lpb-dev"], capture_output=True, text=True) assert "0.0.58-lpb-dev" in r.stdout # idempotent: second run reports "already exists" and succeeds assert ld.cmd_tag_repos(_quiet_console(), pipeline="dev", version="0.0.58-lpb-dev") == 0 # main pipeline targets the 'lpb' branch (absent on this remote → fail fast) assert ld.cmd_tag_repos(_quiet_console(), pipeline="main", version="0.0.58-lpb") == 1 finally: for p in (env, patch_repos, patch_ws): p.stop() def test_devstack_tag_repos_missing_clone(tmpdir): with mock.patch.object(ld, "TAG_REPOS", [("pi", "lpb-dev", "lpb")]), \ mock.patch.object(ws_mod, "WORKSPACE_ROOT", tmpdir / "empty-ws"): cons = _quiet_console() assert ld.cmd_tag_repos(cons, pipeline="dev", version="0.0.58-lpb-dev") == 1 assert "workspace sync" in cons.err.getvalue() def test_devstack_release_cli_surface(tmpdir): """New release subcommands/flags parse: docs-ready + promote --force.""" import contextlib import io for argv, needle in ((["release", "docs-ready", "--help"], "docs-ready"), (["release", "promote", "--help"], "--force")): buf = io.StringIO() try: with contextlib.redirect_stdout(buf): ld.main(argv) raise AssertionError(f"{argv} did not exit") except SystemExit as e: assert e.code == 0 assert needle in buf.getvalue() def main() -> int: return run_lpbx_suite("lpb-devstack tests", globals()) if __name__ == "__main__": raise SystemExit(main()) |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |