返回 CodeWhale
measure-persistence-backlog.py
根目录 / scripts / measure-persistence-backlog.py
1 #!/usr/bin/env python3
2 """Measure the paused-consumer persistence-channel backlog hermetically."""
3
4 from __future__ import annotations
5
6 import json
7 import os
8 import re
9 import subprocess
10 import sys
11 import tempfile
12 from pathlib import Path
13
14
15 RECEIPT_ENV = "CODEWHALE_TEST_PERSISTENCE_BACKLOG_RECEIPT_PATH"
16 SOURCE_SHA_ENV = "CODEWHALE_TEST_PERSISTENCE_BACKLOG_SOURCE_SHA"
17 SOURCE_DIRTY_ENV = "CODEWHALE_TEST_PERSISTENCE_BACKLOG_SOURCE_DIRTY"
18 RUSTC_VERSION_ENV = "CODEWHALE_TEST_PERSISTENCE_BACKLOG_RUSTC_VERSION"
19 CARGO_VERSION_ENV = "CODEWHALE_TEST_PERSISTENCE_BACKLOG_CARGO_VERSION"
20 ROOT = Path(__file__).resolve().parent.parent
21 TEST_NAME = (
22 "tui::persistence_actor::backlog_measurement_tests::"
23 "write_paused_persistence_backlog_measurement_receipt"
24 )
25
26
27 class PersistenceBacklogMeasurementError(RuntimeError):
28 """The exact measurement test did not produce a trustworthy receipt."""
29
30
31 def measurement_command() -> list[str]:
32 return [
33 "cargo",
34 "test",
35 "--locked",
36 # Match the feature set CI's `cargo nextest run --workspace
37 # --all-features` already built. Default features are a *different*
38 # unification (this crate's `--all-features` adds `web` and
39 # `long-running-tests`), so asking for them here rebuilt the crate and
40 # its dependents from scratch — ten minutes of the macOS leg spent
41 # recompiling artifacts the previous step had already produced.
42 "--all-features",
43 "-p",
44 "codewhale-tui",
45 "--lib",
46 TEST_NAME,
47 "--",
48 "--exact",
49 "--ignored",
50 "--test-threads=1",
51 ]
52
53
54 def run_measurement(receipt_path: Path, env: dict[str, str]) -> dict:
55 result = subprocess.run(
56 measurement_command(),
57 cwd=ROOT,
58 env=env,
59 text=True,
60 capture_output=True,
61 check=False,
62 )
63 sys.stderr.write(result.stderr)
64 if result.returncode != 0:
65 sys.stdout.write(result.stdout)
66 result.check_returncode()
67
68 combined = "\n".join(result.stdout.splitlines() + result.stderr.splitlines())
69 if re.search(r"\brunning\s+0\s+tests?\b", combined):
70 sys.stdout.write(result.stdout)
71 raise PersistenceBacklogMeasurementError(
72 f"exact library measurement test {TEST_NAME} ran zero tests"
73 )
74 try:
75 return json.loads(receipt_path.read_text(encoding="utf-8"))
76 except (OSError, json.JSONDecodeError) as error:
77 raise PersistenceBacklogMeasurementError(
78 f"exact library measurement test {TEST_NAME} emitted no valid receipt: {error}"
79 ) from error
80
81
82 def main() -> int:
83 source_sha = subprocess.run(
84 ["git", "rev-parse", "HEAD"],
85 cwd=ROOT,
86 text=True,
87 capture_output=True,
88 check=True,
89 ).stdout.strip()
90 source_dirty = bool(
91 subprocess.run(
92 ["git", "status", "--porcelain", "--untracked-files=normal"],
93 cwd=ROOT,
94 text=True,
95 capture_output=True,
96 check=True,
97 ).stdout
98 )
99 rustc_version = subprocess.run(
100 ["rustc", "--version"], text=True, capture_output=True, check=True
101 ).stdout.strip()
102 cargo_version = subprocess.run(
103 ["cargo", "--version"], text=True, capture_output=True, check=True
104 ).stdout.strip()
105 with tempfile.TemporaryDirectory(prefix="codewhale-persistence-backlog-") as root:
106 receipt_path = Path(root) / "receipt.json"
107 env = os.environ.copy()
108 env["CARGO_NET_OFFLINE"] = "true"
109 env[RECEIPT_ENV] = str(receipt_path)
110 env[SOURCE_SHA_ENV] = source_sha
111 env[SOURCE_DIRTY_ENV] = str(source_dirty).lower()
112 env[RUSTC_VERSION_ENV] = rustc_version
113 env[CARGO_VERSION_ENV] = cargo_version
114 try:
115 receipt = run_measurement(receipt_path, env)
116 except subprocess.CalledProcessError as error:
117 return error.returncode
118 except PersistenceBacklogMeasurementError as error:
119 sys.stderr.write(f"invalid persistence backlog receipt: {error}\n")
120 return 1
121
122 print(json.dumps(receipt, indent=2, sort_keys=True))
123 return 0
124
125
126 if __name__ == "__main__":
127 raise SystemExit(main())
128
128 lines PYTHON