Beispiel #1
0
    def cleanupAndCheckForCrashes(self, browser_config, profile_dir, test_name):
        """cleanup browser processes and process crashes if found"""

        # cleanup processes
        self._ffprocess.cleanupProcesses(browser_config['process'],
                                         browser_config['child_process'],
                                         browser_config['browser_wait'])

        # find stackwalk binary
        if platform.system() in ('Windows', 'Microsoft'):
            stackwalkpaths = ['win32', 'minidump_stackwalk.exe']
        elif platform.system() == 'Linux':
            # are we 64 bit?
            if '64' in platform.architecture()[0]:
                stackwalkpaths = ['linux64', 'minidump_stackwalk']
            else:
                stackwalkpaths = ['linux', 'minidump_stackwalk']
        elif platform.system() == 'Darwin':
            stackwalkpaths = ['osx', 'minidump_stackwalk']
        else:
            # no minidump_stackwalk available for your platform
            return
        stackwalkbin = os.path.join(os.path.dirname(__file__), 'breakpad', *stackwalkpaths)
        assert os.path.exists(stackwalkbin), "minidump_stackwalk binary not found: %s" % stackwalkbin

        if browser_config['remote'] is True:
            # favour using Java exceptions in the logcat over minidumps
            if os.path.exists('logcat.log'):
                with open('logcat.log') as f:
                    logcat = f.read().split('\r')
                found = mozcrash.check_for_java_exception(logcat)

            remoteminidumpdir = profile_dir + '/minidumps/'
            if not found:
                # check for minidumps
                minidumpdir = tempfile.mkdtemp()
                try:
                    if self._ffprocess.testAgent.dirExists(remoteminidumpdir):
                        self._ffprocess.testAgent.getDirectory(remoteminidumpdir, minidumpdir)
                except mozdevice.DMError:
                    print "Remote Device Error: Error getting crash minidumps from device"
                    raise
                found = mozcrash.check_for_crashes(minidumpdir,
                                                   browser_config['symbols_path'],
                                                   stackwalk_binary=stackwalkbin,
                                                   test_name=test_name)
                self._hostproc.removeDirectory(minidumpdir)

            # cleanup dumps on remote
            self._ffprocess.testAgent.removeDir(remoteminidumpdir)
        else:
            # check for minidumps
            minidumpdir = os.path.join(profile_dir, 'minidumps')
            found = mozcrash.check_for_crashes(minidumpdir,
                                               browser_config['symbols_path'],
                                               stackwalk_binary=stackwalkbin,
                                               test_name=test_name)

        if found:
            raise talosCrash("Found crashes after test run, terminating test")
Beispiel #2
0
 def checkForCrashes(self, directory, symbolsPath):
     crashed = False
     remote_dump_dir = self._remoteProfile + '/minidumps'
     print "checking for crashes in '%s'" % remote_dump_dir
     if self._devicemanager.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             logger = get_default_logger()
             if logger is not None:
                 crashed = mozcrash.log_crashes(logger,
                                                local_dump_dir,
                                                symbolsPath,
                                                test=self.lastTestSeen)
             else:
                 crashed = mozcrash.check_for_crashes(
                     local_dump_dir,
                     symbolsPath,
                     test_name=self.lastTestSeen)
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self._devicemanager.removeDir(remote_dump_dir)
     return crashed
Beispiel #3
0
 def check_for_crashes(self, symbols_path):
     """
        Pull minidumps from the remote device and generate crash reports.
        Returns True if a crash was detected, or suspected.
     """
     try:
         dump_dir = tempfile.mkdtemp()
         remote_dir = self.remote_minidumps
         if not self.device.is_dir(remote_dir):
             log.warning("No crash directory (%s) found on remote device" %
                         remote_dir)
             return True
         self.device.pull(remote_dir, dump_dir)
         crashed = mozcrash.check_for_crashes(dump_dir,
                                              symbols_path,
                                              test_name="gtest")
     except Exception as e:
         log.error("unable to check for crashes: %s" % str(e))
         crashed = True
     finally:
         try:
             shutil.rmtree(dump_dir)
         except Exception:
             log.warning("unable to remove directory: %s" % dump_dir)
     return crashed
Beispiel #4
0
    def check_for_crashes(self, dump_directory=None, dump_save_path=None,
                          test_name=None, quiet=False):
        """
        Check for a possible crash and output stack trace.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout
        :returns: True if a crash was detected, otherwise False
        """
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        crashed = False
        try:
            crashed = mozcrash.check_for_crashes(dump_directory,
                                                 self.symbols_path,
                                                 dump_save_path=dump_save_path,
                                                 test_name=test_name,
                                                 quiet=quiet)
        except:
            traceback.print_exc()

        return crashed
    def run_one_test(self, prog, env, symbols_path=None):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        log.info("Running test %s", basename)
        with TemporaryDirectory() as tempdir:
            proc = mozprocess.ProcessHandler([prog],
                                             cwd=tempdir,
                                             env=env)
            #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.
            proc.run(timeout=CPPUnitTests.TEST_PROC_TIMEOUT)
            proc.wait()
            if proc.timedOut:
                log.testFail("%s | timed out after %d seconds",
                             basename, CPPUnitTests.TEST_PROC_TIMEOUT)
                return False
            if mozcrash.check_for_crashes(tempdir, symbols_path,
                                          test_name=basename):
                log.testFail("%s | test crashed", basename)
                return False
            result = proc.proc.returncode == 0
            if not result:
                log.testFail("%s | test failed with return code %d",
                             basename, proc.proc.returncode)
            return result
