gabriel / musehub public

smoke_push.py file-level

at sha256:3 · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:0 fix: fall back to any indexed mpack in read_object_bytes when push mpac… · gabriel · Jun 17, 2026
1 #!/usr/bin/env python3
2 """Push smoke test — create a fresh unique repo, build commits, push, report timing.
3
4 Usage:
5 python tools/smoke_push.py xs # 1 commit, 5 files, 512 B/file
6 python tools/smoke_push.py s # 10 commits, 10 files, 1 KB/file
7 python tools/smoke_push.py m # 100 commits,20 files, 2 KB/file
8 python tools/smoke_push.py l # 500 commits,50 files, 4 KB/file
9 python tools/smoke_push.py xl # 1000 commits,100 files,8 KB/file
10 python tools/smoke_push.py xs s m # run multiple sizes in sequence
11 python tools/smoke_push.py --hub https://staging.musehub.ai xs
12 """
13 from __future__ import annotations
14
15 import json
16 import random
17 import shutil
18 import string
19 import subprocess
20 import sys
21 import time
22 from pathlib import Path
23
24 HUB_REPO_CTX = str(Path(__file__).parent.parent) # musehub repo root
25
26 SIZES = {
27 "xs": (1, 5, 512),
28 "s": (10, 10, 1_024),
29 "m": (100, 20, 2_048),
30 "l": (500, 50, 4_096),
31 "xl": (1000, 100, 8_192),
32 }
33
34
35 def run(cmd: list[str], cwd: str | None = None, check: bool = True) -> subprocess.CompletedProcess:
36 return subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, check=check)
37
38
39 def rnd_content(size: int, seed: int) -> str:
40 rng = random.Random(seed)
41 return "".join(random.Random(seed).choice(string.ascii_letters + string.digits + "\n")
42 for _ in range(size))
43
44
45 def smoke(label: str, hub: str) -> dict:
46 n_commits, n_files, file_size = SIZES[label]
47 ts = int(time.time())
48 slug = f"smoke-{label}-{ts}"
49 repo_path = Path(f"/tmp/{slug}")
50
51 total_kb = n_commits * n_files * file_size // 1024
52 print(f"\n{'='*64}")
53 print(f" {label.upper()} — {n_commits} commits × {n_files} files × {file_size}B ≈ {total_kb} KB")
54 print(f" repo: gabriel/{slug} hub: {hub}")
55 print(f"{'='*64}")
56
57 # Fresh local repo
58 repo_path.mkdir(parents=True, exist_ok=True)
59 run(["muse", "init"], cwd=str(repo_path))
60 run(["muse", "remote", "set-url", "local", f"{hub}/gabriel/{slug}"], cwd=str(repo_path))
61
62 # Create hub repo
63 print(f" creating hub repo…", flush=True)
64 r = run(["muse", "-C", HUB_REPO_CTX, "hub", "repo", "create",
65 "--name", slug, "--visibility", "public", "--hub", hub], check=False)
66 if r.returncode != 0:
67 print(f" ❌ hub create failed: {r.stderr[:200]}")
68 shutil.rmtree(repo_path, ignore_errors=True)
69 return {"label": label, "error": "hub create failed"}
70
71 # Build commits
72 print(f" building {n_commits} commit(s)…", flush=True)
73 t_build = time.monotonic()
74 src_dir = repo_path / "src"
75 src_dir.mkdir()
76 for ci in range(n_commits):
77 for fi in range(n_files):
78 (src_dir / f"file_{fi:04d}.txt").write_text(rnd_content(file_size, ci * 10000 + fi))
79 run(["muse", "code", "add", "."], cwd=str(repo_path))
80 run(["muse", "commit", "-m", f"c{ci+1}",
81 "--agent-id", "smoke", "--model-id", "none", "--sign"], cwd=str(repo_path))
82 if n_commits >= 100 and (ci + 1) % 100 == 0:
83 print(f" {ci+1}/{n_commits}", flush=True)
84 print(f" built in {time.monotonic()-t_build:.1f}s", flush=True)
85
86 # Object count from HEAD manifest
87 try:
88 m = json.loads(run(["muse", "read", "--json", "--manifest"], cwd=str(repo_path)).stdout)
89 n_objects = len(m.get("manifest", {}))
90 except Exception:
91 n_objects = -1
92 print(f" HEAD snapshot: {n_objects} unique objects")
93
94 # First push
95 print(f" pushing…", flush=True)
96 t0 = time.monotonic()
97 p = run(["muse", "push", "local", "main"], cwd=str(repo_path), check=False)
98 elapsed = time.monotonic() - t0
99
100 if p.returncode != 0:
101 print(f" ❌ FAILED in {elapsed:.3f}s")
102 print(p.stderr[-400:])
103 shutil.rmtree(repo_path, ignore_errors=True)
104 return {"label": label, "n_commits": n_commits, "n_objects": n_objects,
105 "error": p.stderr[-120:].strip(), "first_push_s": round(elapsed, 3)}
106
107 print(f" ✅ first push: {elapsed:.3f}s")
108 # Show key server timing lines
109 for line in p.stdout.splitlines():
110 if any(k in line for k in ["TOTAL server", "stored", "✅ Pushed"]):
111 print(f" {line.strip()}")
112
113 # Re-push (all objects already in DB — tests O(1) presign path)
114 print(f" re-pushing (already-stored)…", flush=True)
115 t1 = time.monotonic()
116 p2 = run(["muse", "push", "local", "main"], cwd=str(repo_path), check=False)
117 elapsed2 = time.monotonic() - t1
118 print(f" {'✅' if p2.returncode == 0 else '❌'} re-push: {elapsed2:.3f}s")
119
120 shutil.rmtree(repo_path, ignore_errors=True)
121 return {
122 "label": label, "n_commits": n_commits, "n_objects": n_objects,
123 "first_push_s": round(elapsed, 3), "repush_s": round(elapsed2, 3), "ok": True,
124 }
125
126
127 def main() -> None:
128 args = sys.argv[1:]
129 hub = "https://localhost:1337"
130
131 # --hub flag
132 if "--hub" in args:
133 i = args.index("--hub")
134 hub = args[i + 1]
135 args = args[:i] + args[i + 2:]
136
137 if not args:
138 print(__doc__)
139 sys.exit(1)
140
141 labels = [a.lower() for a in args]
142 for lbl in labels:
143 if lbl not in SIZES:
144 print(f"unknown size '{lbl}' — choose from: {', '.join(SIZES)}")
145 sys.exit(1)
146
147 results = [smoke(lbl, hub) for lbl in labels]
148
149 if len(results) > 1:
150 print(f"\n{'='*64}")
151 print(f" SUMMARY")
152 print(f"{'='*64}")
153 print(f"{'Size':<6} {'Commits':>8} {'Objects':>8} {'First':>10} {'Re-push':>9} Status")
154 print("-" * 50)
155 for r in results:
156 if "error" in r and "first_push_s" not in r:
157 print(f"{r['label'].upper():<6} {r.get('n_commits','?'):>8} {r.get('n_objects','?'):>8} "
158 f"{'FAILED':>10} {'—':>9} ❌")
159 else:
160 print(f"{r['label'].upper():<6} {r['n_commits']:>8} {r['n_objects']:>8} "
161 f"{r['first_push_s']:>9.3f}s {r.get('repush_s',0):>8.3f}s ✅")
162
163
164 if __name__ == "__main__":
165 main()