Bug 1238305: Modify cppunittests to look up breakpad symbols for logged stack traces; r=ted
☠☠ backed out by aeacd77c05b5 ☠ ☠
authorAaron Klotz <aklotz@mozilla.com>
Tue, 12 Jan 2016 12:58:59 -0700
changeset 318698 c6617c4a27b44cc66691c1d2bb50e8546f548632
parent 318697 7ae2adc4bb4400d9f6bf52eee2b046c3644c8776
child 318699 ae0bcfbfe71db3f1730cdd02c76ede88ce486cb8
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1238305
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1238305: Modify cppunittests to look up breakpad symbols for logged stack traces; r=ted
testing/mach_commands.py
testing/mozharness/configs/unittests/linux_unittest.py
testing/mozharness/configs/unittests/mac_unittest.py
testing/mozharness/configs/unittests/win_unittest.py
testing/runcppunittests.py
--- a/testing/mach_commands.py
+++ b/testing/mach_commands.py
@@ -352,33 +352,38 @@ class MachCommands(MachCommandBase):
         # If no tests specified, run all tests in main manifest
         tests = params['test_files']
         if len(tests) == 0:
             tests = [os.path.join(self.distdir, 'cppunittests')]
             manifest_path = os.path.join(self.topsrcdir, 'testing', 'cppunittest.ini')
         else:
             manifest_path = None
 
+        utility_path = self.bindir
+
         if conditions.is_android(self):
             from mozrunner.devices.android_device import verify_android_device
             verify_android_device(self, install=False)
             return self.run_android_test(tests, symbols_path, manifest_path, log)
 
-        return self.run_desktop_test(tests, symbols_path, manifest_path, log)
+        return self.run_desktop_test(tests, symbols_path, manifest_path,
+                                     utility_path, log)
 
-    def run_desktop_test(self, tests, symbols_path, manifest_path, log):
+    def run_desktop_test(self, tests, symbols_path, manifest_path, utility_path,
+                         log):
         import runcppunittests as cppunittests
         from mozlog import commandline
 
         parser = cppunittests.CPPUnittestOptions()
         commandline.add_logging_group(parser)
         options, args = parser.parse_args()
 
         options.symbols_path = symbols_path
         options.manifest_path = manifest_path
+        options.utility_path = utility_path
         options.xre_path = self.bindir
 
         try:
             result = cppunittests.run_test_harness(options, tests)
         except Exception as e:
             log.error("Caught exception running cpp unit tests: %s" % str(e))
             result = False
             raise
