Skip to content

Commit 03749fe

Browse files
committed
enhance(test-benchmark): use config file for fixed opcode count scenarios
1 parent b6553ba commit 03749fe

File tree

2 files changed

+328
-12
lines changed

2 files changed

+328
-12
lines changed

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

Lines changed: 71 additions & 12 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,15 +50,48 @@ 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-
"""Remove non-repricing tests when --fixed-opcode-count is specified."""
82+
"""Remove non-repricing tests when `--fixed-opcode-count` is specified."""
4883
fixed_opcode_count = config.getoption("fixed_opcode_count")
49-
if not fixed_opcode_count:
50-
# If --fixed-opcode-count is not specified, don't filter anything
84+
85+
# Only filter if --fixed-opcode-count flag was provided (with or without value)
86+
if fixed_opcode_count is None:
5187
return
5288

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]
94+
5395
filtered = []
5496
for item in items:
5597
if not item.get_closest_marker("benchmark"):
@@ -79,10 +121,10 @@ def pytest_collection_modifyitems(
79121
def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
80122
"""Generate tests for the gas benchmark values and fixed opcode counts."""
81123
gas_benchmark_values = metafunc.config.getoption("gas_benchmark_value")
82-
fixed_opcode_counts = metafunc.config.getoption("fixed_opcode_count")
124+
fixed_opcode_counts_cli = metafunc.config.getoption("fixed_opcode_count")
83125

84126
# Ensure mutual exclusivity
85-
if gas_benchmark_values and fixed_opcode_counts:
127+
if gas_benchmark_values and fixed_opcode_counts_cli:
86128
raise pytest.UsageError(
87129
"--gas-benchmark-values and --fixed-opcode-count are mutually exclusive. "
88130
"Use only one at a time."
@@ -110,16 +152,32 @@ def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
110152
metafunc.definition.get_closest_marker("repricing") is not None
111153
)
112154
if has_repricing:
113-
if fixed_opcode_counts:
114-
opcode_counts = [
115-
int(x.strip()) for x in fixed_opcode_counts.split(",")
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(",")
116161
]
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:
117175
opcode_count_parameters = [
118176
pytest.param(
119177
opcode_count,
120178
id=f"opcount_{opcode_count}K",
121179
)
122-
for opcode_count in opcode_counts
180+
for opcode_count in opcode_counts_to_use
123181
]
124182
metafunc.parametrize(
125183
"fixed_opcode_count",
@@ -134,8 +192,9 @@ def gas_benchmark_value(request: pytest.FixtureRequest) -> int:
134192
if hasattr(request, "param"):
135193
return request.param
136194

137-
# If --fixed-opcode-count is specified, use high gas limit to avoid gas constraints
138-
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:
139198
return HIGH_GAS_LIMIT
140199

141200
return EnvironmentDefaults.gas_limit

0 commit comments

Comments
 (0)