Files
rustfs/scripts/test_summarize_scanner_heal_perf.py
T
houseme 807f85cbd7 test: summarize scanner heal perf artifacts (#7426)
* test: summarize scanner heal perf artifacts

Add a quiet Scanner/Heal performance artifact summarizer that normalizes ABBA report verdicts, key regression metrics, cache-cost profile records, and provenance hashes for CI or PR handoff.

Document the summary command in the scanner benchmark runbook and cover measured, synthetic, pending, and invalid cache-cost paths with focused Python tests.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(error): merge equivalent api message branches

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>

* fix(heal): cleanup consumed MRF replay journals

Do not retain Accepted or Merged replay intents as startup anchors after they have been handed to the heal manager. Only refused or still-pending replay records keep the journal on disk until a successor snapshot can persist them.

This keeps successor snapshots limited to the pending queue, which lets successful replay remove both authoritative and legacy journal paths and restores the crash-boundary tests around successor flush.

Co-Authored-By: heihutu <heihutu@gmail.com>

Co-Authored-By: zhi22915 <qiuzgang@gmail.com>
(cherry picked from commit d5b8f49c9d)

---------

Co-authored-by: zhi22915 <qiuzgang@gmail.com>
Co-authored-by: Zhengchao An <anzhengchao@gmail.com>
2026-09-08 07:21:45 +08:00

172 lines
6.3 KiB
Python
Executable File

#!/usr/bin/env python3
from __future__ import annotations
import contextlib
import hashlib
import io
import json
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parent))
import summarize_scanner_heal_perf as summary
def sha(path: Path) -> str:
with path.open("rb") as stream:
hasher = hashlib.sha256()
while chunk := stream.read(1024 * 1024):
hasher.update(chunk)
return hasher.hexdigest()
class ScannerHealPerfSummaryTest(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.addCleanup(self.temp.cleanup)
self.root = Path(self.temp.name)
self.abba = self.root / "abba"
self.abba.mkdir()
self.manifest = {
"fixed": {
"config_sha256": "1" * 64,
"dataset_sha256": "2" * 64,
"release_flags": "--profile production",
"durability": "drive-sync=on",
"topology": "EC8+4",
"offered_load_ops": 100,
},
"baseline": {"revision": "a" * 40, "sha256": "3" * 64},
"candidate": {"revision": "b" * 40, "sha256": "4" * 64},
"adapter_sha256": "5" * 64,
"collector_sha256": "6" * 64,
}
self.comparison = {
"scenario": "cold-hot",
"comparison": "build",
"round": 1,
"status": "pass",
"p99_regression": 0.02,
"throughput_change": -0.01,
"p1": {"required_reduction": 0.8, "observed_reduction": 0.82, "repeatability_drift": 0.01},
"p2_post_stop_work_multiples": [None, 1.1, 1.0, None],
}
self.report = {
"status": "pass",
"performance": "pass",
"evidence": "measured",
"cells": 120,
"comparisons": [self.comparison],
}
self.write_inputs()
def write_inputs(self):
(self.abba / "manifest.json").write_text(json.dumps(self.manifest), encoding="utf-8")
(self.abba / "report.json").write_text(json.dumps(self.report), encoding="utf-8")
def test_measured_pass_writes_quiet_artifacts(self):
cache_log = self.root / "cache.log"
cache_log.write_text(
"compiler noise\nCACHE_COST "
+ json.dumps({
"schema": 1,
"scenario": "small_dirty",
"cache_wire_bytes": 100,
"save_body_bytes_per_sample": 200,
"clone": {"max_ns": 10},
"encode": {"max_ns": 20},
"save_inclusive": {"max_ns": 30},
"build": {"source_revision": "abc", "source_tree": "clean", "test_opt_level_override": "0"},
})
+ "\nmore noise\n",
encoding="utf-8",
)
args = type("Args", (), {
"abba_dir": self.abba,
"cache_cost_log": cache_log,
"require_cache_cost": False,
"json_out": None,
"markdown_out": None,
})
result = summary.build_summary(args)
self.assertEqual(result["verdict"], "PASS")
self.assertEqual(result["abba"]["provenance"]["manifest_sha256"], sha(self.abba / "manifest.json"))
self.assertEqual(result["cache_cost"]["max_save_body_amplification"], 2.0)
def test_synthetic_report_fails_as_performance_conclusion(self):
self.report.update(status="synthetic_validated", performance="pending", evidence="synthetic")
self.write_inputs()
args = type("Args", (), {
"abba_dir": self.abba,
"cache_cost_log": None,
"require_cache_cost": False,
"json_out": None,
"markdown_out": None,
})
result = summary.build_summary(args)
self.assertEqual(result["verdict"], "FAIL")
self.assertIn("synthetic evidence", result["reason"])
def test_requires_cache_profile_when_requested(self):
args = type("Args", (), {
"abba_dir": self.abba,
"cache_cost_log": None,
"require_cache_cost": True,
"json_out": None,
"markdown_out": None,
})
with self.assertRaisesRegex(ValueError, "cache-cost profile log is required"):
summary.build_summary(args)
def test_cli_prints_one_line_and_exits_nonzero_for_pending_performance(self):
self.report.update(status="inconclusive", performance="inconclusive")
self.write_inputs()
stdout = io.StringIO()
stderr = io.StringIO()
argv = [
"summarize_scanner_heal_perf.py",
"--abba-dir",
str(self.abba),
"--json-out",
str(self.root / "summary.json"),
"--markdown-out",
str(self.root / "summary.md"),
]
with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):
with mock.patch.object(sys, "argv", argv):
code = summary.main()
self.assertEqual(code, 1)
self.assertEqual(stdout.getvalue().count("\n"), 1)
self.assertTrue(stdout.getvalue().startswith("FAIL scanner_heal_perf "))
self.assertEqual(stderr.getvalue(), "")
self.assertEqual(summary.read_json(self.root / "summary.json")["verdict"], "FAIL")
self.assertIn("worst_p99_regression", (self.root / "summary.md").read_text(encoding="utf-8"))
def test_invalid_cache_cost_lines_fail_closed(self):
cache_log = self.root / "cache.log"
cache_log.write_text("CACHE_COST {\"schema\": 2}\n", encoding="utf-8")
with self.assertRaisesRegex(ValueError, "unsupported schema"):
summary.summarize_cache_cost(cache_log)
def test_script_entrypoint_is_quiet(self):
script = Path(__file__).with_name("summarize_scanner_heal_perf.py")
process = subprocess.run(
[sys.executable, str(script), "--abba-dir", str(self.abba)],
check=False,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self.assertEqual(process.returncode, 0, process.stderr)
self.assertEqual(process.stdout.count("\n"), 1)
self.assertEqual(process.stderr, "")
if __name__ == "__main__":
unittest.main()