1*523fa7a6SAndroid Build Coastguard Worker# Copyright 2024 Arm Limited and/or its affiliates. 2*523fa7a6SAndroid Build Coastguard Worker# All rights reserved. 3*523fa7a6SAndroid Build Coastguard Worker# 4*523fa7a6SAndroid Build Coastguard Worker# This source code is licensed under the BSD-style license found in the 5*523fa7a6SAndroid Build Coastguard Worker# LICENSE file in the root directory of this source tree. 6*523fa7a6SAndroid Build Coastguard Worker 7*523fa7a6SAndroid Build Coastguard Workerimport logging 8*523fa7a6SAndroid Build Coastguard Workerimport os 9*523fa7a6SAndroid Build Coastguard Workerimport platform 10*523fa7a6SAndroid Build Coastguard Workerimport shutil 11*523fa7a6SAndroid Build Coastguard Workerimport subprocess 12*523fa7a6SAndroid Build Coastguard Workerimport sys 13*523fa7a6SAndroid Build Coastguard Workerimport tempfile 14*523fa7a6SAndroid Build Coastguard Workerfrom datetime import datetime 15*523fa7a6SAndroid Build Coastguard Workerfrom enum import auto, Enum 16*523fa7a6SAndroid Build Coastguard Workerfrom pathlib import Path 17*523fa7a6SAndroid Build Coastguard Workerfrom typing import Any 18*523fa7a6SAndroid Build Coastguard Worker 19*523fa7a6SAndroid Build Coastguard Workerimport pytest 20*523fa7a6SAndroid Build Coastguard Worker 21*523fa7a6SAndroid Build Coastguard Workerimport torch 22*523fa7a6SAndroid Build Coastguard Worker 23*523fa7a6SAndroid Build Coastguard Workerfrom executorch.backends.arm.arm_backend import ArmCompileSpecBuilder 24*523fa7a6SAndroid Build Coastguard Workerfrom executorch.exir.backend.compile_spec_schema import CompileSpec 25*523fa7a6SAndroid Build Coastguard Worker 26*523fa7a6SAndroid Build Coastguard Worker 27*523fa7a6SAndroid Build Coastguard Workerclass arm_test_options(Enum): 28*523fa7a6SAndroid Build Coastguard Worker quantize_io = auto() 29*523fa7a6SAndroid Build Coastguard Worker corstone300 = auto() 30*523fa7a6SAndroid Build Coastguard Worker dump_path = auto() 31*523fa7a6SAndroid Build Coastguard Worker date_format = auto() 32*523fa7a6SAndroid Build Coastguard Worker fast_fvp = auto() 33*523fa7a6SAndroid Build Coastguard Worker 34*523fa7a6SAndroid Build Coastguard Worker 35*523fa7a6SAndroid Build Coastguard Worker_test_options: dict[arm_test_options, Any] = {} 36*523fa7a6SAndroid Build Coastguard Worker 37*523fa7a6SAndroid Build Coastguard Worker# ==== Pytest hooks ==== 38*523fa7a6SAndroid Build Coastguard Worker 39*523fa7a6SAndroid Build Coastguard Worker 40*523fa7a6SAndroid Build Coastguard Workerdef pytest_addoption(parser): 41*523fa7a6SAndroid Build Coastguard Worker parser.addoption("--arm_quantize_io", action="store_true") 42*523fa7a6SAndroid Build Coastguard Worker parser.addoption("--arm_run_corstone300", action="store_true") 43*523fa7a6SAndroid Build Coastguard Worker parser.addoption("--default_dump_path", default=None) 44*523fa7a6SAndroid Build Coastguard Worker parser.addoption("--date_format", default="%d-%b-%H:%M:%S") 45*523fa7a6SAndroid Build Coastguard Worker parser.addoption("--fast_fvp", action="store_true") 46*523fa7a6SAndroid Build Coastguard Worker 47*523fa7a6SAndroid Build Coastguard Worker 48*523fa7a6SAndroid Build Coastguard Workerdef pytest_configure(config): 49*523fa7a6SAndroid Build Coastguard Worker if config.option.arm_quantize_io: 50*523fa7a6SAndroid Build Coastguard Worker load_libquantized_ops_aot_lib() 51*523fa7a6SAndroid Build Coastguard Worker _test_options[arm_test_options.quantize_io] = True 52*523fa7a6SAndroid Build Coastguard Worker if config.option.arm_run_corstone300: 53*523fa7a6SAndroid Build Coastguard Worker corstone300_exists = shutil.which("FVP_Corstone_SSE-300_Ethos-U55") 54*523fa7a6SAndroid Build Coastguard Worker if not corstone300_exists: 55*523fa7a6SAndroid Build Coastguard Worker raise RuntimeError( 56*523fa7a6SAndroid Build Coastguard Worker "Tests are run with --arm_run_corstone300 but corstone300 FVP is not installed." 57*523fa7a6SAndroid Build Coastguard Worker ) 58*523fa7a6SAndroid Build Coastguard Worker _test_options[arm_test_options.corstone300] = True 59*523fa7a6SAndroid Build Coastguard Worker if config.option.default_dump_path: 60*523fa7a6SAndroid Build Coastguard Worker dump_path = Path(config.option.default_dump_path).expanduser() 61*523fa7a6SAndroid Build Coastguard Worker if dump_path.exists() and os.path.isdir(dump_path): 62*523fa7a6SAndroid Build Coastguard Worker _test_options[arm_test_options.dump_path] = dump_path 63*523fa7a6SAndroid Build Coastguard Worker else: 64*523fa7a6SAndroid Build Coastguard Worker raise RuntimeError( 65*523fa7a6SAndroid Build Coastguard Worker f"Supplied argument 'default_dump_path={dump_path}' that does not exist or is not a directory." 66*523fa7a6SAndroid Build Coastguard Worker ) 67*523fa7a6SAndroid Build Coastguard Worker _test_options[arm_test_options.date_format] = config.option.date_format 68*523fa7a6SAndroid Build Coastguard Worker _test_options[arm_test_options.fast_fvp] = config.option.fast_fvp 69*523fa7a6SAndroid Build Coastguard Worker logging.basicConfig(level=logging.INFO, stream=sys.stdout) 70*523fa7a6SAndroid Build Coastguard Worker 71*523fa7a6SAndroid Build Coastguard Worker 72*523fa7a6SAndroid Build Coastguard Workerdef pytest_collection_modifyitems(config, items): 73*523fa7a6SAndroid Build Coastguard Worker if not config.option.arm_quantize_io: 74*523fa7a6SAndroid Build Coastguard Worker skip_if_aot_lib_not_loaded = pytest.mark.skip( 75*523fa7a6SAndroid Build Coastguard Worker "u55 tests can only run with quantize_io=True." 76*523fa7a6SAndroid Build Coastguard Worker ) 77*523fa7a6SAndroid Build Coastguard Worker 78*523fa7a6SAndroid Build Coastguard Worker for item in items: 79*523fa7a6SAndroid Build Coastguard Worker if "u55" in item.name: 80*523fa7a6SAndroid Build Coastguard Worker item.add_marker(skip_if_aot_lib_not_loaded) 81*523fa7a6SAndroid Build Coastguard Worker 82*523fa7a6SAndroid Build Coastguard Worker 83*523fa7a6SAndroid Build Coastguard Workerdef pytest_sessionstart(session): 84*523fa7a6SAndroid Build Coastguard Worker pass 85*523fa7a6SAndroid Build Coastguard Worker 86*523fa7a6SAndroid Build Coastguard Worker 87*523fa7a6SAndroid Build Coastguard Workerdef pytest_sessionfinish(session, exitstatus): 88*523fa7a6SAndroid Build Coastguard Worker if get_option(arm_test_options.dump_path): 89*523fa7a6SAndroid Build Coastguard Worker _clean_dir( 90*523fa7a6SAndroid Build Coastguard Worker get_option(arm_test_options.dump_path), 91*523fa7a6SAndroid Build Coastguard Worker f"ArmTester_{get_option(arm_test_options.date_format)}.log", 92*523fa7a6SAndroid Build Coastguard Worker ) 93*523fa7a6SAndroid Build Coastguard Worker 94*523fa7a6SAndroid Build Coastguard Worker 95*523fa7a6SAndroid Build Coastguard Worker# ==== End of Pytest hooks ===== 96*523fa7a6SAndroid Build Coastguard Worker 97*523fa7a6SAndroid Build Coastguard Worker# ==== Custom Pytest decorators ===== 98*523fa7a6SAndroid Build Coastguard Worker 99*523fa7a6SAndroid Build Coastguard Worker 100*523fa7a6SAndroid Build Coastguard Workerdef expectedFailureOnFVP(test_item): 101*523fa7a6SAndroid Build Coastguard Worker if is_option_enabled("corstone300"): 102*523fa7a6SAndroid Build Coastguard Worker test_item.__unittest_expecting_failure__ = True 103*523fa7a6SAndroid Build Coastguard Worker return test_item 104*523fa7a6SAndroid Build Coastguard Worker 105*523fa7a6SAndroid Build Coastguard Worker 106*523fa7a6SAndroid Build Coastguard Worker# ==== End of Custom Pytest decorators ===== 107*523fa7a6SAndroid Build Coastguard Worker 108*523fa7a6SAndroid Build Coastguard Worker 109*523fa7a6SAndroid Build Coastguard Workerdef load_libquantized_ops_aot_lib(): 110*523fa7a6SAndroid Build Coastguard Worker so_ext = { 111*523fa7a6SAndroid Build Coastguard Worker "Darwin": "dylib", 112*523fa7a6SAndroid Build Coastguard Worker "Linux": "so", 113*523fa7a6SAndroid Build Coastguard Worker "Windows": "dll", 114*523fa7a6SAndroid Build Coastguard Worker }.get(platform.system(), None) 115*523fa7a6SAndroid Build Coastguard Worker 116*523fa7a6SAndroid Build Coastguard Worker find_lib_cmd = [ 117*523fa7a6SAndroid Build Coastguard Worker "find", 118*523fa7a6SAndroid Build Coastguard Worker "cmake-out-aot-lib", 119*523fa7a6SAndroid Build Coastguard Worker "-name", 120*523fa7a6SAndroid Build Coastguard Worker f"libquantized_ops_aot_lib.{so_ext}", 121*523fa7a6SAndroid Build Coastguard Worker ] 122*523fa7a6SAndroid Build Coastguard Worker res = subprocess.run(find_lib_cmd, capture_output=True) 123*523fa7a6SAndroid Build Coastguard Worker if res.returncode == 0: 124*523fa7a6SAndroid Build Coastguard Worker library_path = res.stdout.decode().strip() 125*523fa7a6SAndroid Build Coastguard Worker torch.ops.load_library(library_path) 126*523fa7a6SAndroid Build Coastguard Worker 127*523fa7a6SAndroid Build Coastguard Worker 128*523fa7a6SAndroid Build Coastguard Workerdef is_option_enabled( 129*523fa7a6SAndroid Build Coastguard Worker option: str | arm_test_options, fail_if_not_enabled: bool = False 130*523fa7a6SAndroid Build Coastguard Worker) -> bool: 131*523fa7a6SAndroid Build Coastguard Worker """ 132*523fa7a6SAndroid Build Coastguard Worker Returns whether an option is successfully enabled, i.e. if the flag was 133*523fa7a6SAndroid Build Coastguard Worker given to pytest and the necessary requirements are available. 134*523fa7a6SAndroid Build Coastguard Worker Implemented options are: 135*523fa7a6SAndroid Build Coastguard Worker - corstone300. 136*523fa7a6SAndroid Build Coastguard Worker - quantize_io. 137*523fa7a6SAndroid Build Coastguard Worker 138*523fa7a6SAndroid Build Coastguard Worker The optional parameter 'fail_if_not_enabled' makes the function raise 139*523fa7a6SAndroid Build Coastguard Worker a RuntimeError instead of returning False. 140*523fa7a6SAndroid Build Coastguard Worker """ 141*523fa7a6SAndroid Build Coastguard Worker if isinstance(option, str): 142*523fa7a6SAndroid Build Coastguard Worker option = arm_test_options[option.lower()] 143*523fa7a6SAndroid Build Coastguard Worker 144*523fa7a6SAndroid Build Coastguard Worker if option in _test_options and _test_options[option]: 145*523fa7a6SAndroid Build Coastguard Worker return True 146*523fa7a6SAndroid Build Coastguard Worker else: 147*523fa7a6SAndroid Build Coastguard Worker if fail_if_not_enabled: 148*523fa7a6SAndroid Build Coastguard Worker raise RuntimeError(f"Required option '{option}' for test is not enabled") 149*523fa7a6SAndroid Build Coastguard Worker else: 150*523fa7a6SAndroid Build Coastguard Worker return False 151*523fa7a6SAndroid Build Coastguard Worker 152*523fa7a6SAndroid Build Coastguard Worker 153*523fa7a6SAndroid Build Coastguard Workerdef get_option(option: arm_test_options) -> Any | None: 154*523fa7a6SAndroid Build Coastguard Worker if option in _test_options: 155*523fa7a6SAndroid Build Coastguard Worker return _test_options[option] 156*523fa7a6SAndroid Build Coastguard Worker return None 157*523fa7a6SAndroid Build Coastguard Worker 158*523fa7a6SAndroid Build Coastguard Worker 159*523fa7a6SAndroid Build Coastguard Workerdef maybe_get_tosa_collate_path() -> str | None: 160*523fa7a6SAndroid Build Coastguard Worker """ 161*523fa7a6SAndroid Build Coastguard Worker Checks the environment variable TOSA_TESTCASES_BASE_PATH and returns the 162*523fa7a6SAndroid Build Coastguard Worker path to the where to store the current tests if it is set. 163*523fa7a6SAndroid Build Coastguard Worker """ 164*523fa7a6SAndroid Build Coastguard Worker tosa_test_base = os.environ.get("TOSA_TESTCASES_BASE_PATH") 165*523fa7a6SAndroid Build Coastguard Worker if tosa_test_base: 166*523fa7a6SAndroid Build Coastguard Worker current_test = os.environ.get("PYTEST_CURRENT_TEST") 167*523fa7a6SAndroid Build Coastguard Worker #'backends/arm/test/ops/test_mean_dim.py::TestMeanDim::test_meandim_tosa_BI_0_zeros (call)' 168*523fa7a6SAndroid Build Coastguard Worker test_class = current_test.split("::")[1] 169*523fa7a6SAndroid Build Coastguard Worker test_name = current_test.split("::")[-1].split(" ")[0] 170*523fa7a6SAndroid Build Coastguard Worker if "BI" in test_name: 171*523fa7a6SAndroid Build Coastguard Worker tosa_test_base = os.path.join(tosa_test_base, "tosa-bi") 172*523fa7a6SAndroid Build Coastguard Worker elif "MI" in test_name: 173*523fa7a6SAndroid Build Coastguard Worker tosa_test_base = os.path.join(tosa_test_base, "tosa-mi") 174*523fa7a6SAndroid Build Coastguard Worker else: 175*523fa7a6SAndroid Build Coastguard Worker tosa_test_base = os.path.join(tosa_test_base, "other") 176*523fa7a6SAndroid Build Coastguard Worker 177*523fa7a6SAndroid Build Coastguard Worker return os.path.join(tosa_test_base, test_class, test_name) 178*523fa7a6SAndroid Build Coastguard Worker 179*523fa7a6SAndroid Build Coastguard Worker return None 180*523fa7a6SAndroid Build Coastguard Worker 181*523fa7a6SAndroid Build Coastguard Worker 182*523fa7a6SAndroid Build Coastguard Workerdef get_tosa_compile_spec( 183*523fa7a6SAndroid Build Coastguard Worker tosa_version: str, permute_memory_to_nhwc=True, custom_path=None 184*523fa7a6SAndroid Build Coastguard Worker) -> list[CompileSpec]: 185*523fa7a6SAndroid Build Coastguard Worker """ 186*523fa7a6SAndroid Build Coastguard Worker Default compile spec for TOSA tests. 187*523fa7a6SAndroid Build Coastguard Worker """ 188*523fa7a6SAndroid Build Coastguard Worker return get_tosa_compile_spec_unbuilt( 189*523fa7a6SAndroid Build Coastguard Worker tosa_version, permute_memory_to_nhwc, custom_path 190*523fa7a6SAndroid Build Coastguard Worker ).build() 191*523fa7a6SAndroid Build Coastguard Worker 192*523fa7a6SAndroid Build Coastguard Worker 193*523fa7a6SAndroid Build Coastguard Workerdef get_tosa_compile_spec_unbuilt( 194*523fa7a6SAndroid Build Coastguard Worker tosa_version: str, permute_memory_to_nhwc=False, custom_path=None 195*523fa7a6SAndroid Build Coastguard Worker) -> ArmCompileSpecBuilder: 196*523fa7a6SAndroid Build Coastguard Worker """Get the ArmCompileSpecBuilder for the default TOSA tests, to modify 197*523fa7a6SAndroid Build Coastguard Worker the compile spec before calling .build() to finalize it. 198*523fa7a6SAndroid Build Coastguard Worker """ 199*523fa7a6SAndroid Build Coastguard Worker if not custom_path: 200*523fa7a6SAndroid Build Coastguard Worker intermediate_path = maybe_get_tosa_collate_path() or tempfile.mkdtemp( 201*523fa7a6SAndroid Build Coastguard Worker prefix="arm_tosa_" 202*523fa7a6SAndroid Build Coastguard Worker ) 203*523fa7a6SAndroid Build Coastguard Worker else: 204*523fa7a6SAndroid Build Coastguard Worker intermediate_path = custom_path 205*523fa7a6SAndroid Build Coastguard Worker 206*523fa7a6SAndroid Build Coastguard Worker if not os.path.exists(intermediate_path): 207*523fa7a6SAndroid Build Coastguard Worker os.makedirs(intermediate_path, exist_ok=True) 208*523fa7a6SAndroid Build Coastguard Worker compile_spec_builder = ( 209*523fa7a6SAndroid Build Coastguard Worker ArmCompileSpecBuilder() 210*523fa7a6SAndroid Build Coastguard Worker .tosa_compile_spec(tosa_version) 211*523fa7a6SAndroid Build Coastguard Worker .set_permute_memory_format(permute_memory_to_nhwc) 212*523fa7a6SAndroid Build Coastguard Worker .dump_intermediate_artifacts_to(intermediate_path) 213*523fa7a6SAndroid Build Coastguard Worker ) 214*523fa7a6SAndroid Build Coastguard Worker 215*523fa7a6SAndroid Build Coastguard Worker return compile_spec_builder 216*523fa7a6SAndroid Build Coastguard Worker 217*523fa7a6SAndroid Build Coastguard Worker 218*523fa7a6SAndroid Build Coastguard Workerdef get_u55_compile_spec( 219*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc=True, quantize_io=False, custom_path=None 220*523fa7a6SAndroid Build Coastguard Worker) -> list[CompileSpec]: 221*523fa7a6SAndroid Build Coastguard Worker """ 222*523fa7a6SAndroid Build Coastguard Worker Default compile spec for Ethos-U55 tests. 223*523fa7a6SAndroid Build Coastguard Worker """ 224*523fa7a6SAndroid Build Coastguard Worker return get_u55_compile_spec_unbuilt( 225*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc, quantize_io=quantize_io, custom_path=custom_path 226*523fa7a6SAndroid Build Coastguard Worker ).build() 227*523fa7a6SAndroid Build Coastguard Worker 228*523fa7a6SAndroid Build Coastguard Worker 229*523fa7a6SAndroid Build Coastguard Workerdef get_u85_compile_spec( 230*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc=True, quantize_io=False, custom_path=None 231*523fa7a6SAndroid Build Coastguard Worker) -> list[CompileSpec]: 232*523fa7a6SAndroid Build Coastguard Worker """ 233*523fa7a6SAndroid Build Coastguard Worker Default compile spec for Ethos-U85 tests. 234*523fa7a6SAndroid Build Coastguard Worker """ 235*523fa7a6SAndroid Build Coastguard Worker return get_u85_compile_spec_unbuilt( 236*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc, quantize_io=quantize_io, custom_path=custom_path 237*523fa7a6SAndroid Build Coastguard Worker ).build() 238*523fa7a6SAndroid Build Coastguard Worker 239*523fa7a6SAndroid Build Coastguard Worker 240*523fa7a6SAndroid Build Coastguard Workerdef get_u55_compile_spec_unbuilt( 241*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc=True, quantize_io=False, custom_path=None 242*523fa7a6SAndroid Build Coastguard Worker) -> ArmCompileSpecBuilder: 243*523fa7a6SAndroid Build Coastguard Worker """Get the ArmCompileSpecBuilder for the Ethos-U55 tests, to modify 244*523fa7a6SAndroid Build Coastguard Worker the compile spec before calling .build() to finalize it. 245*523fa7a6SAndroid Build Coastguard Worker """ 246*523fa7a6SAndroid Build Coastguard Worker artifact_path = custom_path or tempfile.mkdtemp(prefix="arm_u55_") 247*523fa7a6SAndroid Build Coastguard Worker if not os.path.exists(artifact_path): 248*523fa7a6SAndroid Build Coastguard Worker os.makedirs(artifact_path, exist_ok=True) 249*523fa7a6SAndroid Build Coastguard Worker compile_spec = ( 250*523fa7a6SAndroid Build Coastguard Worker ArmCompileSpecBuilder() 251*523fa7a6SAndroid Build Coastguard Worker .ethosu_compile_spec( 252*523fa7a6SAndroid Build Coastguard Worker "ethos-u55-128", 253*523fa7a6SAndroid Build Coastguard Worker system_config="Ethos_U55_High_End_Embedded", 254*523fa7a6SAndroid Build Coastguard Worker memory_mode="Shared_Sram", 255*523fa7a6SAndroid Build Coastguard Worker extra_flags="--debug-force-regor --output-format=raw", 256*523fa7a6SAndroid Build Coastguard Worker ) 257*523fa7a6SAndroid Build Coastguard Worker .set_quantize_io(is_option_enabled("quantize_io") or quantize_io) 258*523fa7a6SAndroid Build Coastguard Worker .set_permute_memory_format(permute_memory_to_nhwc) 259*523fa7a6SAndroid Build Coastguard Worker .dump_intermediate_artifacts_to(artifact_path) 260*523fa7a6SAndroid Build Coastguard Worker ) 261*523fa7a6SAndroid Build Coastguard Worker return compile_spec 262*523fa7a6SAndroid Build Coastguard Worker 263*523fa7a6SAndroid Build Coastguard Worker 264*523fa7a6SAndroid Build Coastguard Workerdef get_u85_compile_spec_unbuilt( 265*523fa7a6SAndroid Build Coastguard Worker permute_memory_to_nhwc=True, quantize_io=False, custom_path=None 266*523fa7a6SAndroid Build Coastguard Worker) -> list[CompileSpec]: 267*523fa7a6SAndroid Build Coastguard Worker """Get the ArmCompileSpecBuilder for the Ethos-U85 tests, to modify 268*523fa7a6SAndroid Build Coastguard Worker the compile spec before calling .build() to finalize it. 269*523fa7a6SAndroid Build Coastguard Worker """ 270*523fa7a6SAndroid Build Coastguard Worker artifact_path = custom_path or tempfile.mkdtemp(prefix="arm_u85_") 271*523fa7a6SAndroid Build Coastguard Worker compile_spec = ( 272*523fa7a6SAndroid Build Coastguard Worker ArmCompileSpecBuilder() 273*523fa7a6SAndroid Build Coastguard Worker .ethosu_compile_spec( 274*523fa7a6SAndroid Build Coastguard Worker "ethos-u85-128", 275*523fa7a6SAndroid Build Coastguard Worker system_config="Ethos_U85_SYS_DRAM_Mid", 276*523fa7a6SAndroid Build Coastguard Worker memory_mode="Shared_Sram", 277*523fa7a6SAndroid Build Coastguard Worker extra_flags="--output-format=raw", 278*523fa7a6SAndroid Build Coastguard Worker ) 279*523fa7a6SAndroid Build Coastguard Worker .set_quantize_io(is_option_enabled("quantize_io") or quantize_io) 280*523fa7a6SAndroid Build Coastguard Worker .set_permute_memory_format(permute_memory_to_nhwc) 281*523fa7a6SAndroid Build Coastguard Worker .dump_intermediate_artifacts_to(artifact_path) 282*523fa7a6SAndroid Build Coastguard Worker ) 283*523fa7a6SAndroid Build Coastguard Worker return compile_spec 284*523fa7a6SAndroid Build Coastguard Worker 285*523fa7a6SAndroid Build Coastguard Worker 286*523fa7a6SAndroid Build Coastguard Workerdef current_time_formated() -> str: 287*523fa7a6SAndroid Build Coastguard Worker """Return current time as a formated string""" 288*523fa7a6SAndroid Build Coastguard Worker return datetime.now().strftime(get_option(arm_test_options.date_format)) 289*523fa7a6SAndroid Build Coastguard Worker 290*523fa7a6SAndroid Build Coastguard Worker 291*523fa7a6SAndroid Build Coastguard Workerdef _clean_dir(dir: Path, filter: str, num_save=10): 292*523fa7a6SAndroid Build Coastguard Worker sorted_files: list[tuple[datetime, Path]] = [] 293*523fa7a6SAndroid Build Coastguard Worker for file in dir.iterdir(): 294*523fa7a6SAndroid Build Coastguard Worker try: 295*523fa7a6SAndroid Build Coastguard Worker creation_time = datetime.strptime(file.name, filter) 296*523fa7a6SAndroid Build Coastguard Worker insert_index = -1 297*523fa7a6SAndroid Build Coastguard Worker for i, to_compare in enumerate(sorted_files): 298*523fa7a6SAndroid Build Coastguard Worker compare_time = to_compare[0] 299*523fa7a6SAndroid Build Coastguard Worker if creation_time < compare_time: 300*523fa7a6SAndroid Build Coastguard Worker insert_index = i 301*523fa7a6SAndroid Build Coastguard Worker break 302*523fa7a6SAndroid Build Coastguard Worker if insert_index == -1 and len(sorted_files) < num_save: 303*523fa7a6SAndroid Build Coastguard Worker sorted_files.append((creation_time, file)) 304*523fa7a6SAndroid Build Coastguard Worker else: 305*523fa7a6SAndroid Build Coastguard Worker sorted_files.insert(insert_index, (creation_time, file)) 306*523fa7a6SAndroid Build Coastguard Worker except ValueError: 307*523fa7a6SAndroid Build Coastguard Worker continue 308*523fa7a6SAndroid Build Coastguard Worker 309*523fa7a6SAndroid Build Coastguard Worker if len(sorted_files) > num_save: 310*523fa7a6SAndroid Build Coastguard Worker for remove in sorted_files[0 : len(sorted_files) - num_save]: 311*523fa7a6SAndroid Build Coastguard Worker file = remove[1] 312*523fa7a6SAndroid Build Coastguard Worker file.unlink() 313