Skip to content

Commit 033ca8f

Browse files
committed
tests: optimize a/b test fixture
In the previous implementation, git clone executed for each parameter of the parametize test. This has a large overhead, adjusted it so that fixtures only called once per class. Signed-off-by: Tomoya Iwata <iwata.tomoya@classmethod.jp>
1 parent d42d39f commit 033ca8f

File tree

2 files changed

+55
-11
lines changed

2 files changed

+55
-11
lines changed

tests/framework/ab_test.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
does not block PRs). If not, it fails, preventing PRs from introducing new vulnerable dependencies.
2323
"""
2424
import statistics
25-
from pathlib import Path
25+
from pathlib import Path, PosixPath
2626
from tempfile import TemporaryDirectory
27-
from typing import Callable, List, Optional, TypeVar
27+
from typing import Callable, Generator, List, Optional, Tuple, TypeVar
2828

2929
import scipy
3030

@@ -98,6 +98,32 @@ def git_ab_test(
9898
return result_a, result_b, comparison
9999

100100

101+
def git_clone_ab_dirs(
102+
a_revision: str = DEFAULT_A_REVISION,
103+
b_revision: Optional[str] = None,
104+
) -> Generator[Tuple[PosixPath, PosixPath], None, None]:
105+
"""
106+
Prepare cloned Git repository to run A/B tests.
107+
108+
:param a_revision: The revision to checkout for the "A" part of the test. Defaults to the pull request target branch
109+
if run in CI, and "main" otherwise.
110+
:param b_revision: The git revision to check out for "B" part of the test. Defaults to whatever is currently checked
111+
out (in which case no temporary directory will be created).
112+
"""
113+
114+
with TemporaryDirectory() as tmp_dir:
115+
dir_a = git_clone(Path(tmp_dir) / a_revision, a_revision)
116+
117+
if b_revision:
118+
dir_b = git_clone(Path(tmp_dir) / b_revision, b_revision)
119+
else:
120+
# By default, pytest execution happens inside the `tests` subdirectory. Pass the repository root, as
121+
# documented.
122+
dir_b = Path.cwd().parent
123+
124+
yield (dir_a, dir_b)
125+
126+
101127
DEFAULT_A_DIRECTORY = FC_WORKSPACE_DIR / "build" / "main"
102128
DEFAULT_B_DIRECTORY = FC_WORKSPACE_DIR / "build" / "cargo_target" / DEFAULT_TARGET_DIR
103129

tests/integration_tests/performance/test_benchmarks.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
import pytest
1313

1414
from framework import utils
15-
from framework.ab_test import git_ab_test
15+
from framework.ab_test import binary_ab_test, git_clone_ab_dirs
1616
from host_tools.cargo_build import cargo
1717

1818
LOGGER = logging.getLogger(__name__)
19+
git_clone_ab_dirs_one_time = pytest.fixture(git_clone_ab_dirs, scope="class")
1920

2021

2122
def get_benchmark_names() -> List[str]:
@@ -39,16 +40,33 @@ def get_benchmark_names() -> List[str]:
3940
return list(set(benchmark_names))
4041

4142

42-
@pytest.mark.no_block_pr
43-
@pytest.mark.parametrize("benchname", get_benchmark_names())
44-
def test_no_regression_relative_to_target_branch(benchname):
43+
class TestBenchMarks:
4544
"""
46-
Run the microbenchmarks in this repository, comparing results from pull
47-
request target branch against what's achieved on HEAD
45+
This class is used to prevent fixtures from being executed for each parameter in
46+
a parametrize test.
4847
"""
49-
run_criterion = get_run_criterion(benchname)
50-
compare_results = get_compare_results(benchname)
51-
git_ab_test(run_criterion, compare_results)
48+
49+
@pytest.mark.no_block_pr
50+
@pytest.mark.parametrize("benchname", get_benchmark_names())
51+
def test_no_regression_relative_to_target_branch(
52+
self, benchname, git_clone_ab_dirs_one_time
53+
):
54+
"""
55+
Run the microbenchmarks in this repository, comparing results from pull
56+
request target branch against what's achieved on HEAD
57+
"""
58+
59+
dir_a = git_clone_ab_dirs_one_time[0]
60+
dir_b = git_clone_ab_dirs_one_time[1]
61+
run_criterion = get_run_criterion(benchname)
62+
compare_results = get_compare_results(benchname)
63+
64+
binary_ab_test(
65+
test_runner=run_criterion,
66+
comparator=compare_results,
67+
a_directory=dir_a,
68+
b_directory=dir_b,
69+
)
5270

5371

5472
def get_run_criterion(benchmark_name) -> Callable[[Path, bool], Path]:

0 commit comments

Comments
 (0)