testing/gtest/rungtests.py

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 #!/usr/bin/env python
     2 #
     3 # This Source Code Form is subject to the terms of the Mozilla Public
     4 # License, v. 2.0. If a copy of the MPL was not distributed with this
     5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
     7 from __future__ import with_statement
     8 import sys, os
     9 from optparse import OptionParser
    10 import mozprocess, mozinfo, mozlog, mozcrash
    12 log = mozlog.getLogger('gtest')
    14 class GTests(object):
    15     # Time (seconds) to wait for test process to complete
    16     TEST_PROC_TIMEOUT = 1200
    17     # Time (seconds) in which process will be killed if it produces no output.
    18     TEST_PROC_NO_OUTPUT_TIMEOUT = 300
    20     def run_gtest(self, prog, xre_path, symbols_path=None):
    21         """
    22         Run a single C++ unit test program.
    24         Arguments:
    25         * prog: The path to the test program to run.
    26         * env: The environment to use for running the program.
    27         * symbols_path: A path to a directory containing Breakpad-formatted
    28                         symbol files for producing stack traces on crash.
    30         Return True if the program exits with a zero status, False otherwise.
    31         """
    32         self.xre_path = xre_path
    33         env = self.build_environment()
    34         log.info("Running gtest")
    35         proc = mozprocess.ProcessHandler([prog, "-unittest"],
    36                                          cwd=os.getcwd(),
    37                                          env=env)
    38         #TODO: After bug 811320 is fixed, don't let .run() kill the process,
    39         # instead use a timeout in .wait() and then kill to get a stack.
    40         proc.run(timeout=GTests.TEST_PROC_TIMEOUT,
    41                  outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
    42         proc.wait()
    43         if proc.timedOut:
    44             log.testFail("gtest | timed out after %d seconds", GTests.TEST_PROC_TIMEOUT)
    45             return False
    46         if mozcrash.check_for_crashes(os.getcwd(), symbols_path, test_name="gtest"):
    47             # mozcrash will output the log failure line for us.
    48             return False
    49         result = proc.proc.returncode == 0
    50         if not result:
    51             log.testFail("gtest | test failed with return code %d", proc.proc.returncode)
    52         return result
    54     def build_core_environment(self, env = {}):
    55         """
    56         Add environment variables likely to be used across all platforms, including remote systems.
    57         """
    58         env["MOZILLA_FIVE_HOME"] = self.xre_path
    59         env["MOZ_XRE_DIR"] = self.xre_path
    60         env["XPCOM_DEBUG_BREAK"] = "stack-and-abort"
    61         env["MOZ_CRASHREPORTER_NO_REPORT"] = "1"
    62         env["MOZ_CRASHREPORTER"] = "1"
    63         env["MOZ_RUN_GTEST"] = "1"
    64         # Normally we run with GTest default output, override this to use the TBPL test format.
    65         env["MOZ_TBPL_PARSER"] = "1"
    66         return env
    68     def build_environment(self):
    69         """
    70         Create and return a dictionary of all the appropriate env variables and values.
    71         On a remote system, we overload this to set different values and are missing things like os.environ and PATH.
    72         """
    73         if not os.path.isdir(self.xre_path):
    74             raise Exception("xre_path does not exist: %s", self.xre_path)
    75         env = dict(os.environ)
    76         env = self.build_core_environment(env)
    77         pathvar = ""
    78         if mozinfo.os == "linux":
    79             pathvar = "LD_LIBRARY_PATH"
    80         elif mozinfo.os == "mac":
    81             pathvar = "DYLD_LIBRARY_PATH"
    82         elif mozinfo.os == "win":
    83             pathvar = "PATH"
    84         if pathvar:
    85             if pathvar in env:
    86                 env[pathvar] = "%s%s%s" % (self.xre_path, os.pathsep, env[pathvar])
    87             else:
    88                 env[pathvar] = self.xre_path
    89         return env
    91 class gtestOptions(OptionParser):
    92     def __init__(self):
    93         OptionParser.__init__(self)
    94         self.add_option("--xre-path",
    95                         action = "store", type = "string", dest = "xre_path",
    96                         default = None,
    97                         help = "absolute path to directory containing XRE (probably xulrunner)")
    98         self.add_option("--symbols-path",
    99                         action = "store", type = "string", dest = "symbols_path",
   100                         default = None,
   101                         help = "absolute path to directory containing breakpad symbols, or the URL of a zip file containing symbols")
   103 def main():
   104     parser = gtestOptions()
   105     options, args = parser.parse_args()
   106     if not args:
   107         print >>sys.stderr, """Usage: %s <binary>""" % sys.argv[0]
   108         sys.exit(1)
   109     if not options.xre_path:
   110         print >>sys.stderr, """Error: --xre-path is required"""
   111         sys.exit(1)
   112     prog = os.path.abspath(args[0])
   113     options.xre_path = os.path.abspath(options.xre_path)
   114     tester = GTests()
   115     try:
   116         result = tester.run_gtest(prog, options.xre_path, options.symbols_path)
   117     except Exception, e:
   118         log.error(str(e))
   119         result = False
   120     sys.exit(0 if result else 1)
   122 if __name__ == '__main__':
   123     main()

mercurial