Changeset 911348cd
- Timestamp:
- Jul 15, 2016, 11:34:46 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 52c97dd
- Parents:
- ed5ad08
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/tests/test.py
red5ad08 r911348cd 16 16 ################################################################################ 17 17 18 # Test class that defines what a test is 18 19 class Test: 19 20 def __init__(self, name, path): 20 21 self.name, self.path = name, path 21 22 23 # parses the Makefile to find the machine type (32-bit / 64-bit) 22 24 def getMachineType(): 23 25 with open('Makefile') as file: … … 26 28 return m.group(1) 27 29 30 # reads the directory ./.expect and indentifies the tests 28 31 def listTests(): 29 32 machineType = getMachineType() 30 33 34 # tests directly in the .expect folder will always be processed 31 35 generic_list = map(lambda fname: Test(fname, fname), 32 36 [splitext(f)[0] for f in listdir('./.expect') … … 34 38 ]) 35 39 40 # tests in the machineType folder will be ran only for the corresponding compiler 36 41 typed_list = map(lambda fname: Test( fname, "%s/%s" % (machineType, fname) ), 37 42 [splitext(f)[0] for f in listdir("./.expect/%s" % machineType) … … 39 44 ]) 40 45 46 # append both lists to get 41 47 return generic_list + typed_list 42 48 49 # helper functions to run terminal commands 43 50 def sh(cmd, dry_run = False, print2stdout = True): 44 if dry_run : 51 if dry_run : # if this is a dry_run, only print the commands that would be ran 45 52 print("cmd: %s" % cmd) 46 53 return 0, None 47 else : 54 else : # otherwise create a pipe and run the desired command 48 55 proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True) 49 56 out, err = proc.communicate() 50 57 return proc.returncode, out 51 58 59 # helper function to replace patterns in a file 52 60 def file_replace(fname, pat, s_after): 53 61 # first, see if the pattern is even in the file. … … 65 73 os.rename(out_fname, fname) 66 74 75 # tests output may differ depending on the depth of the makefile 67 76 def fix_MakeLevel(file) : 68 77 if environ.get('MAKELEVEL') : 69 78 file_replace(file, "make\[%i\]" % int(environ.get('MAKELEVEL')), 'make' ) 70 79 80 # helper function to check if a files contains only a spacific string 71 81 def fileContainsOnly(file, text) : 72 82 with open(file) as f: 73 83 ff = f.read().strip() 74 84 result = ff == text.strip() 75 #76 # print("Comparing :\n\t'%s'\nWith:\n\t'%s'" % (ff, text))77 # print("Result is : \n\t", end="")78 # print(result)79 85 80 86 return result; 81 87 88 # check whether or not a file is executable 82 89 def fileIsExecutable(file) : 83 90 try : … … 90 97 return False 91 98 99 # find the test data for a given test name 92 100 def filterTests(testname) : 93 101 found = [test for test in allTests if test.name == testname] … … 99 107 def run_test_instance(test, generate, dry_run): 100 108 109 # find the output file based on the test name and options flag 101 110 out_file = (".out/%s.log" % test.name) if not generate else (".expect/%s.txt" % test.path) 102 111 112 # remove any outputs from the previous tests to prevent side effects 103 113 sh("rm -f %s" % out_file, dry_run) 104 114 sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run) … … 107 117 make_ret, _ = sh("%s %s 2> %s 1> /dev/null" % (make_cmd, test.name, out_file), dry_run) 108 118 119 # if the make command succeds continue otherwise skip to diff 109 120 if make_ret == 0 : 110 121 # fetch optional input … … 121 132 error = None 122 133 134 # fix output to prevent make depth to cause issues 123 135 fix_MakeLevel(out_file) 124 136 125 137 if generate : 138 # if we are ounly generating the output we still need to check that the test actually exists 126 139 if not dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'. Stop." % test.name) : 127 140 retcode = 1; … … 145 158 ".expect/%s.txt .out/%s.log") 146 159 160 # fetch return code and error from the diff command 147 161 retcode, error = sh(diff_cmd % (test.path, test.name), dry_run, False) 148 162 … … 152 166 return retcode, error 153 167 154 def run_tests(tests, generate, dry_run) : 168 # run the given list of tests with the given parameters 169 def run_tests(tests, generate, dry_run, jobs) : 170 # clean the sandbox from previous commands 155 171 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run) 172 173 #make sure the required folder are present 156 174 sh('mkdir -p .out .expect', dry_run) 157 175 … … 160 178 161 179 failed = False; 180 # for eeach test to run 162 181 for t in tests: 182 # print formated name 163 183 print("%20s " % t.name, end="") 164 184 sys.stdout.flush() 185 186 #run the test instance and collect the result 165 187 test_failed, error = run_test_instance(t, generate, dry_run) 188 189 # aggregate test suite result 166 190 failed = test_failed or failed 167 191 192 # update output based on current action 168 193 if generate : 169 194 failed_txt = "ERROR" … … 173 198 success_txt = "PASSED" 174 199 200 #print result with error if needed 175 201 print(failed_txt if test_failed else success_txt) 176 202 if error : 177 203 print(error, file=sys.stderr) 178 204 205 #clean the workspace 179 206 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run) 180 207 … … 184 211 # main loop 185 212 ################################################################################ 213 # create a parser with the arguments for the tests script 186 214 parser = argparse.ArgumentParser(description='Script which runs cforall tests') 187 215 parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true') … … 189 217 parser.add_argument('--all', help='Run all test available', action='store_true') 190 218 parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true') 219 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='1') 191 220 parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run') 192 221 222 # parse the command line arguments 193 223 options = parser.parse_args() 194 224 225 # script must have at least some tests to run 195 226 if (len(options.tests) > 0 and options.all and not options.list) \ 196 227 or (len(options.tests) == 0 and not options.all and not options.list) : … … 199 230 sys.exit(1) 200 231 232 # fetch the liest of all valid tests 201 233 allTests = listTests() 202 234 235 # if user wants all tests than no other treatement of the test list is required 203 236 if options.all or options.list : 204 237 tests = allTests 205 238 206 239 else : 240 #otherwise we need to validate that the test list that was entered is valid 207 241 tests = [] 208 242 243 # if we are regenerating the tests we need to find the information of the 244 # already existing tests and create new info for the new tests 209 245 if options.regenerate_expected : 210 246 tests = map(filterTests, options.tests) 211 247 212 248 else : 249 # otherwise we only need to validate that all tests are present in the complete list 213 250 for testname in options.tests: 214 251 test = [t for t in allTests if t.name == testname] … … 219 256 print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr) 220 257 258 # make sure we have at least some test to run 221 259 if len(tests) == 0 : 222 260 print('ERROR: No valid test to run', file=sys.stderr) 223 261 sys.exit(1) 224 262 263 # sort the test alphabetically for convenience 225 264 tests.sort(key=lambda t: t.name) 226 265 266 # check if the user already passed in a number of jobs for multi-threading 227 267 make_flags = environ.get('MAKEFLAGS') 228 make_cmd = "make" if make_flags and "-j" in make_flags else "make -j8" 229 268 make_has_max_jobs = make_flags and "-j" in make_flags 269 make_max_jobs = re.search("(-j|--jobs)\s*([0-9]+)", make_flags).group(2) if make_has_max_jobs else None 270 make_cmd = "make" if make_has_max_jobs else "make -j8" 271 272 # make sure we have a valid number of jobs that corresponds to user input 273 options.jobs = int(make_max_jobs) if make_max_jobs else options.jobs 274 if options.jobs <= 0 : 275 print('ERROR: Invalid number of jobs', file=sys.stderr) 276 sys.exit(1) 277 278 279 # users may want to simply list the tests 230 280 if options.list : 231 281 print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests))) 232 282 233 283 else : 284 # otherwise run all tests and make sure to return the correct error code 234 285 sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run) )
Note: See TracChangeset
for help on using the changeset viewer.