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 12This script inherits the chrome_tests.py in Chrome, but allows running any test 13instead of only the hard-coded ones. It uses the -t cmdline flag to do this, and 14only supports specifying a single test for each run. 15 16Suppression files: 17The Chrome valgrind directory we use as a DEPS dependency contains the following 18suppression 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 24Since they're referenced from the chrome_tests.py script, we have similar files 25below the directory of this script. When executing, this script will setup both 26Chrome's suppression files and our own, so we can easily maintain libyuv 27specific suppressions in our own files. 28""" 29 30import logging 31import optparse 32import os 33import sys 34 35import logging_utils 36import path_utils 37 38import chrome_tests 39 40 41class 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 74def 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 137if __name__ == '__main__': 138 return_code = main(sys.argv) 139 sys.exit(return_code) 140