33import subprocess
44import sys
55import inspect
6- from typing import Dict , List , Type , Tuple
6+ import argparse
7+ from typing import Dict , List , Type , Tuple , Callable
78from pathlib import Path
89
910from dumpulator import Dumpulator
@@ -43,17 +44,22 @@ def collect_tests(dll_data) -> Tuple[Dict[str, List[str]], int]:
4344 tests [prefix ].append (export .name )
4445 return tests , module .base
4546
46- def run_tests (dll_path : str , harness_dump : str ) -> Dict [str , bool ]:
47+ def run_tests (dll_path : str , harness_dump : str , filter : Callable [[ str , str ], bool ] ) -> Dict [str , bool ]:
4748 print (f"--- { dll_path } ---" )
4849 with open (dll_path , "rb" ) as dll :
4950 dll_data = dll .read ()
5051 environments = collect_environments ()
5152 tests , base = collect_tests (dll_data )
5253 results : Dict [str , bool ] = {}
5354 for prefix , exports in tests .items ():
54- print ( f" \n Running { prefix . lower () } tests:" )
55+ printed_prefix = False
5556 environment = environments .get (prefix , TestEnvironment )
5657 for export in exports :
58+ if not filter (prefix , export ):
59+ continue
60+ if not printed_prefix :
61+ print (f"\n Running { prefix .lower ()} tests:" )
62+ printed_prefix = True
5763 dp = Dumpulator (harness_dump , trace = True )
5864 module = dp .map_module (dll_data , dll_path , base )
5965 environment ().setup (dp )
@@ -128,6 +134,7 @@ def build(platform):
128134 build ("x64" )
129135
130136def main ():
137+ # Make sure all the required artifacts are there
131138 dll_x64 = "DumpulatorTests/bin/Tests_x64.dll"
132139 dll_x86 = "DumpulatorTests/bin/Tests_x86.dll"
133140 if not os .path .exists (dll_x64 ) or not os .path .exists (dll_x86 ):
@@ -149,15 +156,52 @@ def main():
149156 if not download_main (dmp_x64 , dmp_x86 ):
150157 sys .exit (1 )
151158
152- results_x64 = run_tests (dll_x64 , dmp_x64 )
153- print ("" )
154- results_x86 = run_tests (dll_x86 , dmp_x86 )
155-
156- print ("" )
157- success_x64 = print_results ("x64" , results_x64 )
158- print ("" )
159- success_x86 = print_results ("x86" , results_x86 )
160- if not success_x64 or not success_x86 :
159+ archs = {
160+ "x64" : (dll_x64 , dmp_x64 ),
161+ "x86" : (dll_x86 , dmp_x86 ),
162+ }
163+
164+ # Parse arguments
165+ parser = argparse .ArgumentParser (description = "Dumpulator test harness" )
166+ parser .add_argument ("--arch" , choices = ["x86" , "x64" ], help = "Architecture to use (omit for both)" , required = False )
167+ parser .add_argument ("--tests" , nargs = "+" , help = "List of specific tests to run" , required = False )
168+ parser .add_argument ("--list" , action = "store_true" , help = "List all tests" )
169+ parser .add_argument ("--prefix" , nargs = "+" , help = "Only run tests from this prefix" , required = False )
170+ args = parser .parse_args ()
171+
172+ # List all tests
173+ if args .list :
174+ for arch , (dll , _ ) in archs .items ():
175+ with open (dll , "rb" ) as f :
176+ dll_data = f .read ()
177+ print (f"--- { dll } ---" )
178+ tests , _ = collect_tests (dll_data )
179+ for prefix , exports in tests .items ():
180+ for export in exports :
181+ print (f"--arch { arch } --prefix { prefix .lower ()} --tests { export } " )
182+ return
183+
184+ if args .arch :
185+ archs = { args .arch : archs [args .arch ] }
186+
187+ def filter (prefix , export ) -> bool :
188+ prefix_ok = not args .prefix or args .prefix .lower () == prefix .lower ()
189+ export_ok = not args .tests or export in args .tests
190+ return prefix_ok and export_ok
191+
192+ # Run the tests
193+ results = {}
194+ for arch , (dll , dmp ) in archs .items ():
195+ results [arch ] = run_tests (dll , dmp , filter )
196+ print ("" )
197+
198+ # Print the results
199+ success = True
200+ for arch , result in results .items ():
201+ if not print_results (arch , result ):
202+ success = False
203+
204+ if not success :
161205 sys .exit (1 )
162206
163207if __name__ == "__main__" :
0 commit comments