Home | History | Annotate | Download | only in valgrind
      1 #!/usr/bin/env python
      2 # Copyright (c) 2012 The LibYuv 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 libyuv 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   valgrind/tsan/suppressions.txt
     22   valgrind/tsan/suppressions_mac.txt
     23   valgrind/tsan/suppressions_win32.txt
     24 Since they're referenced from the chrome_tests.py script, we have similar files
     25 below the directory of this script. When executing, this script will setup both
     26 Chrome's suppression files and our own, so we can easily maintain libyuv
     27 specific suppressions in our own files.
     28 """
     29 
     30 import logging
     31 import optparse
     32 import os
     33 import sys
     34 
     35 import logging_utils
     36 import path_utils
     37 
     38 import chrome_tests
     39 
     40 
     41 class LibyuvTest(chrome_tests.ChromeTests):
     42   """Class that handles setup of suppressions for libyuv.
     43 
     44   Everything else is inherited from chrome_tests.ChromeTests.
     45   """
     46 
     47   def _DefaultCommand(self, tool, exe=None, valgrind_test_args=None):
     48     """Override command-building method so we can add more suppressions."""
     49     cmd = chrome_tests.ChromeTests._DefaultCommand(self, tool, exe,
     50                                                    valgrind_test_args)
     51     # When ChromeTests._DefaultCommand has executed, it has setup suppression
     52     # files based on what's found in the memcheck/ or tsan/ subdirectories of
     53     # this script's location. If Mac or Windows is executing, additional
     54     # platform specific files have also been added.
     55     # Since only the ones located below this directory is added, we must also
     56     # add the ones maintained by Chrome, located in ../../tools/valgrind.
     57 
     58     # The idea is to look for --suppression arguments in the cmd list and add a
     59     # modified copy of each suppression file, for the corresponding file in
     60     # ../../tools/valgrind.
     61     script_dir = path_utils.ScriptDir()
     62     old_base, _ = os.path.split(script_dir)
     63 
     64     checkout_src = os.path.abspath(os.path.join(script_dir, os.pardir,
     65                                                 os.pardir))
     66     new_dir = os.path.join(checkout_src, 'tools', 'valgrind')
     67     add_suppressions = []
     68     for token in cmd:
     69       if '--suppressions' in token:
     70         add_suppressions.append(token.replace(script_dir, new_dir))
     71     return add_suppressions + cmd
     72 
     73 
     74 def main(_):
     75   parser = optparse.OptionParser('usage: %prog -b <dir> -t <test> <test args>')
     76   parser.disable_interspersed_args()
     77   parser.add_option('-b', '--build-dir',
     78                     help=('Location of the compiler output. Can only be used '
     79                           'when the test argument does not contain this path.'))
     80   parser.add_option("--target", help="Debug or Release")
     81   parser.add_option('-t', '--test', help='Test to run.')
     82   parser.add_option('', '--baseline', action='store_true', default=False,
     83                     help='Generate baseline data instead of validating')
     84   parser.add_option('', '--gtest_filter',
     85                     help='Additional arguments to --gtest_filter')
     86   parser.add_option('', '--gtest_repeat',
     87                     help='Argument for --gtest_repeat')
     88   parser.add_option("--gtest_shuffle", action="store_true", default=False,
     89                     help="Randomize tests' orders on every iteration.")
     90   parser.add_option("--gtest_break_on_failure", action="store_true",
     91                     default=False,
     92                     help="Drop in to debugger on assertion failure. Also "
     93                          "useful for forcing tests to exit with a stack dump "
     94                          "on the first assertion failure when running with "
     95                          "--gtest_repeat=-1")
     96   parser.add_option('-v', '--verbose', action='store_true', default=False,
     97                     help='Verbose output - enable debug log messages')
     98   parser.add_option('', '--tool', dest='valgrind_tool', default='memcheck',
     99                     help='Specify a valgrind tool to run the tests under')
    100   parser.add_option('', '--tool_flags', dest='valgrind_tool_flags', default='',
    101                     help='Specify custom flags for the selected valgrind tool')
    102   parser.add_option('', '--keep_logs', action='store_true', default=False,
    103                     help=('Store memory tool logs in the <tool>.logs directory '
    104                           'instead of /tmp.\nThis can be useful for tool '
    105                           'developers/maintainers.\nPlease note that the <tool>'
    106                           '.logs directory will be clobbered on tool startup.'))
    107   parser.add_option("--test-launcher-bot-mode", action="store_true",
    108                     help="run the tests with --test-launcher-bot-mode")
    109   parser.add_option("--test-launcher-total-shards", type=int,
    110                     help="run the tests with --test-launcher-total-shards")
    111   parser.add_option("--test-launcher-shard-index", type=int,
    112                     help="run the tests with --test-launcher-shard-index")
    113   options, args = parser.parse_args()
    114 
    115   if options.verbose:
    116     logging_utils.config_root(logging.DEBUG)
    117   else:
    118     logging_utils.config_root()
    119 
    120   if not options.test:
    121     parser.error('--test not specified')
    122 
    123   # Support build dir both with and without the target.
    124   if (options.target and options.build_dir and
    125       not options.build_dir.endswith(options.target)):
    126     options.build_dir = os.path.join(options.build_dir, options.target)
    127 
    128   # If --build_dir is provided, prepend it to the test executable if needed.
    129   test_executable = options.test
    130   if options.build_dir and not test_executable.startswith(options.build_dir):
    131     test_executable = os.path.join(options.build_dir, test_executable)
    132   args = [test_executable] + args
    133 
    134   test = LibyuvTest(options, args, 'cmdline')
    135   return test.Run()
    136 
    137 if __name__ == '__main__':
    138   return_code = main(sys.argv)
    139   sys.exit(return_code)
    140