Skip to content

Commit c438f8d

Browse files
authored
Refactor pytest config + add default dump dir option
Differential Revision: D65481575 Pull Request resolved: #6637
1 parent 179d495 commit c438f8d

File tree

2 files changed

+88
-5
lines changed

2 files changed

+88
-5
lines changed

backends/arm/test/common.py

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
import subprocess
1212
import sys
1313
import tempfile
14+
from datetime import datetime
15+
from enum import auto, Enum
16+
from pathlib import Path
17+
from typing import Any
1418

1519
import pytest
1620

@@ -19,27 +23,46 @@
1923
from executorch.backends.arm.arm_backend import ArmCompileSpecBuilder
2024
from executorch.exir.backend.compile_spec_schema import CompileSpec
2125

22-
_enabled_options: list[str] = []
26+
27+
class arm_test_options(Enum):
28+
quantize_io = auto()
29+
corstone300 = auto()
30+
dump_path = auto()
31+
date_format = auto()
32+
33+
34+
_test_options: dict[arm_test_options, Any] = {}
2335

2436
# ==== Pytest hooks ====
2537

2638

2739
def pytest_addoption(parser):
2840
parser.addoption("--arm_quantize_io", action="store_true")
2941
parser.addoption("--arm_run_corstone300", action="store_true")
42+
parser.addoption("--default_dump_path", default=None)
43+
parser.addoption("--date_format", default="%d-%b-%H:%M:%S")
3044

3145

3246
def pytest_configure(config):
3347
if config.option.arm_quantize_io:
3448
load_libquantized_ops_aot_lib()
35-
_enabled_options.append("quantize_io")
49+
_test_options[arm_test_options.quantize_io] = True
3650
if config.option.arm_run_corstone300:
3751
corstone300_exists = shutil.which("FVP_Corstone_SSE-300_Ethos-U55")
3852
if not corstone300_exists:
3953
raise RuntimeError(
4054
"Tests are run with --arm_run_corstone300 but corstone300 FVP is not installed."
4155
)
42-
_enabled_options.append("corstone300")
56+
_test_options[arm_test_options.corstone300] = True
57+
if config.option.default_dump_path:
58+
dump_path = Path(config.option.default_dump_path).expanduser()
59+
if dump_path.exists() and os.path.isdir(dump_path):
60+
_test_options[arm_test_options.dump_path] = dump_path
61+
else:
62+
raise RuntimeError(
63+
f"Supplied argument 'default_dump_path={dump_path}' that does not exist or is not a directory."
64+
)
65+
_test_options[arm_test_options.date_format] = config.option.date_format
4366
logging.basicConfig(level=logging.INFO, stream=sys.stdout)
4467

4568

@@ -54,6 +77,18 @@ def pytest_collection_modifyitems(config, items):
5477
item.add_marker(skip_if_aot_lib_not_loaded)
5578

5679

80+
def pytest_sessionstart(session):
81+
pass
82+
83+
84+
def pytest_sessionfinish(session, exitstatus):
85+
if get_option(arm_test_options.dump_path):
86+
_clean_dir(
87+
get_option(arm_test_options.dump_path),
88+
f"ArmTester_{get_option(arm_test_options.date_format)}.log",
89+
)
90+
91+
5792
# ==== End of Pytest hooks =====
5893

5994

@@ -76,7 +111,9 @@ def load_libquantized_ops_aot_lib():
76111
torch.ops.load_library(library_path)
77112

78113

79-
def is_option_enabled(option: str, fail_if_not_enabled: bool = False) -> bool:
114+
def is_option_enabled(
115+
option: str | arm_test_options, fail_if_not_enabled: bool = False
116+
) -> bool:
80117
"""
81118
Returns whether an option is successfully enabled, i.e. if the flag was
82119
given to pytest and the necessary requirements are available.
@@ -87,7 +124,10 @@ def is_option_enabled(option: str, fail_if_not_enabled: bool = False) -> bool:
87124
The optional parameter 'fail_if_not_enabled' makes the function raise
88125
a RuntimeError instead of returning False.
89126
"""
90-
if option.lower() in _enabled_options:
127+
if isinstance(option, str):
128+
option = arm_test_options[option.lower()]
129+
130+
if option in _test_options and _test_options[option]:
91131
return True
92132
else:
93133
if fail_if_not_enabled:
@@ -96,6 +136,12 @@ def is_option_enabled(option: str, fail_if_not_enabled: bool = False) -> bool:
96136
return False
97137

98138

139+
def get_option(option: arm_test_options) -> Any | None:
140+
if option in _test_options:
141+
return _test_options[option]
142+
return None
143+
144+
99145
def maybe_get_tosa_collate_path() -> str | None:
100146
"""
101147
Checks the environment variable TOSA_TESTCASES_BASE_PATH and returns the
@@ -219,3 +265,32 @@ def get_u85_compile_spec_unbuilt(
219265
.dump_intermediate_artifacts_to(artifact_path)
220266
)
221267
return compile_spec
268+
269+
270+
def current_time_formated() -> str:
271+
"""Return current time as a formated string"""
272+
return datetime.now().strftime(get_option(arm_test_options.date_format))
273+
274+
275+
def _clean_dir(dir: Path, filter: str, num_save=10):
276+
sorted_files: list[tuple[datetime, Path]] = []
277+
for file in dir.iterdir():
278+
try:
279+
creation_time = datetime.strptime(file.name, filter)
280+
insert_index = -1
281+
for i, to_compare in enumerate(sorted_files):
282+
compare_time = to_compare[0]
283+
if creation_time < compare_time:
284+
insert_index = i
285+
break
286+
if insert_index == -1 and len(sorted_files) < num_save:
287+
sorted_files.append((creation_time, file))
288+
else:
289+
sorted_files.insert(insert_index, (creation_time, file))
290+
except ValueError:
291+
continue
292+
293+
if len(sorted_files) > num_save:
294+
for remove in sorted_files[0 : len(sorted_files) - num_save]:
295+
file = remove[1]
296+
file.unlink()

backends/arm/test/tester/arm_tester.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
ArmQuantizer,
2323
get_symmetric_quantization_config,
2424
)
25+
from executorch.backends.arm.test.common import (
26+
arm_test_options,
27+
current_time_formated,
28+
get_option,
29+
)
2530

2631
from executorch.backends.arm.test.runner_utils import (
2732
_get_input_quantization_params,
@@ -575,6 +580,9 @@ def _get_tosa_operator_distribution(
575580

576581

577582
def _dump_str(to_print: str, path_to_dump: Optional[str] = None):
583+
default_dump_path = get_option(arm_test_options.dump_path)
584+
if not path_to_dump and default_dump_path:
585+
path_to_dump = default_dump_path / f"ArmTester_{current_time_formated()}.log"
578586
if path_to_dump:
579587
with open(path_to_dump, "a") as fp:
580588
fp.write(to_print)

0 commit comments

Comments
 (0)