# HG changeset patch # User Raphaël Gomès <rgomes@octobus.net> # Date 1644665346 -3600 # Sat Feb 12 12:29:06 2022 +0100 # Node ID 00db05de2ad35e559ba96d63ff877a8faf8531f7 # Parent 82eff314a61ed13b14b221f47ea5371864063a75 # EXP-Topic questions-answer Add a command to get answers to our most common questions diff --git a/bin/get-answers b/bin/get-answers new file mode 100755 --- /dev/null +++ b/bin/get-answers @@ -0,0 +1,146 @@ +#!/usr/bin/env python3 +# Get answers to the most common questions we have +# quick check: +# for question in 0 1 2 3 4 5 6 7 8 9 10 11 12; do for repo in 0 1 2; do bin/get-answers results-percheron $question $repo; done; done + +from argparse import ArgumentParser +import argparse +from pathlib import Path +import subprocess +import sys + + +repos = ["mozilla", "netbeans", "mercurial"] + +DIFF = str(Path(__file__).parent / "diff-result") + +K_JANE_D1 = ( + "Jane fast-path dirstate-v1", + "result-mercurial-f87e5257eeb1-jane--{repo}-dirstate-v1*", +) +K_JANE_NO_CACHE = ( + "Jane fast-path dirstate-v1 (no cache)", + "result-mercurial-c7e675848027-jane--{repo}-dirstate-v1*", +) +K_RHG_D2 = ("rhg dirstate-v2", "result-mercurial-18b212b00ee0-rhg--{repo}-dirstate-v2*") +K_RHG_D2_REL_PATH = ( + "rhg dirstate-v2 (relpaths)", + "result-mercurial-f87e5257eeb1-rhg--{repo}-dirstate-v2*", +) +K_RHG_D2_REL_PATH_NO_CACHE = ( + "rhg dirstate-v2 (relpaths, no cache)", + "result-mercurial-93b4d58a1bfc-rhg--{repo}-dirstate-v2*", +) +K_HG_D1_RUST = ( + "hg dirstate-v1 rust", + "result-mercurial-02e9ad08999b-rust--{repo}-dirstate-v1*", +) +K_HG_D1_NORUST = ( + "hg dirstate-v1 no-rust", + "result-mercurial-02e9ad08999b-no-rust--{repo}-dirstate-v1*", +) +K_HG_D1_NORUST_OLD = ( + "dirstate-v1 no-rust (old 5.4)", + "result-mercurial-5.4.2-no-rust--{repo}-dirstate-v1*", +) +K_HG_D2_RUST = ( + "hg dirstate-v2 rust", + "result-mercurial-02e9ad08999b-rust--{repo}-dirstate-v2*", +) +K_HG_D2_NORUST = ( + "hg dirstate-v2 no-rust", + "result-mercurial-b528861ebfdc-no-rust--{repo}-dirstate-v2*", +) + +QUESTIONS = [ + (K_JANE_D1, K_RHG_D2), + (K_HG_D2_NORUST, K_RHG_D2), + (K_HG_D1_NORUST, K_RHG_D2), + (K_HG_D2_RUST, K_RHG_D2), + (K_HG_D1_RUST, K_RHG_D2), + (K_HG_D1_NORUST_OLD, K_HG_D1_NORUST), + (K_HG_D1_NORUST, K_HG_D2_NORUST), + (K_HG_D1_NORUST, K_HG_D1_RUST), + (K_HG_D1_RUST, K_HG_D2_RUST), + (K_HG_D1_NORUST, K_HG_D2_RUST), + (K_JANE_D1, K_RHG_D2_REL_PATH), + (K_JANE_NO_CACHE, K_RHG_D2_REL_PATH_NO_CACHE), + (K_RHG_D2_REL_PATH, K_RHG_D2_REL_PATH_NO_CACHE), +] + + +def print_err(msg): + print(msg, file=sys.stderr) + + +def show_comparison(results_dir: Path, question_index: int, repo_index: int): + repo = repos[repo_index] + + (left_name, left_glob), (right_name, right_glob) = QUESTIONS[question_index] + + question = f"{left_name} vs {right_name}" + results_left = sorted(results_dir.glob(left_glob.format(repo=repo))) + results_right = sorted(results_dir.glob(right_glob.format(repo=repo))) + + header = f"Results for {question} in repo {repo}" + print("=" * len(header)) + print(header) + print("=" * len(header)) + if not results_left: + print_err(f"No results for the left") + sys.exit(1) + if not results_right: + print_err(f"No results for the right") + sys.exit(1) + for left, right in zip(results_left, results_right): + bench = str(left).rsplit("--", 1)[1] + assert bench == str(right).rsplit("--", 1)[1] + cmd = [DIFF, str(left), str(right)] + res = subprocess.run(cmd, capture_output=True) + bench = bench.removesuffix(".pbr") + if res.returncode != 0: + print_err(f"{bench} returned error code {res.returncode}") + continue + print(f"{bench:<50} {res.stdout.strip().decode()}") + + +def main(results_dir, question_index, repo_index): + if question_index < 0 or question_index > len(QUESTIONS) - 1: + print_err("Please input a valid question index") + sys.exit(1) + if repo_index < 0 or repo_index > len(repos) - 1: + print_err("Please input a valid repo index") + sys.exit(1) + results_dir = Path(results_dir) + if not results_dir.is_dir(): + print_err("The results dir must be a directory") + sys.exit(1) + show_comparison(results_dir, question_index, repo_index) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument( + "results_dir", + action="store", + type=str, + help="Path to a directory containing the results", + ) + parser.add_argument( + "question", + action="store", + type=int, + help="\n".join(f"{i}: {l[0]} vs {r[0]}" for i, (l, r) in enumerate(QUESTIONS)), + ) + parser.add_argument( + "repo", + action="store", + type=int, + help="\n".join(f"{i}: {r}" for i, r in enumerate(repos)), + ) + if len(sys.argv) < 4: + parser.print_help() + sys.exit(1) + + args = parser.parse_args() + main(args.results_dir, args.question, args.repo)