| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | |
| 3 # | |
| 4 # Use of this source code is governed by a BSD-style license | |
| 5 # that can be found in the LICENSE file in the root of the source | |
| 6 # tree. An additional intellectual property rights grant can be found | |
| 7 # in the file PATENTS. All contributing project authors may | |
| 8 # be found in the AUTHORS file in the root of the source tree. | |
| 9 | |
| 10 """Runs various WebRTC tests through valgrind_test.py. | |
| 11 | |
| 12 This script inherits the chrome_tests.py in Chrome, but allows running any test | |
| 13 instead of only the hard-coded ones. It uses the -t cmdline flag to do this, and | |
| 14 only supports specifying a single test for each run. | |
| 15 | |
| 16 Suppression files: | |
| 17 The Chrome valgrind directory we use as a DEPS dependency contains the following | |
| 18 suppression files: | |
| 19 valgrind/memcheck/suppressions.txt | |
| 20 valgrind/memcheck/suppressions_mac.txt | |
| 21 Since they're referenced from the chrome_tests.py script, we have similar files | |
| 22 below the directory of this script. When executing, this script will setup both | |
| 23 Chrome's suppression files and our own, so we can easily maintain WebRTC | |
| 24 specific suppressions in our own files. | |
| 25 """ | |
| 26 | |
| 27 import logging | |
| 28 import optparse | |
| 29 import os | |
| 30 import sys | |
| 31 | |
| 32 import logging_utils | |
| 33 import path_utils | |
| 34 | |
| 35 import chrome_tests | |
| 36 | |
| 37 | |
| 38 class WebRTCTest(chrome_tests.ChromeTests): | |
| 39 """Class that handles setup of suppressions for WebRTC. | |
| 40 | |
| 41 Everything else is inherited from chrome_tests.ChromeTests. | |
| 42 """ | |
| 43 | |
| 44 def __init__(self, test_name, options, args, test_in_chrome_tests): | |
| 45 """Create a WebRTC test. | |
| 46 Args: | |
| 47 test_name: Short name for the test executable (no path). | |
| 48 options: options to pass to ChromeTests. | |
| 49 args: args to pass to ChromeTests. | |
| 50 test_in_chrome_tests: The name of the test configuration in ChromeTests. | |
| 51 """ | |
| 52 self._test_name = test_name | |
| 53 chrome_tests.ChromeTests.__init__(self, options, args, test_in_chrome_tests) | |
| 54 | |
| 55 def _DefaultCommand(self, tool, exe=None, valgrind_test_args=None): | |
| 56 """Override command-building method so we can add more suppressions.""" | |
| 57 cmd = chrome_tests.ChromeTests._DefaultCommand(self, tool, exe, | |
| 58 valgrind_test_args) | |
| 59 | |
| 60 # Add gtest filters, if found. | |
| 61 chrome_tests.ChromeTests._AppendGtestFilter(self, tool, self._test_name, | |
| 62 cmd) | |
| 63 | |
| 64 # When ChromeTests._DefaultCommand has executed, it has setup suppression | |
| 65 # files based on what's found in the memcheck/ subdirectory of | |
| 66 # this script's location. If Mac or Windows is executing, additional | |
| 67 # platform specific files have also been added. | |
| 68 # Since only the ones located below this directory are added, we must also | |
| 69 # add the ones maintained by Chrome, located in ../valgrind. | |
| 70 | |
| 71 # The idea is to look for --suppression arguments in the cmd list and add a | |
| 72 # modified copy of each suppression file, for the corresponding file in | |
| 73 # ../valgrind. If we would simply replace 'valgrind-webrtc' with 'valgrind' | |
| 74 # we may produce invalid paths if other parts of the path contain that | |
| 75 # string. That's why the code below only replaces the end of the path. | |
| 76 script_dir = path_utils.ScriptDir() | |
| 77 old_base, _ = os.path.split(script_dir) | |
| 78 new_dir = os.path.join(old_base, 'valgrind') | |
| 79 add_suppressions = [] | |
| 80 for token in cmd: | |
| 81 if '--suppressions' in token: | |
| 82 add_suppressions.append(token.replace(script_dir, new_dir)) | |
| 83 return add_suppressions + cmd | |
| 84 | |
| 85 | |
| 86 def main(_): | |
| 87 parser = optparse.OptionParser( | |
| 88 'usage: %prog -b <dir> -t <test> -- <test args>') | |
| 89 parser.disable_interspersed_args() | |
| 90 parser.add_option('-b', '--build-dir', | |
| 91 help=('Location of the compiler output. Can only be used ' | |
| 92 'when the test argument does not contain this path.')) | |
| 93 parser.add_option("--target", help="Debug or Release") | |
| 94 parser.add_option('-t', '--test', help='Test to run.') | |
| 95 parser.add_option('', '--baseline', action='store_true', default=False, | |
| 96 help='Generate baseline data instead of validating') | |
| 97 parser.add_option('', '--gtest_filter', | |
| 98 help='Additional arguments to --gtest_filter') | |
| 99 parser.add_option('', '--gtest_repeat', | |
| 100 help='Argument for --gtest_repeat') | |
| 101 parser.add_option("--gtest_shuffle", action="store_true", default=False, | |
| 102 help="Randomize tests' orders on every iteration.") | |
| 103 parser.add_option("--gtest_break_on_failure", action="store_true", | |
| 104 default=False, | |
| 105 help="Drop in to debugger on assertion failure. Also " | |
| 106 "useful for forcing tests to exit with a stack dump " | |
| 107 "on the first assertion failure when running with " | |
| 108 "--gtest_repeat=-1") | |
| 109 parser.add_option('-v', '--verbose', action='store_true', default=False, | |
| 110 help='Verbose output - enable debug log messages') | |
| 111 parser.add_option('', '--tool', dest='valgrind_tool', default='memcheck', | |
| 112 help='Specify a valgrind tool to run the tests under') | |
| 113 parser.add_option('', '--tool_flags', dest='valgrind_tool_flags', default='', | |
| 114 help='Specify custom flags for the selected valgrind tool') | |
| 115 parser.add_option('', '--keep_logs', action='store_true', default=False, | |
| 116 help=('Store memory tool logs in the <tool>.logs directory ' | |
| 117 'instead of /tmp.\nThis can be useful for tool ' | |
| 118 'developers/maintainers.\nPlease note that the <tool>' | |
| 119 '.logs directory will be clobbered on tool startup.')) | |
| 120 parser.add_option("--test-launcher-bot-mode", action="store_true", | |
| 121 help="run the tests with --test-launcher-bot-mode") | |
| 122 parser.add_option("--test-launcher-total-shards", type=int, | |
| 123 help="run the tests with --test-launcher-total-shards") | |
| 124 parser.add_option("--test-launcher-shard-index", type=int, | |
| 125 help="run the tests with --test-launcher-shard-index") | |
| 126 options, args = parser.parse_args() | |
| 127 | |
| 128 if options.verbose: | |
| 129 logging_utils.config_root(logging.DEBUG) | |
| 130 else: | |
| 131 logging_utils.config_root() | |
| 132 | |
| 133 if not options.test: | |
| 134 parser.error('--test not specified') | |
| 135 | |
| 136 # Support build dir both with and without the target. | |
| 137 if (options.target and options.build_dir and | |
| 138 not options.build_dir.endswith(options.target)): | |
| 139 options.build_dir = os.path.join(options.build_dir, options.target) | |
| 140 | |
| 141 # If --build_dir is provided, prepend it to the test executable if needed. | |
| 142 test_executable = options.test | |
| 143 if options.build_dir and not test_executable.startswith(options.build_dir): | |
| 144 test_executable = os.path.join(options.build_dir, test_executable) | |
| 145 args = [test_executable] + args | |
| 146 | |
| 147 test = WebRTCTest(options.test, options, args, 'cmdline') | |
| 148 return test.Run() | |
| 149 | |
| 150 if __name__ == '__main__': | |
| 151 return_code = main(sys.argv) | |
| 152 sys.exit(return_code) | |
| OLD | NEW |