Beispiel #6
0
    def test_symbol_path_url(self):
        """
        Test that passing a URL as symbols_path correctly fetches the URL.
        """
        open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
        self.stdouts.append(["this is some output"])

        def make_zipfile():
            data = StringIO.StringIO()
            z = zipfile.ZipFile(data, 'w')
            z.writestr("symbols.txt", "abc/xyz")
            z.close()
            return data.getvalue()
        def get_symbols(req):
            headers = {}
            return (200, headers, make_zipfile())
        httpd = mozhttpd.MozHttpd(port=0,
                                  urlhandlers=[{'method':'GET', 'path':'/symbols', 'function':get_symbols}])
        httpd.start()
        symbol_url = urlparse.urlunsplit(('http', '%s:%d' % httpd.httpd.server_address,
                                        '/symbols','',''))
        self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                                symbol_url,
                                                stackwalk_binary=self.stackwalk,
                                                quiet=True))
Beispiel #7
0
 def test_symbol_path_not_present(self):
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             symbols_path=None,
                                             stackwalk_binary=self.stackwalk,
                                             quiet=True))
    def run_one_test(self, prog, env, symbols_path=None, interactive=False):
        """
        Run a single C++ unit test program remotely.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        remote_bin = posixpath.join(self.remote_bin_dir, basename)
        self.log.test_start(basename)
        buf = StringIO.StringIO()
        returncode = self.device.shell([remote_bin], buf, env=env, cwd=self.remote_home_dir,
                                       timeout=cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT)
        self.log.process_output(basename, "\n%s" % buf.getvalue(),
                                command=[remote_bin])
        with mozfile.TemporaryDirectory() as tempdir:
            self.device.getDirectory(self.remote_home_dir, tempdir)
            if mozcrash.check_for_crashes(tempdir, symbols_path,
                                          test_name=basename):
                self.log.test_end(basename, status='CRASH', expected='PASS')
                return False
        result = returncode == 0
        if not result:
            self.log.test_end(basename, status='FAIL', expected='PASS',
                              message=("test failed with return code %d" %
                                       returncode))
        else:
            self.log.test_end(basename, status='PASS', expected='PASS')
        return result
    def run_one_test(self, prog, env, symbols_path=None):
        """
        Run a single C++ unit test program remotely.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        remote_bin = posixpath.join(self.remote_bin_dir, basename)
        log.info("Running test %s", basename)
        buf = StringIO.StringIO()
        returncode = self.device.shell(
            [remote_bin],
            buf,
            env=env,
            cwd=self.remote_home_dir,
            timeout=cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT)
        print >> sys.stdout, buf.getvalue()
        with mozfile.TemporaryDirectory() as tempdir:
            self.device.getDirectory(self.remote_home_dir, tempdir)
            if mozcrash.check_for_crashes(tempdir,
                                          symbols_path,
                                          test_name=basename):
                log.testFail("%s | test crashed", basename)
                return False
        result = returncode == 0
        if not result:
            log.testFail("%s | test failed with return code %s", basename,
                         returncode)
        return result
Beispiel #10
0
    def run_gtest(self, prog, xre_path, symbols_path=None):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        self.xre_path = xre_path
        env = self.build_environment()
        log.info("Running gtest")
        proc = mozprocess.ProcessHandler([prog, "-unittest"],
                                         cwd=os.getcwd(),
                                         env=env)
        #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.
        proc.run(timeout=GTests.TEST_PROC_TIMEOUT,
                 outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
        proc.wait()
        if proc.timedOut:
            log.testFail("gtest | timed out after %d seconds", GTests.TEST_PROC_TIMEOUT)
            return False
        if mozcrash.check_for_crashes(os.getcwd(), symbols_path, test_name="gtest"):
            # mozcrash will output the log failure line for us.
            return False
        result = proc.proc.returncode == 0
        if not result:
            log.testFail("gtest | test failed with return code %d", proc.proc.returncode)
        return result
Beispiel #11
0
    def run_one_test(self, prog, env, symbols_path=None, interactive=False,
                     timeout_factor=1):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.
        * timeout_factor: An optional test-specific timeout multiplier.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        self.log.test_start(basename)
        with mozfile.TemporaryDirectory() as tempdir:
            if interactive:
                # For tests run locally, via mach, print output directly
                proc = mozprocess.ProcessHandler([prog],
                                                 cwd=tempdir,
                                                 env=env,
                                                 storeOutput=False)
            else:
                proc = mozprocess.ProcessHandler([prog],
                                                 cwd=tempdir,
                                                 env=env,
                                                 storeOutput=True,
                                                 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:
                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):
                self.log.test_end(basename, status='CRASH', expected='PASS')
                return False
            result = proc.proc.returncode == 0
            if not result:
                self.log.test_end(basename, status='FAIL', expected='PASS',
                                  message=("test failed with return code %d" %
                                           proc.proc.returncode))
            else:
                self.log.test_end(basename, status='PASS', expected='PASS')
            return result
Beispiel #12
0
 def test_symbol_path_not_present(self):
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             symbols_path=None,
                                             stackwalk_binary=self.stackwalk,
                                             quiet=True))
Beispiel #13
0
    def test_symbol_path_url(self):
        """
        Test that passing a URL as symbols_path correctly fetches the URL.
        """
        open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
        self.stdouts.append(["this is some output"])

        def make_zipfile():
            data = StringIO.StringIO()
            z = zipfile.ZipFile(data, 'w')
            z.writestr("symbols.txt", "abc/xyz")
            z.close()
            return data.getvalue()

        def get_symbols(req):
            headers = {}
            return (200, headers, make_zipfile())

        httpd = mozhttpd.MozHttpd(port=0,
                                  urlhandlers=[{
                                      'method': 'GET',
                                      'path': '/symbols',
                                      'function': get_symbols
                                  }])
        httpd.start()
        symbol_url = urlparse.urlunsplit(
            ('http', '%s:%d' % httpd.httpd.server_address, '/symbols', '', ''))
        self.assert_(
            mozcrash.check_for_crashes(self.tempdir,
                                       symbol_url,
                                       stackwalk_binary=self.stackwalk,
                                       quiet=True))
