gabriel / musehub public
test_publish_muse_release_prune.py python
98 lines 4.3 KB
Raw
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
1 """Phase 2 of MuseHub issue #128 -- deploy/publish_muse_release.sh must use
2 prune_releases.py (PEP 440 precedence) instead of sort -V's lexical
3 comparison, for both the S3 cleanup and the server (SSM) cleanup blocks.
4
5 Source-level assertions, matching this repo's existing convention in
6 test_deployment.py for validating deploy scripts without executing real AWS
7 calls -- live verification against the actual staging instance/S3 bucket is
8 Phase 3 (PRUNE_10), a deliberate, human-directed action, not something a test
9 suite should trigger.
10 """
11 from __future__ import annotations
12
13 from pathlib import Path
14
15 _ROOT = Path(__file__).resolve().parents[1]
16 _PUBLISH_SH = _ROOT / "deploy" / "publish_muse_release.sh"
17 _SRC = _PUBLISH_SH.read_text()
18
19
20 def _executable_lines(src: str) -> str:
21 """Strip full-line comments -- isolates actual bash code from prose that
22 may legitimately mention "sort -V" while explaining why it was removed."""
23 return "\n".join(
24 line for line in src.splitlines() if not line.strip().startswith("#")
25 )
26
27
28 _CODE = _executable_lines(_SRC)
29
30
31 class TestPruneReleasesWiredIntoPublishScript:
32 def test_PRUNE_06_sort_dash_v_removed_entirely(self) -> None:
33 """sort -V's lexical comparison must not execute anywhere in the script.
34
35 Explanatory comments are allowed to mention "sort -V" by name (e.g.
36 documenting why it was removed) -- this checks executable code only.
37 """
38 assert "sort -V" not in _CODE
39
40 def test_PRUNE_06b_s3_cleanup_calls_prune_releases_py(self) -> None:
41 """S3 cleanup must pipe candidate filenames through prune_releases.py."""
42 assert "prune_releases.py" in _SRC
43 assert '--keep "$KEEP_RELEASES"' in _SRC
44
45 def test_PRUNE_06c_s3_cleanup_still_greps_muse_tarball_pattern(self) -> None:
46 """The existing muse-*.tar.gz filter must survive the rewrite --
47 prune_releases.py raises on unparseable names, so anything that
48 isn't a muse release tarball must never reach it."""
49 assert "grep '^muse-.*\\.tar\\.gz$'" in _SRC
50
51 def test_PRUNE_07_server_cleanup_has_no_sort_in_remote_command(self) -> None:
52 """The remote SSM command string must never invoke sort or awk-based
53 version comparison -- only prune_releases.py (run locally) decides
54 what's stale; the remote host receives an explicit rm list.
55
56 Checks executable code only (comments may legitimately say "the
57 remote shell never sorts" while explaining the design)."""
58 # Isolate the server-cleanup section (list + rm), not the whole file,
59 # so an unrelated "sort" elsewhere in the script wouldn't false-pass.
60 start = _CODE.index("LIST_CMD_ID=")
61 end = _CODE.index("HTTP=$(curl")
62 server_section = _CODE[start:end]
63 assert "sort" not in server_section
64 assert "awk" not in server_section
65
66 def test_PRUNE_07b_server_cleanup_computes_stale_set_locally(self) -> None:
67 """The stale set for the server must be computed via a local
68 prune_releases.py call against the SSM-fetched file listing, not
69 inside the remote SSM command string."""
70 start = _CODE.index("LIST_CMD_ID=")
71 end = _CODE.index("HTTP=$(curl")
72 server_section = _CODE[start:end]
73 assert "prune_releases.py" in server_section
74 assert 'REMOTE_FILES' in server_section
75
76 def test_PRUNE_07c_server_rm_command_targets_explicit_filenames(self) -> None:
77 """The rm sent to the remote host must be an explicit filename list,
78 not a re-derived sort/keep-N pipeline."""
79 start = _CODE.index("LIST_CMD_ID=")
80 end = _CODE.index("HTTP=$(curl")
81 server_section = _CODE[start:end]
82 assert "rm -v" in server_section
83
84 def test_script_dir_used_for_prune_releases_reference(self) -> None:
85 """prune_releases.py must be referenced via $SCRIPT_DIR, not a bare
86 relative path -- the script must work regardless of the caller's cwd."""
87 assert '$SCRIPT_DIR/prune_releases.py' in _SRC
88
89 def test_syntax_is_valid_bash(self) -> None:
90 """The script must still parse as valid bash after the rewrite."""
91 import subprocess
92
93 result = subprocess.run(
94 ["bash", "-n", str(_PUBLISH_SH)],
95 capture_output=True,
96 text=True,
97 )
98 assert result.returncode == 0, result.stderr
File History 2 commits
sha256:34035d72cef530c1ab9d6a6f53be18d803dde705fc3157617d70352a96d0747b Merge branch 'fix/wire-push-external-parent-manifest' into dev Human 8 days ago
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 8 days ago