--- a/testing/mozharness/configs/unittests/linux_unittest.py
+++ b/testing/mozharness/configs/unittests/linux_unittest.py
@@ -64,16 +64,17 @@ config = {
         "jittest": ["jit-test/*"],
         "mozbase": ["mozbase/*"],
         "mozmill": ["mozmill/*"],
     },
     "suite_definitions": {
         "cppunittest": {
             "options": [
                 "--symbols-path=%(symbols_path)s",
+                "--utility-path=tests/bin",
                 "--xre-path=%(abs_app_dir)s"
             ],
             "run_filename": "runcppunittests.py",
             "testsdir": "cppunittest"
         },
         "jittest": {
             "options": [
                 "tests/bin/js",
--- a/testing/mozharness/configs/unittests/mac_unittest.py
+++ b/testing/mozharness/configs/unittests/mac_unittest.py
@@ -53,16 +53,17 @@ config = {
         "jittest": ["jit-test/*"],
         "mozbase": ["mozbase/*"],
         "mozmill": ["mozmill/*"],
     },
     "suite_definitions": {
         "cppunittest": {
             "options": [
                 "--symbols-path=%(symbols_path)s",
+                "--utility-path=tests/bin",
                 "--xre-path=%(abs_res_dir)s"
             ],
             "run_filename": "runcppunittests.py",
             "testsdir": "cppunittest"
         },
         "jittest": {
             "options": [
                 "tests/bin/js",
--- a/testing/mozharness/configs/unittests/win_unittest.py
+++ b/testing/mozharness/configs/unittests/win_unittest.py
@@ -62,16 +62,17 @@ config = {
         "jittest": ["jit-test/*"],
         "mozbase": ["mozbase/*"],
         "mozmill": ["mozmill/*"],
     },
     "suite_definitions": {
         "cppunittest": {
             "options": [
                 "--symbols-path=%(symbols_path)s",
+                "--utility-path=tests/bin",
                 "--xre-path=%(abs_app_dir)s"
             ],
             "run_filename": "runcppunittests.py",
             "testsdir": "cppunittest"
         },
         "jittest": {
             "options": [
                 "tests/bin/js",
--- a/testing/runcppunittests.py
+++ b/testing/runcppunittests.py
@@ -9,16 +9,17 @@ import sys, os, tempfile, shutil
 from optparse import OptionParser
 import manifestparser
 import mozprocess
 import mozinfo
 import mozcrash
 import mozfile
 import mozlog
 from contextlib import contextmanager
+from mozrunner.utils import get_stack_fixer_function
 from subprocess import PIPE
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 
 class CPPUnitTests(object):
     # Time (seconds) to wait for test process to complete
     TEST_PROC_TIMEOUT = 900
     # Time (seconds) in which process will be killed if it produces no output.
@@ -55,17 +56,21 @@ class CPPUnitTests(object):
                                                  processOutputLine=lambda _: None)
             #TODO: After bug 811320 is fixed, don't let .run() kill the process,
             # instead use a timeout in .wait() and then kill to get a stack.
             test_timeout = CPPUnitTests.TEST_PROC_TIMEOUT * timeout_factor
             proc.run(timeout=test_timeout,
                      outputTimeout=CPPUnitTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
             proc.wait()
             if proc.output:
-                output = "\n%s" % "\n".join(proc.output)
+                if self.fix_stack:
+                    procOutput = [self.fix_stack(l) for l in proc.output]
+                else:
+                    procOutput = proc.output
+                output = "\n%s" % "\n".join(procOutput)
                 self.log.process_output(proc.pid, output, command=[prog])
             if proc.timedOut:
                 message = "timed out after %d seconds" % CPPUnitTests.TEST_PROC_TIMEOUT
                 self.log.test_end(basename, status='TIMEOUT', expected='PASS',
                                   message=message)
                 return False
             if mozcrash.check_for_crashes(tempdir, symbols_path,
                                           test_name=basename):
@@ -132,31 +137,34 @@ class CPPUnitTests(object):
 
             # media/mtransport tests statically link in NSS, which
             # causes ODR violations. See bug 1215679.
             assert not 'ASAN_OPTIONS' in env
             env['ASAN_OPTIONS'] = 'detect_leaks=0:detect_odr_violation=0'
 
         return env
 
-    def run_tests(self, programs, xre_path, symbols_path=None, interactive=False):
+    def run_tests(self, programs, xre_path, symbols_path=None, utility_path=None, interactive=False):
         """
         Run a set of C++ unit test programs.
 
         Arguments:
         * programs: An iterable containing (test path, test timeout factor) tuples
         * xre_path: A path to a directory containing a XUL Runtime Environment.
         * symbols_path: A path to a directory containing Breakpad-formatted
                         symbol files for producing stack traces on crash.
+        * utility_path: A path to a directory containing utility programs
+                        (xpcshell et al)
 
         Returns True if all test programs exited with a zero status, False
         otherwise.
         """
         self.xre_path = xre_path
         self.log = mozlog.get_default_logger()
+        self.fix_stack = get_stack_fixer_function(utility_path, symbols_path)
         self.log.suite_start(programs)
         env = self.build_environment()
         pass_count = 0
         fail_count = 0
         for prog in programs:
             test_path = prog[0]
             timeout_factor = prog[1]
             single_result = self.run_one_test(test_path, env, symbols_path,
@@ -183,16 +191,20 @@ class CPPUnittestOptions(OptionParser):
         self.add_option("--symbols-path",
                         action = "store", type = "string", dest = "symbols_path",
                         default = None,
                         help = "absolute path to directory containing breakpad symbols, or the URL of a zip file containing symbols")
         self.add_option("--manifest-path",
                         action = "store", type = "string", dest = "manifest_path",
                         default = None,
                         help = "path to test manifest, if different from the path to test binaries")
+        self.add_option("--utility-path",
+                        action = "store", type = "string", dest = "utility_path",
+                        default = None,
+                        help = "path to directory containing utility programs")
 
 def extract_unittests_from_args(args, environ, manifest_path):
     """Extract unittests from args, expanding directories as needed"""
     mp = manifestparser.TestManifest(strict=True)
     tests = []
     binary_path = None
 
     if manifest_path:
@@ -232,18 +244,20 @@ def update_mozinfo():
         dirs.add(path)
         path = os.path.split(path)[0]
     mozinfo.find_and_update_from_json(*dirs)
 
 def run_test_harness(options, args):
     update_mozinfo()
     progs = extract_unittests_from_args(args, mozinfo.info, options.manifest_path)
     options.xre_path = os.path.abspath(options.xre_path)
+    options.utility_path = os.path.abspath(options.utility_path)
     tester = CPPUnitTests()
-    result = tester.run_tests(progs, options.xre_path, options.symbols_path)
+    result = tester.run_tests(progs, options.xre_path, options.symbols_path,
+                              options.utility_path)
 
     return result
 
 def main():
     parser = CPPUnittestOptions()
     mozlog.commandline.add_logging_group(parser)
     options, args = parser.parse_args()
     if not args: