Bug 1238305: Modify cppunittests to look up breakpad symbols for logged stack traces; r=ted
authorAaron Klotz <aklotz@mozilla.com>
Fri, 03 May 2019 13:00:46 -0600
changeset 534772 63bc837753d653ab13635e432400c1b6d31d12ca
parent 534771 0214c4b7b50c1f4ab7c8f29ce83666b1fbba91a2
child 534849 0119df88bee8139c1e4ddadb53ac3faaa6701fd2
child 534865 31e1cf4a6cb4d5b2395af96142f042cf330a0076
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs1238305
milestone68.0a1
first release with
nightly linux32
63bc837753d6 / 68.0a1 / 20190507214514 / files
nightly linux64
63bc837753d6 / 68.0a1 / 20190507214514 / files
nightly mac
63bc837753d6 / 68.0a1 / 20190507214514 / files
nightly win32
63bc837753d6 / 68.0a1 / 20190507214514 / files
nightly win64
63bc837753d6 / 68.0a1 / 20190507214514 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
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
@@ -396,33 +396,38 @@ class MachCommands(MachCommandBase):
         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
@@ -59,16 +59,17 @@ config = {
         "tools/*",
         "mozpack/*",
         "mozbuild/*",
     ],
     "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
@@ -31,16 +31,17 @@ config = {
         "modules/*",
         "mozbase/*",
         "tools/*",
     ],
     "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
@@ -54,16 +54,17 @@ config = {
         "tools/*",
         "mozpack/*",
         "mozbuild/*",
     ],
     "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
@@ -10,16 +10,17 @@ import os
 from optparse import OptionParser
 from os import environ as env
 import manifestparser
 import mozprocess
 import mozinfo
 import mozcrash
 import mozfile
 import mozlog
+import mozrunner.utils
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 
 # Export directory js/src for tests that need it.
 env['CPP_UNIT_TESTS_DIR_JS_SRC'] = os.path.abspath(os.path.join(SCRIPT_DIR, "..", ".."))
 
 
 class CPPUnitTests(object):
@@ -59,17 +60,22 @@ 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):
@@ -138,31 +144,37 @@ class CPPUnitTests(object):
 
             # media/mtransport tests statically link in NSS, which
             # causes ODR violations. See bug 1215679.
             assert 'ASAN_OPTIONS' not 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()
+        if utility_path:
+            self.fix_stack = mozrunner.utils.get_stack_fixer_function(
+                utility_path, symbols_path)
         self.log.suite_start(programs, name='cppunittest')
         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,
@@ -191,16 +203,20 @@ class CPPUnittestOptions(OptionParser):
                         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
 
@@ -252,18 +268,20 @@ def update_mozinfo():
         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()