Beispiel #14
0
    def run_one_test(self, prog, env, symbols_path=None):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        log.info("Running test %s", basename)
        with TemporaryDirectory() as tempdir:
            proc = mozprocess.ProcessHandler([prog], cwd=tempdir, env=env)
            #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.
            proc.run(timeout=CPPUnitTests.TEST_PROC_TIMEOUT,
                     outputTimeout=CPPUnitTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
            proc.wait()
            if proc.timedOut:
                log.testFail("%s | timed out after %d seconds", basename,
                             CPPUnitTests.TEST_PROC_TIMEOUT)
                return False
            if mozcrash.check_for_crashes(tempdir,
                                          symbols_path,
                                          test_name=basename):
                log.testFail("%s | test crashed", basename)
                return False
            result = proc.proc.returncode == 0
            if not result:
                log.testFail("%s | test failed with return code %d", basename,
                             proc.proc.returncode)
            return result
def get_crashreports(directory, name=None):
    rc = 0
    upload_path = os.environ.get("UPLOAD_PATH")
    if upload_path:
        # For automation, log the minidumps with stackwalk and get them moved to
        # the artifacts directory.
        fetches_dir = os.environ.get("MOZ_FETCHES_DIR")
        if not fetches_dir:
            raise Exception(
                "Unable to process minidump in automation because "
                "$MOZ_FETCHES_DIR is not set in the environment"
            )
        stackwalk_binary = os.path.join(
            fetches_dir, "minidump_stackwalk", "minidump_stackwalk"
        )
        if sys.platform == "win32":
            stackwalk_binary += ".exe"
        minidump_path = os.path.join(directory, "minidumps")
        rc = mozcrash.check_for_crashes(
            minidump_path,
            symbols_path=fetches_dir,
            stackwalk_binary=stackwalk_binary,
            dump_save_path=upload_path,
            test_name=name,
        )
    return rc
def checkCrashesAtExit():
    if mozcrash.check_for_crashes(dump_directory=os.path.join(
            PROFILE_DIR, 'minidumps'),
                                  symbols_path=SYMBOLS_PATH,
                                  test_name=TEST_NAME):
        print >> sys.stderr, 'TinderboxPrint: ' + TEST_NAME + '<br/><em class="testfail">CRASH</em>'
        sys.exit(1)
Beispiel #17
0
    def check_for_crashes(self,
                          dump_directory=None,
                          dump_save_path=None,
                          test_name=None,
                          quiet=False):
        """
        Check for a possible crash and output stack trace.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout
        :returns: True if a crash was detected, otherwise False
        """
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        crashed = False
        try:
            crashed = mozcrash.check_for_crashes(dump_directory,
                                                 self.symbols_path,
                                                 dump_save_path=dump_save_path,
                                                 test_name=test_name,
                                                 quiet=quiet)
        except:
            traceback.print_exc()

        return crashed
    def run_one_test(self, prog, env, symbols_path=None):
        """
        Run a single C++ unit test program remotely.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        remote_bin = posixpath.join(self.remote_bin_dir, basename)
        log.info("Running test %s", basename)
        buf = StringIO.StringIO()
        returncode = self.device.shell([remote_bin], buf, env=env, cwd=self.remote_home_dir,
                                       timeout=cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT)
        print >> sys.stdout, buf.getvalue()
        with mozfile.TemporaryDirectory() as tempdir:
            self.device.getDirectory(self.remote_home_dir, tempdir)
            if mozcrash.check_for_crashes(tempdir, symbols_path,
                                          test_name=basename):
                log.testFail("%s | test crashed", basename)
                return False
        result = returncode == 0
        if not result:
            log.testFail("%s | test failed with return code %s",
                         basename, returncode)
        return result
Beispiel #19
0
    def check_for_crashes(self, dump_directory=None, dump_save_path=None, test_name=None, quiet=False):
        """
        Check for a possible crash and output stack trace.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout
        :returns: True if a crash was detected, otherwise False
        """
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, "minidumps")

        if not dump_save_path:
            dump_save_path = self.dump_save_path

        try:
            logger = get_default_logger()
            if logger is not None:
                if test_name is None:
                    test_name = "runner.py"
                self.crashed += mozcrash.log_crashes(
                    logger, dump_directory, self.symbols_path, dump_save_path=dump_save_path, test=test_name
                )
            else:
                crashed = mozcrash.check_for_crashes(
                    dump_directory, self.symbols_path, dump_save_path=dump_save_path, test_name=test_name, quiet=quiet
                )
                if crashed:
                    self.crashed += 1
        except:
            traceback.print_exc()

        return self.crashed
    def run_gtest(self, prog, xre_path, cwd, symbols_path=None,
                  utility_path=None, enable_webrender=False):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * cwd: The directory to run tests from (support files will be found
               in this direcotry).
        * 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.
                        currently used to locate a stack fixer to provide
                        symbols symbols for assertion stacks.

        Return True if the program exits with a zero status, False otherwise.
        """
        self.xre_path = xre_path
        env = self.build_environment(enable_webrender)
        log.info("Running gtest")

        if cwd and not os.path.isdir(cwd):
            os.makedirs(cwd)

        stream_output = mozprocess.StreamOutput(sys.stdout)
        process_output = stream_output
        if utility_path:
            stack_fixer = get_stack_fixer_function(utility_path, symbols_path)
            if stack_fixer:
                def f(line): return stream_output(stack_fixer(line))
                process_output = f

        proc = mozprocess.ProcessHandler([prog, "-unittest",
                                         "--gtest_death_test_style=threadsafe"],
                                         cwd=cwd,
                                         env=env,
                                         processOutputLine=process_output)
        # 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.
        proc.run(timeout=GTests.TEST_PROC_TIMEOUT,
                 outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
        proc.wait()
        log.info("gtest | process wait complete, returncode=%s" % proc.proc.returncode)
        if proc.timedOut:
            if proc.outputTimedOut:
                log.testFail("gtest | timed out after %d seconds without output",
                             GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
            else:
                log.testFail("gtest | timed out after %d seconds",
                             GTests.TEST_PROC_TIMEOUT)
            return False
        if mozcrash.check_for_crashes(cwd, symbols_path, test_name="gtest"):
            # mozcrash will output the log failure line for us.
            return False
        result = proc.proc.returncode == 0
        if not result:
            log.testFail("gtest | test failed with return code %d", proc.proc.returncode)
        return result
Beispiel #21
0
 def test_nodumps(self):
     """
     Test that check_for_crashes returns False if no dumps are present.
     """
     self.stdouts.append(["this is some output"])
     self.assertFalse(mozcrash.check_for_crashes(self.tempdir,
                                                 'symbols_path',
                                                 stackwalk_binary=self.stackwalk))
Beispiel #22
0
    def check_for_crashes(self, browser_config, profile_dir, test_name):
        # check for minidumps
        minidumpdir = os.path.join(profile_dir, "minidumps")
        found = mozcrash.check_for_crashes(minidumpdir, browser_config["symbols_path"], test_name=test_name)
        mozfile.remove(minidumpdir)

        if found:
            raise TalosCrash("Found crashes after test run, terminating test")
Beispiel #23
0
    def run_gtest(self, prog, xre_path, cwd, symbols_path=None,
                  utility_path=None):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * cwd: The directory to run tests from (support files will be found
               in this direcotry).
        * 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.
                        currently used to locate a stack fixer to provide
                        symbols symbols for assertion stacks.

        Return True if the program exits with a zero status, False otherwise.
        """
        self.xre_path = xre_path
        env = self.build_environment()
        log.info("Running gtest")

        if cwd and not os.path.isdir(cwd):
            os.makedirs(cwd)

        stream_output = mozprocess.StreamOutput(sys.stdout)
        process_output = stream_output
        if utility_path:
            stack_fixer = get_stack_fixer_function(utility_path, symbols_path)
            if stack_fixer:
                process_output = lambda line: stream_output(stack_fixer(line))


        proc = mozprocess.ProcessHandler([prog, "-unittest",
                                         "--gtest_death_test_style=threadsafe"],
                                         cwd=cwd,
                                         env=env,
                                         processOutputLine=process_output)
        #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.
        proc.run(timeout=GTests.TEST_PROC_TIMEOUT,
                 outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
        proc.wait()
        if proc.timedOut:
            if proc.outputTimedOut:
                log.testFail("gtest | timed out after %d seconds without output",
                             GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
            else:
                log.testFail("gtest | timed out after %d seconds",
                             GTests.TEST_PROC_TIMEOUT)
            return False
        if mozcrash.check_for_crashes(cwd, symbols_path, test_name="gtest"):
            # mozcrash will output the log failure line for us.
            return False
        result = proc.proc.returncode == 0
        if not result:
            log.testFail("gtest | test failed with return code %d", proc.proc.returncode)
        return result
Beispiel #24
0
 def test_stackwalk_envvar(self):
     """
     Test that check_for_crashes uses the MINIDUMP_STACKWALK environment var.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     os.environ["MINIDUMP_STACKWALK"] = self.stackwalk
     self.assert_(mozcrash.check_for_crashes(self.tempdir, "symbols_path", quiet=True))
     del os.environ["MINIDUMP_STACKWALK"]
Beispiel #25
0
 def test_simple(self):
     """
     Test that check_for_crashes returns True if a dump is present.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             'symbols_path',
                                             stackwalk_binary=self.stackwalk))
Beispiel #26
0
 def check_for_crashes(self, dump_directory, test_name=None):
     crashed = False
     try:
         crashed = mozcrash.check_for_crashes(dump_directory,
                                              self.symbols_path,
                                              test_name=test_name)
     except:
         traceback.print_exc()
     return crashed
 def check_for_crashes(self, dump_directory, test_name=None):
     crashed = False
     try:
         crashed = mozcrash.check_for_crashes(dump_directory,
                                              self.symbols_path,
                                              test_name=test_name)
     except:
         traceback.print_exc()
     return crashed
Beispiel #28
0
    def check_for_crashes(self, browser_config, minidump_dir, test_name):
        # check for minidumps
        found = mozcrash.check_for_crashes(minidump_dir,
                                           browser_config['symbols_path'],
                                           test_name=test_name)
        mozfile.remove(minidump_dir)

        if found:
            raise TalosCrash("Found crashes after test run, terminating test")
Beispiel #29
0
 def test_nodumps(self):
     """
     Test that check_for_crashes returns False if no dumps are present.
     """
     self.stdouts.append(["this is some output"])
     self.assertFalse(mozcrash.check_for_crashes(self.tempdir,
                                                 symbols_path='symbols_path',
                                                 stackwalk_binary=self.stackwalk,
                                                 quiet=True))
Beispiel #30
0
    def check_for_crashes(self, browser_config, minidump_dir, test_name):
        # check for minidumps
        found = mozcrash.check_for_crashes(minidump_dir,
                                           browser_config['symbols_path'],
                                           test_name=test_name)
        mozfile.remove(minidump_dir)

        if found:
            raise TalosCrash("Found crashes after test run, terminating test")
Beispiel #31
0
 def wrapper(dump_directory=fspath(tmpdir),
             symbols_path='symbols_path',
             stackwalk_binary=fspath(stackwalk),
             dump_save_path=None,
             test_name=None,
             quiet=True):
     return mozcrash.check_for_crashes(dump_directory, symbols_path,
                                       stackwalk_binary, dump_save_path,
                                       test_name, quiet)
Beispiel #32
0
    def run_one_test(self,
                     prog,
                     env,
                     symbols_path=None,
                     interactive=False,
                     timeout_factor=1):
        """
        Run a single C++ unit test program remotely.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.
        * timeout_factor: An optional test-specific timeout multiplier.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        remote_bin = posixpath.join(self.remote_bin_dir, basename)
        self.log.test_start(basename)
        test_timeout = cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT * timeout_factor

        try:
            output = self.device.shell_output(remote_bin,
                                              env=env,
                                              cwd=self.remote_home_dir,
                                              timeout=test_timeout)
            returncode = 0
        except ADBTimeoutError:
            raise
        except ADBProcessError as e:
            output = e.adb_process.stdout
            returncode = e.adb_process.exitcode

        self.log.process_output(basename,
                                "\n%s" % output,
                                command=[remote_bin])
        with mozfile.TemporaryDirectory() as tempdir:
            self.device.pull(self.remote_home_dir, tempdir)
            if mozcrash.check_for_crashes(tempdir,
                                          symbols_path,
                                          test_name=basename):
                self.log.test_end(basename, status="CRASH", expected="PASS")
                return False
        result = returncode == 0
        if not result:
            self.log.test_end(
                basename,
                status="FAIL",
                expected="PASS",
                message=("test failed with return code %s" % returncode),
            )
        else:
            self.log.test_end(basename, status="PASS", expected="PASS")
        return result
Beispiel #33
0
 def test_simple(self):
     """
     Test that check_for_crashes returns True if a dump is present.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             symbols_path='symbols_path',
                                             stackwalk_binary=self.stackwalk,
                                             quiet=True))
    def run_one_test(self, prog, env, symbols_path=None, interactive=False,
                     timeout_factor=1):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.
        * timeout_factor: An optional test-specific timeout multiplier.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        self.log.test_start(basename)
        with mozfile.TemporaryDirectory() as tempdir:
            if interactive:
                # For tests run locally, via mach, print output directly
                proc = mozprocess.ProcessHandler([prog],
                                                 cwd=tempdir,
                                                 env=env,
                                                 storeOutput=False)
            else:
                proc = mozprocess.ProcessHandler([prog],
                                                 cwd=tempdir,
                                                 env=env,
                                                 storeOutput=True,
                                                 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)
                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):
                self.log.test_end(basename, status='CRASH', expected='PASS')
                return False
            result = proc.proc.returncode == 0
            if not result:
                self.log.test_end(basename, status='FAIL', expected='PASS',
                                  message=("test failed with return code %d" %
                                           proc.proc.returncode))
            else:
                self.log.test_end(basename, status='PASS', expected='PASS')
            return result
Beispiel #35
0
 def test_stackwalk_envvar(self):
     """
     Test that check_for_crashes uses the MINIDUMP_STACKWALK environment var.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     self.stdouts.append(["this is some output"])
     os.environ['MINIDUMP_STACKWALK'] = self.stackwalk
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             symbols_path='symbols_path',
                                             quiet=True))
     del os.environ['MINIDUMP_STACKWALK']
Beispiel #36
0
    def check_for_crashes(self, dump_directory=None, test_name=None):
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        crashed = False
        try:
            crashed = mozcrash.check_for_crashes(dump_directory,
                                                 self.symbols_path,
                                                 test_name=test_name)
        except:
            traceback.print_exc()
        return crashed
Beispiel #37
0
 def test_save_path_not_present(self):
     """
     Test that dump_save_path works when the directory doesn't exist.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     save_path = os.path.join(self.tempdir, "saved")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             'symbols_path',
                                             stackwalk_binary=self.stackwalk,
                                             dump_save_path=save_path))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
Beispiel #38
0
    def check_for_crashes(self, dump_directory=None, test_name=None):
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        crashed = False
        try:
            crashed = mozcrash.check_for_crashes(dump_directory,
                                                 self.symbols_path,
                                                 test_name=test_name)
        except:
            traceback.print_exc()
        return crashed
Beispiel #39
0
 def checkForCrashes(self, directory, symbolsPath):
     crashed = False
     remote_dump_dir = self._remoteProfile + "/minidumps"
     if self._devicemanager.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
         finally:
             shutil.rmtree(local_dump_dir)
             self._devicemanager.removeDir(remote_dump_dir)
     return crashed
Beispiel #40
0
    def cleanupAndCheckForCrashes(self, browser_config, profile_dir,
                                  test_name):
        """cleanup browser processes and process crashes if found"""

        # cleanup processes
        cleanup_result = self._ffprocess.cleanupProcesses(
            browser_config['process'], browser_config['child_process'],
            browser_config['browser_wait'])

        # find stackwalk binary
        if platform.system() in ('Windows', 'Microsoft'):
            stackwalkpaths = ['win32', 'minidump_stackwalk.exe']
        elif platform.system() == 'Linux':
            if '64' in platform.architecture()[0]:  #are we 64 bit?
                stackwalkpaths = ['linux64', 'minidump_stackwalk']
            else:
                stackwalkpaths = ['linux', 'minidump_stackwalk']
        elif platform.system() == 'Darwin':
            stackwalkpaths = ['osx', 'minidump_stackwalk']
        else:
            # no minidump_stackwalk available for your platform
            return
        stackwalkbin = os.path.join(os.path.dirname(__file__), 'breakpad',
                                    *stackwalkpaths)
        assert os.path.exists(
            stackwalkbin
        ), "minidump_stackwalk binary not found: %s" % stackwalkbin

        # look for minidumps
        minidumpdir = os.path.join(profile_dir, 'minidumps')
        if browser_config['remote'] == True:
            minidumpdir = tempfile.mkdtemp()
            try:
                remoteminidumpdir = profile_dir + '/minidumps/'
                if self._ffprocess.testAgent.dirExists(remoteminidumpdir):
                    self._ffprocess.testAgent.getDirectory(
                        remoteminidumpdir, minidumpdir)
            except mozdevice.DMError:
                print "Remote Device Error: Error getting crash minidumps from device"
                raise

        found = mozcrash.check_for_crashes(minidumpdir,
                                           browser_config['symbols_path'],
                                           stackwalk_binary=stackwalkbin,
                                           test_name=test_name)

        if browser_config['remote'] == True:
            # cleanup dumps on remote
            self._ffprocess.testAgent.removeDir(remoteminidumpdir)
            self._hostproc.removeDirectory(minidumpdir)

        if found:
            raise talosCrash("Found crashes after test run, terminating test")
Beispiel #41
0
 def checkForCrashes(self, directory, symbolsPath):
     crashed = False
     remote_dump_dir = self._remoteProfile + '/minidumps'
     if self._devicemanager.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
         finally:
             shutil.rmtree(local_dump_dir)
             self._devicemanager.removeDir(remote_dump_dir)
     return crashed
Beispiel #42
0
    def check_for_crashes(self,
                          dump_directory=None,
                          dump_save_path=None,
                          test_name=None,
                          quiet=False):
        """Check for possible crashes and output the stack traces.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout

        :returns: Number of crashes which have been detected since the last invocation
        """
        crash_count = 0

        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, "minidumps")

        if not dump_save_path:
            dump_save_path = self.dump_save_path

        if not test_name:
            test_name = "runner.py"

        try:
            if self.logger:
                if mozcrash:
                    crash_count = mozcrash.log_crashes(
                        self.logger,
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test=test_name,
                    )
                else:
                    self.logger.warning("Can not log crashes without mozcrash")
            else:
                if mozcrash:
                    crash_count = mozcrash.check_for_crashes(
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test_name=test_name,
                        quiet=quiet,
                    )

            self.crashed += crash_count
        except Exception:
            traceback.print_exc()

        return crash_count
Beispiel #43
0
 def test_save_path_envvar(self):
     """
     Test that the MINDUMP_SAVE_PATH environment variable works.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     save_path = os.path.join(self.tempdir, "saved")
     os.mkdir(save_path)
     self.stdouts.append(["this is some output"])
     os.environ['MINIDUMP_SAVE_PATH'] = save_path
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             'symbols_path',
                                             stackwalk_binary=self.stackwalk))
     del os.environ['MINIDUMP_SAVE_PATH']
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
Beispiel #44
0
 def test_save_path(self):
     """
     Test that dump_save_path works.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     save_path = os.path.join(self.tempdir, "saved")
     os.mkdir(save_path)
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             'symbols_path',
                                             stackwalk_binary=self.stackwalk,
                                             dump_save_path=save_path,
                                             quiet=True))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
Beispiel #45
0
 def test_save_path_not_present(self):
     """
     Test that dump_save_path works when the directory doesn't exist.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     save_path = os.path.join(self.tempdir, "saved")
     self.stdouts.append(["this is some output"])
     self.assert_(
         mozcrash.check_for_crashes(self.tempdir,
                                    'symbols_path',
                                    stackwalk_binary=self.stackwalk,
                                    dump_save_path=save_path,
                                    quiet=True))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
