diff --git a/run_tests.py b/run_tests.py index 7d4319f7..dbf96552 100755 --- a/run_tests.py +++ b/run_tests.py @@ -17,6 +17,7 @@ import shlex import platform import tempfile import os.path +import time # disable fancy error/warning printing with ANSI colors, so grepping for error # messages doesn't get confused @@ -52,6 +53,8 @@ parser.add_option('-v', '--verbose', dest='verbose', help='Enable verbose output parser.add_option('--wrap-exe', dest='wrapexe', help='Executable to wrap test runs with (e.g. "valgrind")', default="") +parser.add_option('--time', dest='time', help='Enable time output', + default=False, action="store_true") (options, args) = parser.parse_args() @@ -217,19 +220,60 @@ def run_cmds(compile_cmds, run_cmd, filename, expect_failure): return (0, 0) -def run_test(testname): +def add_prefix(path): global is_windows if is_windows: - # On Windows we run tests in tmp dir, so the root is one level up. + # On Windows we run tests in tmp dir, so the root is one level up. input_prefix = "..\\" else: input_prefix = "" + path = input_prefix + path + path = os.path.normpath(path) + return path + +def check_test(filename): + prev_arch = False + prev_os = False + done_arch = True + done_os = True + done = True + global is_windows + if is_windows: + oss = "windows" + else: + oss = "linux" + b = buffer(file(add_prefix(filename)).read()); + for run in re.finditer('// *rule: run on .*', b): + arch = re.match('.* arch=.*', run.group()) + if arch != None: + if re.search(' arch='+options.arch+'$', arch.group()) != None: + prev_arch = True + if re.search(' arch='+options.arch+' ', arch.group()) != None: + prev_arch = True + done_arch = prev_arch + OS = re.match('.* OS=.*', run.group()) + if OS != None: + if re.search(' OS='+oss, OS.group()) != None: + prev_os = True + done_os = prev_os + done = done_arch and done_os + for skip in re.finditer('// *rule: skip on .*', b): + if re.search(' arch=' + options.arch + '$', skip.group())!=None: + done = False + if re.search(' arch=' + options.arch + ' ', skip.group())!=None: + done = False + if re.search(' OS=' + oss, skip.group())!=None: + done = False + return done + + +def run_test(testname): # testname is a path to the test from the root of ispc dir # filename is a path to the test from the current dir # ispc_exe_rel is a relative path to ispc - filename = os.path.normpath(input_prefix + testname) - ispc_exe_rel = os.path.normpath(input_prefix + ispc_exe) + filename = add_prefix(testname) + ispc_exe_rel = add_prefix(ispc_exe) # is this a test to make sure an error is issued? want_error = (filename.find("tests_errors") != -1) @@ -290,8 +334,8 @@ def run_test(testname): obj_name = "%s.obj" % os.path.basename(filename) exe_name = "%s.exe" % os.path.basename(filename) - cc_cmd = "%s /I. /I../winstuff /Zi /nologo /DTEST_SIG=%d %stest_static.cpp %s /Fe%s" % \ - (options.compiler_exe, match, input_prefix, obj_name, exe_name) + cc_cmd = "%s /I. /I../winstuff /Zi /nologo /DTEST_SIG=%d %s %s /Fe%s" % \ + (options.compiler_exe, match, add_prefix("test_static.cpp"), obj_name, exe_name) if should_fail: cc_cmd += " /DEXPECT_FAILURE" else: @@ -327,7 +371,7 @@ def run_test(testname): if options.no_opt: ispc_cmd += " -O0" if is_generic_target: - ispc_cmd += " --emit-c++ --c++-include-file=%s" % os.path.normpath(input_prefix + options.include_file) + ispc_cmd += " --emit-c++ --c++-include-file=%s" % add_prefix(options.include_file) # compile the ispc code, make the executable, and run it... (compile_error, run_error) = run_cmds([ispc_cmd, cc_cmd], @@ -351,7 +395,7 @@ def run_test(testname): # pull tests to run from the given queue and run them. Multiple copies of # this function will be running in parallel across all of the CPU cores of # the system. -def run_tasks_from_queue(queue, queue_ret, total_tests_arg, max_test_length_arg, counter, mutex): +def run_tasks_from_queue(queue, queue_ret, queue_skip, total_tests_arg, max_test_length_arg, counter, mutex): if is_windows: tmpdir = "tmp%d" % os.getpid() os.mkdir(tmpdir) @@ -380,14 +424,18 @@ def run_tasks_from_queue(queue, queue_ret, total_tests_arg, max_test_length_arg, sys.exit(0) - (compile_error, run_error) = run_test(filename) - if compile_error != 0: - compile_error_files += [ filename ] - if run_error != 0: - run_error_files += [ filename ] + if check_test(filename): + (compile_error, run_error) = run_test(filename) + if compile_error != 0: + compile_error_files += [ filename ] + if run_error != 0: + run_error_files += [ filename ] + + with mutex: + update_progress(filename, total_tests_arg, counter, max_test_length_arg) + else: + queue_skip.put(filename) - with mutex: - update_progress(filename, total_tests_arg, counter, max_test_length_arg) task_threads = [] @@ -413,6 +461,7 @@ if __name__ == '__main__': for x in range(nthreads): q.put('STOP') qret = multiprocessing.Queue() + qskip = multiprocessing.Queue() # need to catch sigint so that we can terminate all of the tasks if # we're interrupted @@ -421,9 +470,10 @@ if __name__ == '__main__': finished_tests_counter = multiprocessing.Value(c_int) finished_tests_counter_lock = multiprocessing.Lock() + start_time = time.time() # launch jobs to run tests for x in range(nthreads): - t = multiprocessing.Process(target=run_tasks_from_queue, args=(q, qret, total_tests, max_test_length, finished_tests_counter, finished_tests_counter_lock)) + t = multiprocessing.Process(target=run_tasks_from_queue, args=(q, qret, qskip, total_tests, max_test_length, finished_tests_counter, finished_tests_counter_lock)) task_threads.append(t) t.start() @@ -433,11 +483,21 @@ if __name__ == '__main__': t.join() sys.stdout.write("\n") + elapsed_time = time.time() - start_time + if options.time: + sys.stdout.write("Elapsed time: %d s\n" % elapsed_time) + while not qret.empty(): (c, r) = qret.get() compile_error_files += c run_error_files += r + skip = 0 + if qskip.qsize() > 0: + sys.stdout.write("%d / %d tests SKIPPED:\n" % (qskip.qsize(), total_tests)) + while not qskip.empty(): + sys.stdout.write("\t%s\n" % qskip.get()) + if len(compile_error_files) > 0: compile_error_files.sort() sys.stdout.write("%d / %d tests FAILED compilation:\n" % (len(compile_error_files), total_tests)) diff --git a/tests_errors/ptrcast-lose-info.ispc b/tests_errors/ptrcast-lose-info.ispc index a8776206..5da374aa 100644 --- a/tests_errors/ptrcast-lose-info.ispc +++ b/tests_errors/ptrcast-lose-info.ispc @@ -1,4 +1,5 @@ // Pointer type cast of type "uniform int32 * uniform" to integer type "uniform int32" may lose information. +// rule: run on arch=x86-64 int32 foo(int * uniform x) { return (int32) x;