diff options
author | Siyuan Zhou <visualzhou@gmail.com> | 2013-08-26 19:00:35 -0400 |
---|---|---|
committer | Matt Kangas <matt.kangas@mongodb.com> | 2013-09-12 18:58:59 -0400 |
commit | 74b09795ac361e56d57fbc9b3ab75db6d7404cb0 (patch) | |
tree | fb8f846229832e3117fe5ae5d57f7d2a0785434d /buildscripts | |
parent | 25257eef8a7e1d3b8a8bbfa12f8e9f7f0ebea7aa (diff) | |
download | mongo-74b09795ac361e56d57fbc9b3ab75db6d7404cb0.tar.gz |
SERVER-10740 Generate test result report from smoke.py
smoke.py could optionally output a test report to a file. This should be
an json summary of a test suite run, so MCI can report on specific failed
tests.
The following command could generate a detailed test report in json
format. smoke-last.json will have the details as well.
smoke.py --report-file <report-file-path>
Signed-off-by: Matt Kangas <matt.kangas@mongodb.com>
Diffstat (limited to 'buildscripts')
-rwxr-xr-x | buildscripts/smoke.py | 53 |
1 files changed, 42 insertions, 11 deletions
diff --git a/buildscripts/smoke.py b/buildscripts/smoke.py index 08bea523c3d..1f9a56a93d5 100755 --- a/buildscripts/smoke.py +++ b/buildscripts/smoke.py @@ -101,6 +101,7 @@ small_oplog = False small_oplog_rs = False all_test_results = [] +report_file = None # This class just implements the with statement API, for a sneaky # purpose below. @@ -122,7 +123,6 @@ def buildlogger(cmd, is_global=False): return [utils.find_python(), 'buildscripts/buildlogger.py'] + cmd return cmd - class mongod(object): def __init__(self, **kwargs): self.kwargs = kwargs @@ -319,8 +319,8 @@ class TestFailure(Exception): class TestExitFailure(TestFailure): def __init__(self, *args): self.path = args[0] - self.status=args[1] + def __str__(self): return "test %s exited with status %d" % (self.path, self.status) @@ -417,7 +417,9 @@ def skipTest(path): return False -def runTest(test): +def runTest(test, result): + # result is a map containing test result details, like result["url"] + # test is a tuple of ( filename , usedb<bool> ) # filename should be a js file to run # usedb is true if the test expects a mongod to be running @@ -515,7 +517,19 @@ def runTest(test): os.environ['MONGO_TEST_FILENAME'] = mongo_test_filename t1 = time.time() - r = call(buildlogger(argv), cwd=test_path) + + proc = Popen(buildlogger(argv), cwd=test_path, stdout=PIPE) + first_line = proc.stdout.readline() # Get suppressed output URL + m = re.search(r"\s*\(output suppressed; see (?P<url>.*)\)$", first_line) + if m: + result["url"] = m.group("url") + sys.stdout.write(first_line) + for line in proc.stdout: # print until subprocess's stdout closed + sys.stdout.write(line) + + proc.wait() # wait if stdout is closed before subprocess exits. + r = proc.returncode + t2 = time.time() del os.environ['MONGO_TEST_FILENAME'] @@ -534,6 +548,8 @@ def runTest(test): sys.stdout.write(" %10.4f %s\n" % ((timediff) * scale, suffix)) sys.stdout.flush() + result["exit_code"] = r + if r != 0: raise TestExitFailure(path, r) @@ -600,15 +616,22 @@ def run_tests(tests): tests_run = 0 for tests_run, test in enumerate(tests): - test_result = { "test": test[0], "start": time.time() } + test_result = { "start": time.time() } + + if test[0].startswith(mongo_repo + os.path.sep): + test_result["test_file"] = test[0][len(mongo_repo)+1:] + else: + # user could specify a file not in repo. leave it alone. + test_result["test_file"] = test[0] + try: fails.append(test) - runTest(test) + runTest(test, test_result) fails.pop() winners.append(test) - test_result["passed"] = True test_result["end"] = time.time() + test_result["status"] = "pass" all_test_results.append( test_result ) if small_oplog or small_oplog_rs: @@ -627,9 +650,9 @@ def run_tests(tests): use_ssl=use_ssl).__enter__() except TestFailure, f: - test_result["passed"] = False test_result["end"] = time.time() test_result["error"] = str(f) + test_result["status"] = "fail" all_test_results.append( test_result ) try: print f @@ -787,6 +810,7 @@ def set_globals(options, tests): global no_journal, set_parameters, no_preallocj, auth, authMechanism, keyFile, smoke_db_prefix, test_path, start_mongod global use_ssl global file_of_commands_mode + global report_file start_mongod = options.start_mongod if hasattr(options, 'use_ssl'): use_ssl = options.use_ssl @@ -831,6 +855,8 @@ def set_globals(options, tests): # if smoke.py is running a list of commands read from a # file (or stdin) rather than running a suite of js tests file_of_commands_mode = options.File and options.mode == 'files' + # generate json report + report_file = options.report_file def file_version(): return md5(open(__file__, 'r').read()).hexdigest() @@ -982,6 +1008,10 @@ def main(): action="store", help='Path to Python file containing buildlogger credentials') parser.add_option('--buildlogger-phase', dest='buildlogger_phase', default=None, action="store", help='Set the "phase" for buildlogger (e.g. "core", "auth") for display in the webapp (optional)') + parser.add_option('--report-file', dest='report_file', default=None, + action='store', + help='Path to generate detailed json report containing all test details') + global tests (options, tests) = parser.parse_args() @@ -1047,9 +1077,10 @@ def main(): finally: add_to_failfile(fails, options) - f = open( "smoke-last.json", "wb" ) - f.write( json.dumps( { "results" : all_test_results } ) ) - f.close() + if report_file: + f = open( report_file, "wb" ) + f.write( json.dumps( { "results" : all_test_results } ) ) + f.close() report() |