Beispiel #46
0
    def check_for_crashes(self,
                          dump_directory=None,
                          dump_save_path=None,
                          test_name=None,
                          quiet=False):
        """
        Check for a possible crash and output stack trace.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout
        :returns: True if a crash was detected, otherwise False
        """
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        if not dump_save_path:
            dump_save_path = self.dump_save_path

        try:
            logger = get_default_logger()
            if logger is not None:
                if test_name is None:
                    test_name = "runner.py"
                if mozcrash:
                    self.crashed += mozcrash.log_crashes(
                        logger,
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test=test_name)
                else:
                    logger.warning("Can not log crashes without mozcrash")
            else:
                if mozcrash:
                    crashed = mozcrash.check_for_crashes(
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test_name=test_name,
                        quiet=quiet)
                    if crashed:
                        self.crashed += 1
                else:
                    logger.warning("Can not log crashes without mozcrash")
        except:
            traceback.print_exc()

        return self.crashed
    def run_one_test(self,
                     prog,
                     env,
                     symbols_path=None,
                     interactive=False,
                     timeout_factor=1):
        """
        Run a single C++ unit test program remotely.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.
        * timeout_factor: An optional test-specific timeout multiplier.

        Return True if the program exits with a zero status, False otherwise.
        """
        basename = os.path.basename(prog)
        remote_bin = posixpath.join(self.remote_bin_dir, basename)
        self.log.test_start(basename)
        buf = StringIO.StringIO()
        test_timeout = cppunittests.CPPUnitTests.TEST_PROC_TIMEOUT * \
            timeout_factor
        returncode = self.device.shell([remote_bin],
                                       buf,
                                       env=env,
                                       cwd=self.remote_home_dir,
                                       timeout=test_timeout)
        self.log.process_output(basename,
                                "\n%s" % buf.getvalue(),
                                command=[remote_bin])
        with mozfile.TemporaryDirectory() as tempdir:
            self.device.getDirectory(self.remote_home_dir, tempdir)
            if mozcrash.check_for_crashes(tempdir,
                                          symbols_path,
                                          test_name=basename):
                self.log.test_end(basename, status='CRASH', expected='PASS')
                return False
        result = returncode == 0
        if not result:
            self.log.test_end(basename,
                              status='FAIL',
                              expected='PASS',
                              message=("test failed with return code %s" %
                                       returncode))
        else:
            self.log.test_end(basename, status='PASS', expected='PASS')
        return result
