Add command line flag to list test times This is useful to find tests that use too much time. In order to cleanly filter out failing tests from the listing, this patch changes the recorded test time for failing tests from sys.max_int to None.
diff --git a/gtest-parallel b/gtest-parallel index 0be59e4..1e5cee6 100755 --- a/gtest-parallel +++ b/gtest-parallel
@@ -149,17 +149,19 @@ return for ((test_binary, test_name), runtime) in times.items(): if (type(test_binary) is not str or type(test_name) is not str - or type(runtime) not in {int, long}): + or type(runtime) not in {int, long, type(None)}): return self.__times = times def get_test_time(self, binary, testname): - "Return the last duration for the given test, or 0 if there's no record." + """Return the last duration for the given test (which can be None + if the test failed), or 0 if there's no record.""" return self.__times.get((binary, testname), 0) def record_test_time(self, binary, testname, runtime_ms): - "Record that the given test ran in the specified number of milliseconds." + """Record that the given test ran in the specified number of + milliseconds. If the test failed, runtime_ms should be None.""" with self.__lock: self.__times[(binary, testname)] = runtime_ms @@ -197,6 +199,8 @@ default=False, help='run disabled tests too') parser.add_option('--format', type='string', default='filter', help='output format (raw,filter)') +parser.add_option('--print_test_times', action='store_true', default=False, + help='When done, list the run time of each test') (options, binaries) = parser.parse_args() @@ -250,7 +254,10 @@ test = test_group + line tests.append((times.get_test_time(test_binary, test), test_binary, test, command)) -tests.sort(reverse=True) + +# Sort tests by falling runtime (with None, which is what's recorded +# for failing tests, being considered larger than any real runtime). +tests.sort(reverse=True, key=lambda x: ((1 if x[0] is None else 0), x)) # Repeat tests (-r flag). tests *= options.repeat @@ -261,9 +268,8 @@ exit_code = 0 # Run the specified job. Return the elapsed time in milliseconds if -# the job succeeds, or a very large number (larger than any reasonable -# elapsed time) if the job fails. (This ensures that failing tests -# will run first the next time.) +# the job succeeds, or None if the job fails. (This ensures that +# failing tests will run first the next time.) def run_job((command, job_id, test)): begin = time.time() sub = subprocess.Popen(command + ['--gtest_filter=' + test] + @@ -284,7 +290,7 @@ return runtime_ms global exit_code exit_code = code - return sys.maxint + return None def worker(): global job_id @@ -312,4 +318,10 @@ [t.join() for t in workers] logger.end() times.write_to_file(save_file) +if options.print_test_times: + ts = sorted((times.get_test_time(test_binary, test), test_binary, test) + for (_, test_binary, test, _) in tests + if times.get_test_time(test_binary, test) is not None) + for (time_ms, test_binary, test) in ts: + print "%8s %s" % ("%dms" % time_ms, test) sys.exit(exit_code)