1111import  subprocess 
1212import  sys 
1313import  tempfile 
14+ from  datetime  import  datetime 
15+ from  enum  import  auto , Enum 
16+ from  pathlib  import  Path 
17+ from  typing  import  Any 
1418
1519import  pytest 
1620
1923from  executorch .backends .arm .arm_backend  import  ArmCompileSpecBuilder 
2024from  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
2739def  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
3246def  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+ 
99145def  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 ()
0 commit comments