Beispiel #48
0
 def check_for_crashes(self, symbols_path):
     remote_dump_dirs = [posixpath.join(p, 'minidumps') for p in self.remote_profiles]
     crashed = False
     for remote_dump_dir in remote_dump_dirs:
         local_dump_dir = tempfile.mkdtemp()
         self.dm.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             if mozcrash.check_for_crashes(local_dump_dir, symbols_path):
                 crashed = True
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self.dm.removeDir(remote_dump_dir)
     return crashed
Beispiel #49
0
 def check_for_crashes(self, symbols_path, last_test=None):
     crashed = False
     remote_dump_dir = posixpath.join(self.remote_profile, 'minidumps')
     self.log.info("checking for crashes in '%s'" % remote_dump_dir)
     if self.dm.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self.dm.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             crashed = mozcrash.check_for_crashes(local_dump_dir, symbols_path, test_name=last_test)
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self.dm.removeDir(remote_dump_dir)
     return crashed
 def checkForCrashes(self, directory, symbolsPath):
     crashed = False
     remote_dump_dir = self._remoteProfile + '/minidumps'
     print "checking for crashes in '%s'" % remote_dump_dir
     if self._devicemanager.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self._devicemanager.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             crashed = mozcrash.check_for_crashes(local_dump_dir, symbolsPath, test_name=self.lastTestSeen)
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self._devicemanager.removeDir(remote_dump_dir)
     return crashed
