view contrib/perf-utils/compare-discovery-case @ 49338:4b239acb23a0

auto-upgrade: add a test that will host "quiet" testing We will add options to suppress the message in the coming changeset. The changes will be clearer if the full test is already in place.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 14 Jun 2022 15:45:37 +0200
parents a78c45a22ce4
children df1d4e442c08
line wrap: on
line source

#!/usr/bin/env python3
# compare various algorithm variants for a given case
#
#  search-discovery-case REPO LOCAL_CASE REMOTE_CASE
#
# The description for the case input uses the same format as the ouput of
# search-discovery-case

import json
import os
import subprocess
import sys

this_script = os.path.abspath(sys.argv[0])
script_name = os.path.basename(this_script)
this_dir = os.path.dirname(this_script)
hg_dir = os.path.join(this_dir, '..', '..')
HG_REPO = os.path.normpath(hg_dir)
HG_BIN = os.path.join(HG_REPO, 'hg')


SUBSET_PATH = os.path.join(HG_REPO, 'contrib', 'perf-utils', 'subsetmaker.py')

CMD_BASE = (
    HG_BIN,
    'debugdiscovery',
    '--template',
    'json',
    '--config',
    'extensions.subset=%s' % SUBSET_PATH,
)

# --old
# --nonheads
#
# devel.discovery.exchange-heads=True
# devel.discovery.grow-sample=True
# devel.discovery.grow-sample.dynamic=True

VARIANTS = {
    'tree-discovery': ('--old',),
    'set-discovery-basic': (
        '--config',
        'devel.discovery.exchange-heads=no',
        '--config',
        'devel.discovery.grow-sample=no',
        '--config',
        'devel.discovery.grow-sample.dynamic=no',
        '--config',
        'devel.discovery.randomize=yes',
    ),
    'set-discovery-heads': (
        '--config',
        'devel.discovery.exchange-heads=yes',
        '--config',
        'devel.discovery.grow-sample=no',
        '--config',
        'devel.discovery.grow-sample.dynamic=no',
        '--config',
        'devel.discovery.randomize=yes',
    ),
    'set-discovery-grow-sample': (
        '--config',
        'devel.discovery.exchange-heads=yes',
        '--config',
        'devel.discovery.grow-sample=yes',
        '--config',
        'devel.discovery.grow-sample.dynamic=no',
        '--config',
        'devel.discovery.randomize=yes',
    ),
    'set-discovery-dynamic-sample': (
        '--config',
        'devel.discovery.exchange-heads=yes',
        '--config',
        'devel.discovery.grow-sample=yes',
        '--config',
        'devel.discovery.grow-sample.dynamic=yes',
        '--config',
        'devel.discovery.randomize=yes',
    ),
    'set-discovery-default': (
        '--config',
        'devel.discovery.randomize=yes',
    ),
}

VARIANTS_KEYS = [
    'tree-discovery',
    'set-discovery-basic',
    'set-discovery-heads',
    'set-discovery-grow-sample',
    'set-discovery-dynamic-sample',
    'set-discovery-default',
]

assert set(VARIANTS.keys()) == set(VARIANTS_KEYS)


def format_case(case):
    return '-'.join(str(s) for s in case)


def to_revsets(case):
    t = case[0]
    if t == 'scratch':
        return 'not scratch(all(), %d, "%d")' % (case[1], case[2])
    elif t == 'randomantichain':
        return '::randomantichain(all(), "%d")' % case[1]
    elif t == 'rev':
        return '::%d' % case[1]
    else:
        assert False


def compare(repo, local_case, remote_case):
    case = (repo, local_case, remote_case)
    for variant in VARIANTS_KEYS:
        res = process(case, VARIANTS[variant])
        revs = res["nb-revs"]
        local_heads = res["nb-head-local"]
        common_heads = res["nb-common-heads"]
        roundtrips = res["total-roundtrips"]
        queries = res["total-queries"]
        if 'tree-discovery' in variant:
            print(
                repo,
                format_case(local_case),
                format_case(remote_case),
                variant,
                roundtrips,
                queries,
                revs,
                local_heads,
                common_heads,
            )
        else:
            undecided_common = res["nb-ini_und-common"]
            undecided_missing = res["nb-ini_und-missing"]
            undecided = undecided_common + undecided_missing
            print(
                repo,
                format_case(local_case),
                format_case(remote_case),
                variant,
                roundtrips,
                queries,
                revs,
                local_heads,
                common_heads,
                undecided,
                undecided_common,
                undecided_missing,
            )
    return 0


def process(case, variant):
    (repo, left, right) = case
    cmd = list(CMD_BASE)
    cmd.append('-R')
    cmd.append(repo)
    cmd.append('--local-as-revs')
    cmd.append(to_revsets(left))
    cmd.append('--remote-as-revs')
    cmd.append(to_revsets(right))
    cmd.extend(variant)
    s = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    out, err = s.communicate()
    return json.loads(out)[0]


if __name__ == '__main__':
    if len(sys.argv) != 4:
        usage = f'USAGE: {script_name} REPO LOCAL_CASE REMOTE_CASE'
        print(usage, file=sys.stderr)
        sys.exit(128)
    repo = sys.argv[1]
    local_case = sys.argv[2].split('-')
    local_case = (local_case[0],) + tuple(int(x) for x in local_case[1:])
    remote_case = sys.argv[3].split('-')
    remote_case = (remote_case[0],) + tuple(int(x) for x in remote_case[1:])
    sys.exit(compare(repo, local_case, remote_case))