Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """A tool to run a chrome test executable, used by the buildbot slaves. | 6 """A tool to run a chrome test executable, used by the buildbot slaves. |
| 7 | 7 |
| 8 When this is run, the current directory (cwd) should be the outer build | 8 When this is run, the current directory (cwd) should be the outer build |
| 9 directory (e.g., chrome-release/build/). | 9 directory (e.g., chrome-release/build/). |
| 10 | 10 |
| 11 For a list of command-line options, call this script with '--help'. | 11 For a list of command-line options, call this script with '--help'. |
| 12 """ | 12 """ |
| 13 | 13 |
| 14 import copy | 14 import copy |
| 15 import logging | 15 import logging |
| 16 import optparse | 16 import optparse |
| 17 import os | 17 import os |
| 18 import re | |
| 18 import stat | 19 import stat |
| 19 import sys | 20 import sys |
| 20 import tempfile | 21 import tempfile |
| 21 | 22 |
| 22 # sys.path needs to be modified here because python2.6 automatically adds the | 23 # sys.path needs to be modified here because python2.6 automatically adds the |
| 23 # system "google" module (/usr/lib/pymodules/python2.6/google) to sys.modules | 24 # system "google" module (/usr/lib/pymodules/python2.6/google) to sys.modules |
| 24 # when we import "chromium_config" (I don't know why it does this). This causes | 25 # when we import "chromium_config" (I don't know why it does this). This causes |
| 25 # the import of our local "google.*" modules to fail because python seems to | 26 # the import of our local "google.*" modules to fail because python seems to |
| 26 # only look for a system "google.*", even if our path is in sys.path before | 27 # only look for a system "google.*", even if our path is in sys.path before |
| 27 # importing "google.*". If we modify sys.path here, before importing | 28 # importing "google.*". If we modify sys.path here, before importing |
| 28 # "chromium_config", python2.6 properly uses our path to find our "google.*" | 29 # "chromium_config", python2.6 properly uses our path to find our "google.*" |
| 29 # (even though it still automatically adds the system "google" module to | 30 # (even though it still automatically adds the system "google" module to |
| 30 # sys.modules, and probably should still be using that to resolve "google.*", | 31 # sys.modules, and probably should still be using that to resolve "google.*", |
| 31 # which I really don't understand). | 32 # which I really don't understand). |
| 32 sys.path.insert(0, os.path.abspath('src/tools/python')) | 33 sys.path.insert(0, os.path.abspath('src/tools/python')) |
| 33 | 34 |
| 34 # Because of this dependency on a chromium checkout, we need to disable some | 35 # Because of this dependency on a chromium checkout, we need to disable some |
| 35 # pylint checks. | 36 # pylint checks. |
| 36 # pylint: disable=E0611 | 37 # pylint: disable=E0611 |
| 37 # pylint: disable=E1101 | 38 # pylint: disable=E1101 |
| 39 from buildbot.status import builder | |
| 38 from common import chromium_utils | 40 from common import chromium_utils |
|
cmp
2012/06/28 19:14:16
insert an empty line before line 40
| |
| 41 from common import gtest_utils | |
| 39 from slave import gtest_slave_utils | 42 from slave import gtest_slave_utils |
| 40 from slave import slave_utils | 43 from slave import slave_utils |
| 41 from slave import xvfb | 44 from slave import xvfb |
| 42 import config | 45 import config |
| 43 | 46 |
| 44 USAGE = '%s [options] test.exe [test args]' % os.path.basename(sys.argv[0]) | 47 USAGE = '%s [options] test.exe [test args]' % os.path.basename(sys.argv[0]) |
| 45 | 48 |
| 46 CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox' | 49 CHROME_SANDBOX_PATH = '/opt/chromium/chrome_sandbox' |
| 47 | 50 |
| 48 DEST_DIR = 'gtest_results' | 51 DEST_DIR = 'gtest_results' |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 73 return len(os.listdir(tempfile.gettempdir())) | 76 return len(os.listdir(tempfile.gettempdir())) |
| 74 | 77 |
| 75 | 78 |
| 76 def _RunGTestCommand(command, results_tracker=None, pipes=None): | 79 def _RunGTestCommand(command, results_tracker=None, pipes=None): |
| 77 if results_tracker and pipes: | 80 if results_tracker and pipes: |
| 78 # This is not supported by RunCommand. | 81 # This is not supported by RunCommand. |
| 79 print 'Invalid test invocation. (results_tracker and pipes)' | 82 print 'Invalid test invocation. (results_tracker and pipes)' |
| 80 return 1 | 83 return 1 |
| 81 if results_tracker: | 84 if results_tracker: |
| 82 return chromium_utils.RunCommand( | 85 return chromium_utils.RunCommand( |
| 83 command, parser_func=results_tracker.OnReceiveLine) | 86 command, parser_func=results_tracker.ProcessLine) |
| 84 else: | 87 else: |
| 85 return chromium_utils.RunCommand(command, pipes=pipes) | 88 return chromium_utils.RunCommand(command, pipes=pipes) |
| 86 | 89 |
| 87 | 90 |
| 88 def _GenerateJSONForTestResults(options, results_tracker): | 91 def _GenerateJSONForTestResults(options, results_tracker): |
| 89 """Generate (update) a JSON file from the gtest results XML and | 92 """Generate (update) a JSON file from the gtest results XML and |
| 90 upload the file to the archive server. | 93 upload the file to the archive server. |
| 91 The archived JSON file will be placed at: | 94 The archived JSON file will be placed at: |
| 92 www-dir/DEST_DIR/buildname/testname/results.json | 95 www-dir/DEST_DIR/buildname/testname/results.json |
| 93 on the archive server (NOTE: this is to be deprecated). | 96 on the archive server (NOTE: this is to be deprecated). |
| 94 Note that it adds slave's WebKit/Tools/Scripts to the PYTHONPATH | 97 Note that it adds slave's WebKit/Tools/Scripts to the PYTHONPATH |
| 95 to run the JSON generator. | 98 to run the JSON generator. |
| 96 | 99 |
| 97 Args: | 100 Args: |
| 98 options: command-line options that are supposed to have build_dir, | 101 options: command-line options that are supposed to have build_dir, |
| 99 results_directory, builder_name, build_name and test_output_xml values. | 102 results_directory, builder_name, build_name and test_output_xml values. |
| 100 """ | 103 """ |
| 101 # pylint: disable=W0703 | 104 # pylint: disable=W0703 |
| 102 results_map = None | 105 results_map = None |
| 103 try: | 106 try: |
| 104 if os.path.exists(options.test_output_xml): | 107 if os.path.exists(options.test_output_xml): |
| 105 results_map = gtest_slave_utils.GetResultsMapFromXML( | 108 results_map = gtest_slave_utils.GetResultsMapFromXML( |
| 106 options.test_output_xml) | 109 options.test_output_xml) |
| 107 else: | 110 else: |
| 108 sys.stderr.write('Unable to generate JSON from XML, using log output.') | 111 sys.stderr.write('Unable to generate JSON from XML, using log output.') |
| 109 # The file did not get generated. See if we can generate a results map | 112 # The file did not get generated. See if we can generate a results map |
| 110 # from the log output. | 113 # from the log output. |
| 111 results_map = results_tracker.GetResultsMap() | 114 results_map = gtest_slave_utils.GetResultsMap(results_tracker) |
| 112 except Exception, e: | 115 except Exception, e: |
| 113 # This error will be caught by the following 'not results_map' statement. | 116 # This error will be caught by the following 'not results_map' statement. |
| 114 print 'Error: ', e | 117 print 'Error: ', e |
| 115 | 118 |
| 116 if not results_map: | 119 if not results_map: |
| 117 print 'No data was available to update the JSON results' | 120 print 'No data was available to update the JSON results' |
| 118 return | 121 return |
| 119 | 122 |
| 120 build_dir = os.path.abspath(options.build_dir) | 123 build_dir = os.path.abspath(options.build_dir) |
| 121 slave_name = slave_utils.SlaveBuildName(build_dir) | 124 slave_name = slave_utils.SlaveBuildName(build_dir) |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 mime_types_path, | 184 mime_types_path, |
| 182 document_root) | 185 document_root) |
| 183 stop_cmd = platform_util.GetStopHttpdCommand() | 186 stop_cmd = platform_util.GetStopHttpdCommand() |
| 184 http_server = google.httpd_utils.ApacheHttpd(start_cmd, stop_cmd, [8000]) | 187 http_server = google.httpd_utils.ApacheHttpd(start_cmd, stop_cmd, [8000]) |
| 185 try: | 188 try: |
| 186 http_server.StartServer() | 189 http_server.StartServer() |
| 187 except google.httpd_utils.HttpdNotStarted, e: | 190 except google.httpd_utils.HttpdNotStarted, e: |
| 188 raise google.httpd_utils.HttpdNotStarted('%s. See log file in %s' % | 191 raise google.httpd_utils.HttpdNotStarted('%s. See log file in %s' % |
| 189 (e, output_dir)) | 192 (e, output_dir)) |
| 190 return http_server | 193 return http_server |
| 191 | 194 |
|
cmp
2012/06/28 19:14:16
nit: insert an empty line
| |
| 195 def getText(result, observer, name): | |
|
cmp
2012/06/28 19:14:16
please add a heredoc with a summary of this method
cmp
2012/06/28 20:59:08
just checking: is this only used by the annotate()
Mike Stip (use stip instead)
2012/07/11 00:10:41
yes, look at getText() in scripts/master/log_parse
| |
| 196 GTEST_DASHBOARD_BASE = ("http://test-results.appspot.com" | |
|
cmp
2012/06/28 20:59:08
nit: single quotes here and on line 197
| |
| 197 "/dashboards/flakiness_dashboard.html") | |
| 198 | |
| 199 basic_info = [name] | |
|
cmp
2012/06/28 20:59:08
can you add a comment before line 199 describing w
| |
| 200 | |
| 201 disabled = observer.DisabledTests() | |
| 202 if disabled: | |
| 203 basic_info.append('%s disabled' % str(disabled)) | |
| 204 | |
| 205 flaky = observer.FlakyTests() | |
| 206 if flaky: | |
| 207 basic_info.append('%s flaky' % str(flaky)) | |
| 208 | |
| 209 failed_test_count = len(observer.FailedTests()) | |
| 210 | |
| 211 if failed_test_count == 0: | |
| 212 if result is builder.SUCCESS: | |
| 213 return basic_info | |
| 214 elif result is builder.WARNINGS: | |
| 215 return basic_info + ['warnings'] | |
| 216 | |
| 217 if observer.RunningTests(): | |
| 218 basic_info += ['did not complete'] | |
| 219 | |
| 220 if failed_test_count: | |
| 221 failure_text = ['failed %d' % failed_test_count] | |
| 222 if observer.master_name: | |
| 223 # Include the link to the flakiness dashboard | |
| 224 failure_text.append('<div class="BuildResultInfo">') | |
| 225 failure_text.append('<a href="%s#master=%s&testType=%s' | |
| 226 '&tests=%s">' % ( | |
| 227 GTEST_DASHBOARD_BASE, observer.master_name, | |
| 228 name, | |
| 229 ','.join(observer.FailedTests()))) | |
| 230 failure_text.append('Flakiness dashboard') | |
| 231 failure_text.append('</a>') | |
| 232 failure_text.append('</div>') | |
| 233 else: | |
| 234 failure_text = ['crashed or hung'] | |
| 235 return basic_info + failure_text | |
| 236 | |
|
cmp
2012/06/28 19:14:16
nit: insert an empty line
| |
| 237 def annotate(test_name, result, results_tracker): | |
|
cmp
2012/06/28 19:14:16
please add a heredoc with a summary of this method
| |
| 238 get_text_result = builder.SUCCESS | |
| 239 | |
| 240 for failure in sorted(results_tracker.FailedTests()): | |
| 241 testabbr = re.sub(r'[^\w\.\-]', '_', failure.split('.')[-1]) | |
| 242 for line in results_tracker.FailureDescription(failure): | |
| 243 print '@@@STEP_LOG_LINE@%s@%s@@@' % (testabbr, line) | |
| 244 print '@@@STEP_LOG_END@%s@@@' % testabbr | |
| 245 | |
| 246 for suppression_hash in sorted(results_tracker.SuppressionHashes()): | |
| 247 for line in results_tracker.Suppression(suppression_hash): | |
| 248 print '@@@STEP_LOG_LINE@%s@%s@@@' % (testabbr, line) | |
| 249 print '@@@STEP_LOG_END@%s@@@' % testabbr | |
| 250 | |
| 251 if results_tracker.ParsingErrors(): | |
| 252 # Generate a log file containing the list of errors. | |
| 253 for line in results_tracker.ParsingErrors(): | |
| 254 print '@@@STEP_LOG_LINE@%s@%s@@@' % ('log parsing error(s)', line) | |
| 255 | |
| 256 print '@@@STEP_LOG_END@%s@@@' % 'log parsing error(s)' | |
| 257 results_tracker.ClearParsingErrors() | |
| 258 | |
| 259 if result is builder.SUCCESS: | |
| 260 if (len(results_tracker.ParsingErrors()) or | |
| 261 len(results_tracker.FailedTests()) or | |
| 262 len(results_tracker.SuppressionHashes())): | |
| 263 print '@@@STEP_WARNINGS@@@' | |
| 264 get_text_result = builder.WARNING | |
| 265 else: | |
| 266 print '@@@STEP_FAILURE@@@' | |
| 267 get_text_result = builder.FAILURE | |
| 268 | |
| 269 for desc in getText(get_text_result, results_tracker, test_name): | |
| 270 print '@@@STEP_TEXT@%s@@@' % desc | |
| 271 | |
| 272 | |
| 192 def main_mac(options, args): | 273 def main_mac(options, args): |
| 193 if len(args) < 1: | 274 if len(args) < 1: |
| 194 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) | 275 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) |
| 195 | 276 |
| 196 test_exe = args[0] | 277 test_exe = args[0] |
| 197 build_dir = os.path.normpath(os.path.abspath(options.build_dir)) | 278 build_dir = os.path.normpath(os.path.abspath(options.build_dir)) |
| 198 test_exe_path = os.path.join(build_dir, options.target, test_exe) | 279 test_exe_path = os.path.join(build_dir, options.target, test_exe) |
| 199 if not os.path.exists(test_exe_path): | 280 if not os.path.exists(test_exe_path): |
| 200 pre = 'Unable to find %s\n' % test_exe_path | 281 pre = 'Unable to find %s\n' % test_exe_path |
| 201 | 282 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 command.append(test_exe_path) | 316 command.append(test_exe_path) |
| 236 elif options.run_shell_script: | 317 elif options.run_shell_script: |
| 237 command = ['bash', test_exe_path] | 318 command = ['bash', test_exe_path] |
| 238 elif options.run_python_script: | 319 elif options.run_python_script: |
| 239 command = [sys.executable, test_exe] | 320 command = [sys.executable, test_exe] |
| 240 else: | 321 else: |
| 241 command = [test_exe_path] | 322 command = [test_exe_path] |
| 242 command.extend(args[1:]) | 323 command.extend(args[1:]) |
| 243 | 324 |
| 244 results_tracker = None | 325 results_tracker = None |
| 326 if options.generate_json_file or options.annotate: | |
| 327 results_tracker = gtest_utils.GTestLogParser() | |
| 328 | |
| 245 if options.generate_json_file: | 329 if options.generate_json_file: |
| 246 results_tracker = gtest_slave_utils.GTestUnexpectedDeathTracker() | |
| 247 | |
| 248 if os.path.exists(options.test_output_xml): | 330 if os.path.exists(options.test_output_xml): |
| 249 # remove the old XML output file. | 331 # remove the old XML output file. |
| 250 os.remove(options.test_output_xml) | 332 os.remove(options.test_output_xml) |
| 251 | 333 |
| 252 try: | 334 try: |
| 253 http_server = None | 335 http_server = None |
| 254 if options.document_root: | 336 if options.document_root: |
| 255 http_server = start_http_server('mac', build_dir=build_dir, | 337 http_server = start_http_server('mac', build_dir=build_dir, |
| 256 test_exe_path=test_exe_path, | 338 test_exe_path=test_exe_path, |
| 257 document_root=options.document_root) | 339 document_root=options.document_root) |
| 258 if options.factory_properties.get('asan', False): | 340 if options.factory_properties.get('asan', False): |
| 259 symbolize = os.path.abspath(os.path.join('src', 'tools', 'valgrind', | 341 symbolize = os.path.abspath(os.path.join('src', 'tools', 'valgrind', |
| 260 'asan', 'asan_symbolize.py')) | 342 'asan', 'asan_symbolize.py')) |
| 261 pipes = [[sys.executable, symbolize], ['c++filt']] | 343 pipes = [[sys.executable, symbolize], ['c++filt']] |
| 262 result = _RunGTestCommand(command, pipes=pipes) | 344 result = _RunGTestCommand(command, pipes=pipes) |
| 263 else: | 345 else: |
| 264 result = _RunGTestCommand(command, results_tracker) | 346 result = _RunGTestCommand(command, results_tracker) |
| 265 finally: | 347 finally: |
| 266 if http_server: | 348 if http_server: |
| 267 http_server.StopServer() | 349 http_server.StopServer() |
| 268 | 350 |
| 269 if options.generate_json_file: | 351 if options.generate_json_file: |
| 270 _GenerateJSONForTestResults(options, results_tracker) | 352 _GenerateJSONForTestResults(options, results_tracker) |
| 271 | 353 |
| 354 if options.annotate: | |
| 355 annotate(options.test_type, result, results_tracker) | |
| 356 | |
| 272 return result | 357 return result |
| 273 | 358 |
| 274 def main_linux(options, args): | 359 def main_linux(options, args): |
| 275 if len(args) < 1: | 360 if len(args) < 1: |
| 276 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) | 361 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) |
| 277 | 362 |
| 278 build_dir = os.path.normpath(os.path.abspath(options.build_dir)) | 363 build_dir = os.path.normpath(os.path.abspath(options.build_dir)) |
| 279 slave_name = slave_utils.SlaveBuildName(build_dir) | 364 slave_name = slave_utils.SlaveBuildName(build_dir) |
| 280 # If this is a sub-project build (i.e. there's a 'sconsbuild' in build_dir), | 365 # If this is a sub-project build (i.e. there's a 'sconsbuild' in build_dir), |
| 281 # look for the test binaries there, otherwise look for the top-level build | 366 # look for the test binaries there, otherwise look for the top-level build |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 358 command.append(test_exe_path) | 443 command.append(test_exe_path) |
| 359 elif options.run_shell_script: | 444 elif options.run_shell_script: |
| 360 command = ['bash', test_exe_path] | 445 command = ['bash', test_exe_path] |
| 361 elif options.run_python_script: | 446 elif options.run_python_script: |
| 362 command = [sys.executable, test_exe] | 447 command = [sys.executable, test_exe] |
| 363 else: | 448 else: |
| 364 command = [test_exe_path] | 449 command = [test_exe_path] |
| 365 command.extend(args[1:]) | 450 command.extend(args[1:]) |
| 366 | 451 |
| 367 results_tracker = None | 452 results_tracker = None |
| 453 if options.generate_json_file or options.annotate: | |
| 454 results_tracker = gtest_utils.GTestLogParser() | |
| 455 | |
| 368 if options.generate_json_file: | 456 if options.generate_json_file: |
| 369 results_tracker = gtest_slave_utils.GTestUnexpectedDeathTracker() | |
| 370 | |
| 371 if os.path.exists(options.test_output_xml): | 457 if os.path.exists(options.test_output_xml): |
| 372 # remove the old XML output file. | 458 # remove the old XML output file. |
| 373 os.remove(options.test_output_xml) | 459 os.remove(options.test_output_xml) |
| 374 | 460 |
| 375 try: | 461 try: |
| 376 http_server = None | 462 http_server = None |
| 377 if options.document_root: | 463 if options.document_root: |
| 378 http_server = start_http_server('linux', build_dir=build_dir, | 464 http_server = start_http_server('linux', build_dir=build_dir, |
| 379 test_exe_path=test_exe_path, | 465 test_exe_path=test_exe_path, |
| 380 document_root=options.document_root) | 466 document_root=options.document_root) |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 392 result = _RunGTestCommand(command, results_tracker) | 478 result = _RunGTestCommand(command, results_tracker) |
| 393 finally: | 479 finally: |
| 394 if http_server: | 480 if http_server: |
| 395 http_server.StopServer() | 481 http_server.StopServer() |
| 396 if options.xvfb: | 482 if options.xvfb: |
| 397 xvfb.StopVirtualX(slave_name) | 483 xvfb.StopVirtualX(slave_name) |
| 398 | 484 |
| 399 if options.generate_json_file: | 485 if options.generate_json_file: |
| 400 _GenerateJSONForTestResults(options, results_tracker) | 486 _GenerateJSONForTestResults(options, results_tracker) |
| 401 | 487 |
| 488 if options.annotate: | |
| 489 annotate(options.test_type, result, results_tracker) | |
| 490 | |
| 402 return result | 491 return result |
| 403 | 492 |
| 404 def main_win(options, args): | 493 def main_win(options, args): |
| 405 """Using the target build configuration, run the executable given in the | 494 """Using the target build configuration, run the executable given in the |
| 406 first non-option argument, passing any following arguments to that | 495 first non-option argument, passing any following arguments to that |
| 407 executable. | 496 executable. |
| 408 """ | 497 """ |
| 409 if len(args) < 1: | 498 if len(args) < 1: |
| 410 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) | 499 raise chromium_utils.MissingArgument('Usage: %s' % USAGE) |
| 411 | 500 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 439 command = [sys.executable, test_exe] | 528 command = [sys.executable, test_exe] |
| 440 else: | 529 else: |
| 441 command = [test_exe_path] | 530 command = [test_exe_path] |
| 442 command.extend(args[1:]) | 531 command.extend(args[1:]) |
| 443 | 532 |
| 444 # Nuke anything that appears to be stale chrome items in the temporary | 533 # Nuke anything that appears to be stale chrome items in the temporary |
| 445 # directory from previous test runs (i.e.- from crashes or unittest leaks). | 534 # directory from previous test runs (i.e.- from crashes or unittest leaks). |
| 446 slave_utils.RemoveChromeTemporaryFiles() | 535 slave_utils.RemoveChromeTemporaryFiles() |
| 447 | 536 |
| 448 results_tracker = None | 537 results_tracker = None |
| 538 if options.generate_json_file or options.annotate: | |
| 539 results_tracker = gtest_utils.GTestLogParser() | |
| 540 | |
| 449 if options.generate_json_file: | 541 if options.generate_json_file: |
| 450 results_tracker = gtest_slave_utils.GTestUnexpectedDeathTracker() | |
| 451 | |
| 452 if os.path.exists(options.test_output_xml): | 542 if os.path.exists(options.test_output_xml): |
| 453 # remove the old XML output file. | 543 # remove the old XML output file. |
| 454 os.remove(options.test_output_xml) | 544 os.remove(options.test_output_xml) |
| 455 | 545 |
| 456 try: | 546 try: |
| 457 http_server = None | 547 http_server = None |
| 458 if options.document_root: | 548 if options.document_root: |
| 459 http_server = start_http_server('win', build_dir=build_dir, | 549 http_server = start_http_server('win', build_dir=build_dir, |
| 460 test_exe_path=test_exe_path, | 550 test_exe_path=test_exe_path, |
| 461 document_root=options.document_root) | 551 document_root=options.document_root) |
| 462 result = _RunGTestCommand(command, results_tracker) | 552 result = _RunGTestCommand(command, results_tracker) |
| 463 finally: | 553 finally: |
| 464 if http_server: | 554 if http_server: |
| 465 http_server.StopServer() | 555 http_server.StopServer() |
| 466 | 556 |
| 467 if options.enable_pageheap: | 557 if options.enable_pageheap: |
| 468 slave_utils.SetPageHeap(build_dir, 'chrome.exe', False) | 558 slave_utils.SetPageHeap(build_dir, 'chrome.exe', False) |
| 469 | 559 |
| 470 if options.generate_json_file: | 560 if options.generate_json_file: |
| 471 _GenerateJSONForTestResults(options, results_tracker) | 561 _GenerateJSONForTestResults(options, results_tracker) |
| 472 | 562 |
| 563 if options.annotate: | |
| 564 annotate(options.test_type, result, results_tracker) | |
| 565 | |
| 473 return result | 566 return result |
| 474 | 567 |
| 475 | 568 |
| 476 def main(): | 569 def main(): |
| 477 import platform | 570 import platform |
| 478 | 571 |
| 479 xvfb_path = os.path.join(os.path.dirname(sys.argv[0]), '..', '..', | 572 xvfb_path = os.path.join(os.path.dirname(sys.argv[0]), '..', '..', |
| 480 'third_party', 'xvfb', platform.architecture()[0]) | 573 'third_party', 'xvfb', platform.architecture()[0]) |
| 481 | 574 |
| 482 # Initialize logging. | 575 # Initialize logging. |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 help="The name of the builder running this script.") | 653 help="The name of the builder running this script.") |
| 561 option_parser.add_option("", "--build-number", default=None, | 654 option_parser.add_option("", "--build-number", default=None, |
| 562 help=("The build number of the builder running" | 655 help=("The build number of the builder running" |
| 563 "this script.")) | 656 "this script.")) |
| 564 option_parser.add_option("", "--test-type", default='', | 657 option_parser.add_option("", "--test-type", default='', |
| 565 help="The test name that identifies the test, " | 658 help="The test name that identifies the test, " |
| 566 "e.g. 'unit-tests'") | 659 "e.g. 'unit-tests'") |
| 567 option_parser.add_option("", "--test-results-server", default='', | 660 option_parser.add_option("", "--test-results-server", default='', |
| 568 help="The test results server to upload the " | 661 help="The test results server to upload the " |
| 569 "results.") | 662 "results.") |
| 663 option_parser.add_option('', '--annotate', action='store_true', | |
| 664 dest = 'annotate', default=False, | |
| 665 help='Annotate output when run as a buildstep.') | |
| 570 chromium_utils.AddPropertiesOptions(option_parser) | 666 chromium_utils.AddPropertiesOptions(option_parser) |
| 571 options, args = option_parser.parse_args() | 667 options, args = option_parser.parse_args() |
| 572 | 668 |
| 573 if options.run_shell_script and options.run_python_script: | 669 if options.run_shell_script and options.run_python_script: |
| 574 sys.stderr.write('Use either --run-shell-script OR --run-python-script, ' | 670 sys.stderr.write('Use either --run-shell-script OR --run-python-script, ' |
| 575 'not both.') | 671 'not both.') |
| 576 return 1 | 672 return 1 |
| 577 | 673 |
| 578 # Print out builder name for log_parser | 674 # Print out builder name for log_parser |
| 579 print '[Running on builder: "%s"]' % options.builder_name | 675 print '[Running on builder: "%s"]' % options.builder_name |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 614 '%d new files were left in %s: Fix the tests to clean up themselves.' | 710 '%d new files were left in %s: Fix the tests to clean up themselves.' |
| 615 ) % ((new_temp_files - temp_files), tempfile.gettempdir()) | 711 ) % ((new_temp_files - temp_files), tempfile.gettempdir()) |
| 616 # TODO(maruel): Make it an error soon. Not yet since I want to iron out all | 712 # TODO(maruel): Make it an error soon. Not yet since I want to iron out all |
| 617 # the remaining cases before. | 713 # the remaining cases before. |
| 618 #result = 1 | 714 #result = 1 |
| 619 return result | 715 return result |
| 620 | 716 |
| 621 | 717 |
| 622 if '__main__' == __name__: | 718 if '__main__' == __name__: |
| 623 sys.exit(main()) | 719 sys.exit(main()) |
| OLD | NEW |