Beispiel #51
0
 def check_for_crashes(self):
     remote_dump_dirs = [posixpath.join(p, 'minidumps') for p in self.remote_profiles]
     crashed = False
     for remote_dump_dir in remote_dump_dirs:
         local_dump_dir = tempfile.mkdtemp()
         self.dm.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             if mozcrash.check_for_crashes(local_dump_dir, self.symbols_path):
                 crashed = True
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self.dm.removeDir(remote_dump_dir)
     return crashed
Beispiel #52
0
 def test_save_path(self):
     """
     Test that dump_save_path works.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
     save_path = os.path.join(self.tempdir, "saved")
     os.mkdir(save_path)
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             symbols_path='symbols_path',
                                             stackwalk_binary=self.stackwalk,
                                             dump_save_path=save_path,
                                             quiet=True))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
Beispiel #53
0
 def test_save_path_envvar(self):
     """
     Test that the MINDUMP_SAVE_PATH environment variable works.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     save_path = os.path.join(self.tempdir, "saved")
     os.mkdir(save_path)
     self.stdouts.append(["this is some output"])
     os.environ['MINIDUMP_SAVE_PATH'] = save_path
     self.assert_(
         mozcrash.check_for_crashes(self.tempdir,
                                    'symbols_path',
                                    stackwalk_binary=self.stackwalk,
                                    quiet=True))
     del os.environ['MINIDUMP_SAVE_PATH']
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
Beispiel #54
0
    def check_for_crashes(self, dump_directory=None, dump_save_path=None,
                          test_name=None, quiet=False):
        """Check for possible crashes and output the stack traces.

        :param dump_directory: Directory to search for minidump files
        :param dump_save_path: Directory to save the minidump files to
        :param test_name: Name to use in the crash output
        :param quiet: If `True` don't print the PROCESS-CRASH message to stdout

        :returns: Number of crashes which have been detected since the last invocation
        """
        crash_count = 0

        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, 'minidumps')

        if not dump_save_path:
            dump_save_path = self.dump_save_path

        if not test_name:
            test_name = "runner.py"

        try:
            if self.logger:
                if mozcrash:
                    crash_count = mozcrash.log_crashes(
                        self.logger,
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test=test_name)
                else:
                    self.logger.warning("Can not log crashes without mozcrash")
            else:
                if mozcrash:
                    crash_count = mozcrash.check_for_crashes(
                        dump_directory,
                        self.symbols_path,
                        dump_save_path=dump_save_path,
                        test_name=test_name,
                        quiet=quiet)

            self.crashed += crash_count
        except:
            traceback.print_exc()

        return crash_count
