1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/gtest/rungtests.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,124 @@ 1.4 +#!/usr/bin/env python 1.5 +# 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + 1.10 +from __future__ import with_statement 1.11 +import sys, os 1.12 +from optparse import OptionParser 1.13 +import mozprocess, mozinfo, mozlog, mozcrash 1.14 + 1.15 +log = mozlog.getLogger('gtest') 1.16 + 1.17 +class GTests(object): 1.18 + # Time (seconds) to wait for test process to complete 1.19 + TEST_PROC_TIMEOUT = 1200 1.20 + # Time (seconds) in which process will be killed if it produces no output. 1.21 + TEST_PROC_NO_OUTPUT_TIMEOUT = 300 1.22 + 1.23 + def run_gtest(self, prog, xre_path, symbols_path=None): 1.24 + """ 1.25 + Run a single C++ unit test program. 1.26 + 1.27 + Arguments: 1.28 + * prog: The path to the test program to run. 1.29 + * env: The environment to use for running the program. 1.30 + * symbols_path: A path to a directory containing Breakpad-formatted 1.31 + symbol files for producing stack traces on crash. 1.32 + 1.33 + Return True if the program exits with a zero status, False otherwise. 1.34 + """ 1.35 + self.xre_path = xre_path 1.36 + env = self.build_environment() 1.37 + log.info("Running gtest") 1.38 + proc = mozprocess.ProcessHandler([prog, "-unittest"], 1.39 + cwd=os.getcwd(), 1.40 + env=env) 1.41 + #TODO: After bug 811320 is fixed, don't let .run() kill the process, 1.42 + # instead use a timeout in .wait() and then kill to get a stack. 1.43 + proc.run(timeout=GTests.TEST_PROC_TIMEOUT, 1.44 + outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT) 1.45 + proc.wait() 1.46 + if proc.timedOut: 1.47 + log.testFail("gtest | timed out after %d seconds", GTests.TEST_PROC_TIMEOUT) 1.48 + return False 1.49 + if mozcrash.check_for_crashes(os.getcwd(), symbols_path, test_name="gtest"): 1.50 + # mozcrash will output the log failure line for us. 1.51 + return False 1.52 + result = proc.proc.returncode == 0 1.53 + if not result: 1.54 + log.testFail("gtest | test failed with return code %d", proc.proc.returncode) 1.55 + return result 1.56 + 1.57 + def build_core_environment(self, env = {}): 1.58 + """ 1.59 + Add environment variables likely to be used across all platforms, including remote systems. 1.60 + """ 1.61 + env["MOZILLA_FIVE_HOME"] = self.xre_path 1.62 + env["MOZ_XRE_DIR"] = self.xre_path 1.63 + env["XPCOM_DEBUG_BREAK"] = "stack-and-abort" 1.64 + env["MOZ_CRASHREPORTER_NO_REPORT"] = "1" 1.65 + env["MOZ_CRASHREPORTER"] = "1" 1.66 + env["MOZ_RUN_GTEST"] = "1" 1.67 + # Normally we run with GTest default output, override this to use the TBPL test format. 1.68 + env["MOZ_TBPL_PARSER"] = "1" 1.69 + return env 1.70 + 1.71 + def build_environment(self): 1.72 + """ 1.73 + Create and return a dictionary of all the appropriate env variables and values. 1.74 + On a remote system, we overload this to set different values and are missing things like os.environ and PATH. 1.75 + """ 1.76 + if not os.path.isdir(self.xre_path): 1.77 + raise Exception("xre_path does not exist: %s", self.xre_path) 1.78 + env = dict(os.environ) 1.79 + env = self.build_core_environment(env) 1.80 + pathvar = "" 1.81 + if mozinfo.os == "linux": 1.82 + pathvar = "LD_LIBRARY_PATH" 1.83 + elif mozinfo.os == "mac": 1.84 + pathvar = "DYLD_LIBRARY_PATH" 1.85 + elif mozinfo.os == "win": 1.86 + pathvar = "PATH" 1.87 + if pathvar: 1.88 + if pathvar in env: 1.89 + env[pathvar] = "%s%s%s" % (self.xre_path, os.pathsep, env[pathvar]) 1.90 + else: 1.91 + env[pathvar] = self.xre_path 1.92 + return env 1.93 + 1.94 +class gtestOptions(OptionParser): 1.95 + def __init__(self): 1.96 + OptionParser.__init__(self) 1.97 + self.add_option("--xre-path", 1.98 + action = "store", type = "string", dest = "xre_path", 1.99 + default = None, 1.100 + help = "absolute path to directory containing XRE (probably xulrunner)") 1.101 + self.add_option("--symbols-path", 1.102 + action = "store", type = "string", dest = "symbols_path", 1.103 + default = None, 1.104 + help = "absolute path to directory containing breakpad symbols, or the URL of a zip file containing symbols") 1.105 + 1.106 +def main(): 1.107 + parser = gtestOptions() 1.108 + options, args = parser.parse_args() 1.109 + if not args: 1.110 + print >>sys.stderr, """Usage: %s <binary>""" % sys.argv[0] 1.111 + sys.exit(1) 1.112 + if not options.xre_path: 1.113 + print >>sys.stderr, """Error: --xre-path is required""" 1.114 + sys.exit(1) 1.115 + prog = os.path.abspath(args[0]) 1.116 + options.xre_path = os.path.abspath(options.xre_path) 1.117 + tester = GTests() 1.118 + try: 1.119 + result = tester.run_gtest(prog, options.xre_path, options.symbols_path) 1.120 + except Exception, e: 1.121 + log.error(str(e)) 1.122 + result = False 1.123 + sys.exit(0 if result else 1) 1.124 + 1.125 +if __name__ == '__main__': 1.126 + main() 1.127 +