Skip to content

Commit 22c1e6c

Browse files
committed
enhance(test-benchmark): use config file for fixed opcode count scenarios
1 parent 5d28db5 commit 22c1e6c

File tree

2 files changed

+342
-27
lines changed

2 files changed

+342
-27
lines changed

packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/benchmarking.py

Lines changed: 85 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
"""The module contains the pytest hooks for the gas benchmark values."""
22

3+
import importlib.util
4+
import sys
5+
from pathlib import Path
6+
37
import pytest
48

59
from execution_testing.test_types import Environment, EnvironmentDefaults
@@ -26,7 +30,12 @@ def pytest_addoption(parser: pytest.Parser) -> None:
2630
dest="fixed_opcode_count",
2731
type=str,
2832
default=None,
29-
help="Specify fixed opcode counts (in thousands) for benchmark tests as a comma-separated list.",
33+
nargs="?",
34+
const="",
35+
help=(
36+
"Specify fixed opcode counts (in thousands) for benchmark tests as a comma-separated list. "
37+
"If provided without a value, uses defaults from tests/benchmark/configs/fixed_opcode_counts.py."
38+
),
3039
)
3140

3241

@@ -41,20 +50,47 @@ def pytest_configure(config: pytest.Config) -> None:
4150
config.op_mode = OpMode.BENCHMARKING # type: ignore[attr-defined]
4251

4352

53+
def _load_opcode_counts_config(config: pytest.Config) -> dict[str, list[int]] | None:
54+
"""
55+
Load the opcode counts configuration from `tests/benchmark/configs/fixed_opcode_counts.py`.
56+
57+
Returns dictionary mapping scenario IDs to opcode counts, or None if config not found.
58+
"""
59+
config_path = Path(config.rootpath) / "tests" / "benchmark" / "configs" / "fixed_opcode_counts.py"
60+
61+
if not config_path.exists():
62+
return None
63+
64+
# Load the module dynamically
65+
spec = importlib.util.spec_from_file_location("fixed_opcode_counts", config_path)
66+
if spec is None or spec.loader is None:
67+
return None
68+
69+
module = importlib.util.module_from_spec(spec)
70+
sys.modules["fixed_opcode_counts"] = module
71+
spec.loader.exec_module(module)
72+
73+
return {
74+
"scenario_counts": getattr(module, "SCENARIO_OPCODE_COUNTS", {}),
75+
"default_counts": getattr(module, "DEFAULT_OPCODE_COUNTS", [100, 500, 1000]),
76+
}
77+
78+
4479
def pytest_collection_modifyitems(
4580
config: pytest.Config, items: list[pytest.Item]
4681
) -> None:
47-
"""Filter tests based on repricing marker"""
48-
gas_benchmark_value = config.getoption("gas_benchmark_value")
82+
"""Remove non-repricing tests when `--fixed-opcode-count` is specified."""
4983
fixed_opcode_count = config.getoption("fixed_opcode_count")
5084

51-
if not gas_benchmark_value and not fixed_opcode_count:
85+
# Only filter if --fixed-opcode-count flag was provided (with or without value)
86+
if fixed_opcode_count is None:
5287
return
5388

54-
# Check if -m repricing marker filter was specified
55-
markexpr = config.getoption("markexpr", "")
56-
if "repricing" not in markexpr:
57-
return
89+
# Load config data if flag provided without value (empty string)
90+
if fixed_opcode_count == "":
91+
config_data = _load_opcode_counts_config(config)
92+
if config_data:
93+
config._opcode_counts_config = config_data # type: ignore[attr-defined]
5894

5995
filtered = []
6096
for item in items:
@@ -85,10 +121,10 @@ def pytest_collection_modifyitems(
85121
def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
86122
"""Generate tests for the gas benchmark values and fixed opcode counts."""
87123
gas_benchmark_values = metafunc.config.getoption("gas_benchmark_value")
88-
fixed_opcode_counts = metafunc.config.getoption("fixed_opcode_count")
124+
fixed_opcode_counts_cli = metafunc.config.getoption("fixed_opcode_count")
89125

90126
# Ensure mutual exclusivity
91-
if gas_benchmark_values and fixed_opcode_counts:
127+
if gas_benchmark_values and fixed_opcode_counts_cli:
92128
raise pytest.UsageError(
93129
"--gas-benchmark-values and --fixed-opcode-count are mutually exclusive. "
94130
"Use only one at a time."
@@ -111,22 +147,43 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
111147
)
112148

113149
if "fixed_opcode_count" in metafunc.fixturenames:
114-
if fixed_opcode_counts:
115-
opcode_counts = [
116-
int(x.strip()) for x in fixed_opcode_counts.split(",")
117-
]
118-
opcode_count_parameters = [
119-
pytest.param(
120-
opcode_count,
121-
id=f"opcount_{opcode_count}K",
150+
# Only parametrize if test has repricing marker
151+
has_repricing = (
152+
metafunc.definition.get_closest_marker("repricing") is not None
153+
)
154+
if has_repricing:
155+
opcode_counts_to_use = None
156+
157+
if fixed_opcode_counts_cli and fixed_opcode_counts_cli != "":
158+
# CLI flag with value takes precedence
159+
opcode_counts_to_use = [
160+
int(x.strip()) for x in fixed_opcode_counts_cli.split(",")
161+
]
162+
elif fixed_opcode_counts_cli == "":
163+
# Flag provided without value - load from config file
164+
config_data = getattr(
165+
metafunc.config, "_opcode_counts_config", None
166+
)
167+
if config_data:
168+
default_counts = config_data.get(
169+
"default_counts", [100] # Default to 100k for all.
170+
)
171+
opcode_counts_to_use = default_counts
172+
173+
# Parametrize if we have counts to use
174+
if opcode_counts_to_use:
175+
opcode_count_parameters = [
176+
pytest.param(
177+
opcode_count,
178+
id=f"opcount_{opcode_count}K",
179+
)
180+
for opcode_count in opcode_counts_to_use
181+
]
182+
metafunc.parametrize(
183+
"fixed_opcode_count",
184+
opcode_count_parameters,
185+
scope="function",
122186
)
123-
for opcode_count in opcode_counts
124-
]
125-
metafunc.parametrize(
126-
"fixed_opcode_count",
127-
opcode_count_parameters,
128-
scope="function",
129-
)
130187

131188

132189
@pytest.fixture(scope="function")
@@ -135,8 +192,9 @@ def gas_benchmark_value(request: pytest.FixtureRequest) -> int:
135192
if hasattr(request, "param"):
136193
return request.param
137194

138-
# If --fixed-opcode-count is specified, use high gas limit to avoid gas constraints
139-
if request.config.getoption("fixed_opcode_count"):
195+
# Only use high gas limit if --fixed-opcode-count flag was provided
196+
fixed_opcode_count = request.config.getoption("fixed_opcode_count")
197+
if fixed_opcode_count is not None:
140198
return HIGH_GAS_LIMIT
141199

142200
return EnvironmentDefaults.gas_limit

0 commit comments

Comments
 (0)