Beispiel #55
0
 def check_for_crashes(self, symbols_path, last_test=None):
     crashed = False
     remote_dump_dir = posixpath.join(self.remote_profile, 'minidumps')
     self.log.info("checking for crashes in '%s'" % remote_dump_dir)
     if self.dm.dirExists(remote_dump_dir):
         local_dump_dir = tempfile.mkdtemp()
         self.dm.getDirectory(remote_dump_dir, local_dump_dir)
         try:
             crashed = mozcrash.check_for_crashes(local_dump_dir,
                                                  symbols_path,
                                                  test_name=last_test)
         except:
             traceback.print_exc()
         finally:
             shutil.rmtree(local_dump_dir)
             self.dm.removeDir(remote_dump_dir)
     return crashed
Beispiel #56
0
    def check_for_crashes(self, dump_directory=None, test_name=None):
        """Check for a possible crash and output stack trace

        :param dump_directory: Directory to search for minidump files
        :param test_name: Name to use in the crash output

        """
        if not dump_directory:
            dump_directory = os.path.join(self.profile.profile, "minidumps")

        crashed = False
        try:
            crashed = mozcrash.check_for_crashes(dump_directory, self.symbols_path, test_name=test_name)
        except:
            traceback.print_exc()

        return crashed
Beispiel #57
0
 def test_save_path_isfile(self):
     """
     Test that dump_save_path works when the directory doesn't exist,
     but a file with the same name exists.
     """
     open(os.path.join(self.tempdir, "test.dmp"), "w").write("foo")
     open(os.path.join(self.tempdir, "test.extra"), "w").write("bar")
     save_path = os.path.join(self.tempdir, "saved")
     open(save_path, "w").write("junk")
     self.stdouts.append(["this is some output"])
     self.assert_(mozcrash.check_for_crashes(self.tempdir,
                                             'symbols_path',
                                             stackwalk_binary=self.stackwalk,
                                             dump_save_path=save_path,
                                             quiet=True))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.dmp")))
     self.assert_(os.path.isfile(os.path.join(save_path, "test.extra")))
