1import subprocess 2import shutil 3import os 4import argparse 5import sys 6 7# python3 tests/nvram_tests/run_tests.py -h 8 9test_files = [] 10# tests that require extra command line arguments(example: nvram reset is called only if -r is passed) 11special_calls = { 12 "nvram_nonentitled": [ 13 "nvram_nonentitled -n xnu.nvram.TestImmutable -- -r", 14 "nvram_nonentitled -n xnu.nvram.TestResetOnlyDel -- -r", 15 "nvram_nonentitled -n xnu.nvram.TestEntRst -- -r", 16 "nvram_nonentitled -n xnu.nvram.TestEntDel -- -r", 17 "nvram_nonentitled -n xnu.nvram.TestNVRAMReset -- -r", 18 "nvram_nonentitled -n xnu.nvram.TestNVRAMOblit -- -r", 19 ], 20 "nvram_system": [ 21 "nvram_system -n xnu.nvram.TestEntRstSys -- -r", 22 "nvram_system -n xnu.nvram.TestNVRAMResetSys -- -r", 23 "nvram_system -n xnu.nvram.TestNVRAMOblitSys -- -r", 24 ], 25 "nvram_ve_reset": ["nvram_ve_reset -n xnu.nvram.TestEntRstEnt -- -r"], 26 "nvram_ve_mod": [ 27 "nvram_ve_mod -n xnu.nvram.TestEntModRstEnt -- -r", 28 "nvram_ve_mod -n xnu.nvram.TestEntModRstSysEnt -- -r", 29 ], 30} 31 32 33def create_arg_parser(): 34 example_cmd = '''examples: 35 To use default args: 36 python %(prog)s 37 To use iphoneos sdk: 38 python %(prog)s -s 1 39 To build only: 40 python %(prog)s -br 0 -f <path to test files if not default> 41 To run only: 42 python %(prog)s -br 1 -b <path to build files if not default> 43 To run only: 44 To invoke reset calls: 45 python %(prog)s -r 1''' 46 47 parser = argparse.ArgumentParser( 48 description='Builds and/or runs nvram tests for xnu', 49 epilog=example_cmd, 50 formatter_class=argparse.RawDescriptionHelpFormatter) 51 52 default_build_path = "tests/build/sym/" 53 default_files_path = "tests/nvram_tests" 54 55 parser.add_argument('-br', type=int, default=2, choices=[ 56 0, 1, 2], required=False, help='0=only builds, 1=only runs, 2=builds and runs') 57 parser.add_argument('-b', type=str, default=default_build_path, 58 required=False, help='Path to the build files') 59 parser.add_argument('-f', type=str, default=default_files_path, 60 required=False, help='Path to the test files') 61 parser.add_argument('-r', type=int, default=0, choices=[ 62 0, 1], required=False, help='0=ignores the reset calls, 1=uses the reset calls') 63 parser.add_argument('-s', type=int, default=0, choices=[ 64 0, 1], required=False, help='0=macos sdk, 1=iphoneos sdk') 65 66 return parser 67 68 69def run_tests(build_path, test_arg): 70 args = "sudo ./" + build_path + test_arg 71 output = subprocess.getoutput(args) 72 print(output) 73 74 75if __name__ == "__main__": 76 77 arg_parser = create_arg_parser() 78 parsed_args = arg_parser.parse_args(sys.argv[1:]) 79 build_path = parsed_args.b 80 file_path = parsed_args.f 81 reset_flag = parsed_args.r 82 action = parsed_args.br 83 sdk = "macosx.internal" if (parsed_args.s == 0) else "iphoneos.internal" 84 85 print(parsed_args) 86 87 if (action != 1): 88 if not os.path.exists(file_path) or os.path.basename(os.getcwd()) != 'xnu': 89 print("Invalid file path:", file_path) 90 sys.exit() 91 92 # Iterate through test_files_path and get all the test files to run 93 for file in os.listdir(file_path): 94 if file.endswith(".c") and "helper" not in file: 95 test_files.append(file.rsplit(".", maxsplit=1)[0]) 96 97 # Delete existing build folder 98 if os.path.isdir(build_path): 99 shutil.rmtree(build_path) 100 101 # Build the tests 102 for i in test_files: 103 print("\n\n************************************** Building", 104 i, "**************************************\n\n") 105 args = "xcrun -sdk " + sdk + " make -C tests " + i 106 output = subprocess.getoutput(args) 107 print(output) 108 109 if (action != 0): 110 if (action == 1): 111 for file in os.listdir(build_path): 112 if not file.endswith(".dSYM"): 113 test_files.append(file) 114 # Run the tests 115 for i in test_files: 116 print("\n\n************************************** Testing", 117 i, "**************************************\n\n") 118 119 if (reset_flag == 1) and (i in special_calls.keys()): 120 for j in special_calls[i]: 121 run_tests(build_path, j) 122 run_tests(build_path, i) 123