def run_one_test(prog, env, symbols_path=None):
    """
    Run a single C++ unit test program.

    Arguments:
    * prog: The path to the test program to run.
    * env: The environment to use for running the program.
    * symbols_path: A path to a directory containing Breakpad-formatted
                    symbol files for producing stack traces on crash.

    Return True if the program exits with a zero status, False otherwise.
    """
    basename = os.path.basename(prog)
    log.info("Running test %s", basename)
    with TemporaryDirectory() as tempdir:
        proc = mozprocess.ProcessHandler([prog],
                                         cwd=tempdir,
                                         env=env)
        proc.run()
        timeout = 300
        proc.processOutput(timeout=timeout)
        if proc.timedOut:
            log.testFail("%s | timed out after %d seconds",
                         basename, timeout)
            return False
        proc.waitForFinish(timeout=timeout)
        if proc.timedOut:
            log.testFail("%s | timed out after %d seconds",
                         basename, timeout)
            return False
        if mozcrash.check_for_crashes(tempdir, symbols_path,
                                      test_name=basename):
            log.testFail("%s | test crashed", basename)
            return False
        result = proc.proc.returncode == 0
        if not result:
            log.testFail("%s | test failed with return code %d",
                         basename, proc.proc.returncode)
        return result
Beispiel #59
0
    def run_gtest(self, prog, xre_path, symbols_path=None, cwd=None):
        """
        Run a single C++ unit test program.

        Arguments:
        * prog: The path to the test program to run.
        * env: The environment to use for running the program.
        * symbols_path: A path to a directory containing Breakpad-formatted
                        symbol files for producing stack traces on crash.

        Return True if the program exits with a zero status, False otherwise.
        """
        self.xre_path = xre_path
        env = self.build_environment()
        log.info("Running gtest")

        if cwd and not os.path.isdir(cwd):
            os.makedirs(cwd)

        proc = mozprocess.ProcessHandler([prog, "-unittest"], cwd=cwd, env=env)
        #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.
        proc.run(timeout=GTests.TEST_PROC_TIMEOUT,
                 outputTimeout=GTests.TEST_PROC_NO_OUTPUT_TIMEOUT)
        proc.wait()
        if proc.timedOut:
            log.testFail("gtest | timed out after %d seconds",
                         GTests.TEST_PROC_TIMEOUT)
            return False
        if mozcrash.check_for_crashes(os.getcwd(),
                                      symbols_path,
                                      test_name="gtest"):
            # mozcrash will output the log failure line for us.
            return False
        result = proc.proc.returncode == 0
        if not result:
            log.testFail("gtest | test failed with return code %d",
                         proc.proc.returncode)
        return result
Beispiel #60
0
  def runApp(self, profile, binary, cmdargs, env,
             timeout=None, debuggerInfo=None,
             symbolsPath=None, options=None):

    def timeoutHandler():
      self.handleTimeout(timeout, proc, options.utilityPath, debuggerInfo)

    interactive = False
    debug_args = None
    if debuggerInfo:
        interactive = debuggerInfo.interactive
        debug_args = [debuggerInfo.path] + debuggerInfo.args

    outputHandler = self.OutputHandler(harness=self,
                                       utilityPath=options.utilityPath,
                                       symbolsPath=symbolsPath,
                                       dump_screen_on_timeout=not debuggerInfo,
        )

    kp_kwargs = {
      'kill_on_timeout': False,
      'cwd': SCRIPT_DIRECTORY,
      'onTimeout': [timeoutHandler],
      'processOutputLine': [outputHandler],
    }

    if interactive:
        # If an interactive debugger is attached,
        # don't use timeouts, and don't capture ctrl-c.
        timeout = None
        signal.signal(signal.SIGINT, lambda sigid, frame: None)

    if mozinfo.info.get('appname') == 'b2g' and mozinfo.info.get('toolkit') != 'gonk':
      runner_cls = mozrunner.Runner
    else:
      runner_cls = mozrunner.runners.get(mozinfo.info.get('appname', 'firefox'),
                                         mozrunner.Runner)
    runner = runner_cls(profile=profile,
                        binary=binary,
                        process_class=mozprocess.ProcessHandlerMixin,
                        cmdargs=cmdargs,
                        env=env,
                        process_args=kp_kwargs)
    runner.start(debug_args=debug_args,
                 interactive=interactive,
                 outputTimeout=timeout)
    proc = runner.process_handler
    status = runner.wait()
    runner.process_handler = None
    if timeout is None:
      didTimeout = False
    else:
      didTimeout = proc.didTimeout

    if status:
      log.info("TEST-UNEXPECTED-FAIL | %s | application terminated with exit code %s", self.lastTestSeen, status)
    else:
      self.lastTestSeen = 'Main app process exited normally'

    crashed = mozcrash.check_for_crashes(os.path.join(profile.profile, "minidumps"),
                                         symbolsPath, test_name=self.lastTestSeen)
    runner.cleanup()
    if not status and crashed:
      status = 1
    return status