Bug 1299216 - [mozrunner] check_for_crashes() has to return the crash count since its last invocation.
Adapt check_for_crashes() for latest mozcrash changes, which returns the number of crashes for both log_crashes()
and check_for_crashes() now. Also the runner should accumulate the number of crashes so it will be known at any
time how many times the process has been crashed.
MozReview-Commit-ID: Dl9FlH1TalH
--- a/testing/mozbase/mozrunner/mozrunner/base/runner.py
+++ b/testing/mozbase/mozrunner/mozrunner/base/runner.py
@@ -36,16 +36,18 @@ class BaseRunner(object):
if isinstance(profile, basestring):
self.profile = self.app_ctx.profile_class(profile=profile,
addons=addons)
else:
self.profile = profile or self.app_ctx.profile_class(**getattr(self.app_ctx,
'profile_args', {}))
+ self.logger = get_default_logger()
+
# process environment
if env is None:
self.env = os.environ.copy()
else:
self.env = env.copy()
self.clean_profile = clean_profile
self.process_class = process_class or ProcessHandler
@@ -94,19 +96,18 @@ class BaseRunner(object):
# ensure the runner is stopped
self.stop()
# attach a debugger, if specified
if debug_args:
cmd = list(debug_args) + cmd
- logger = get_default_logger()
- if logger:
- logger.info('Application command: %s' % ' '.join(cmd))
+ if self.logger:
+ self.logger.info('Application command: %s' % ' '.join(cmd))
if interactive:
self.process_handler = subprocess.Popen(cmd, env=self.env)
# TODO: other arguments
else:
# this run uses the managed processhandler
self.process_handler = self.process_class(cmd, env=self.env, **self.process_args)
self.process_handler.run(self.timeout, self.output_timeout)
@@ -174,59 +175,59 @@ class BaseRunner(object):
"""
Reset the runner to its default state.
"""
self.stop()
self.process_handler = None
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.
+ """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: True if a crash was detected, otherwise False
+
+ :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:
- logger = get_default_logger()
- if logger is not None:
- if test_name is None:
- test_name = "runner.py"
+ if self.logger:
if mozcrash:
- self.crashed += mozcrash.log_crashes(
- logger,
+ crash_count = mozcrash.log_crashes(
+ self.logger,
dump_directory,
self.symbols_path,
dump_save_path=dump_save_path,
test=test_name)
else:
- logger.warning("Can not log crashes without mozcrash")
+ self.logger.warning("Can not log crashes without mozcrash")
else:
if mozcrash:
- crashed = mozcrash.check_for_crashes(
+ crash_count = 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")
+
+ self.crashed += crash_count
except:
traceback.print_exc()
- return self.crashed
+ return crash_count
def cleanup(self):
"""
Cleanup all runner state
"""
self.stop()
--- a/testing/mozbase/mozrunner/tests/manifest.ini
+++ b/testing/mozbase/mozrunner/tests/manifest.ini
@@ -1,6 +1,7 @@
+[test_crash.py]
[test_interactive.py]
[test_start.py]
[test_states.py]
[test_stop.py]
[test_threads.py]
[test_wait.py]
new file mode 100644
--- /dev/null
+++ b/testing/mozbase/mozrunner/tests/test_crash.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import mock
+
+import mozrunnertest
+
+
+class MozrunnerCrashTestCase(mozrunnertest.MozrunnerTestCase):
+
+ @mock.patch('mozcrash.log_crashes', return_value=2)
+ def test_crash_count_with_logger(self, log_crashes):
+ self.assertEqual(self.runner.crashed, 0)
+ self.assertEqual(self.runner.check_for_crashes(), 2)
+ self.assertEqual(self.runner.crashed, 2)
+ self.assertEqual(self.runner.check_for_crashes(), 2)
+ self.assertEqual(self.runner.crashed, 4)
+
+ log_crashes.return_value = 0
+ self.assertEqual(self.runner.check_for_crashes(), 0)
+ self.assertEqual(self.runner.crashed, 4)
+
+ @mock.patch('mozcrash.check_for_crashes', return_value=2)
+ def test_crash_count_without_logger(self, check_for_crashes):
+ self.runner.logger = None
+
+ self.assertEqual(self.runner.crashed, 0)
+ self.assertEqual(self.runner.check_for_crashes(), 2)
+ self.assertEqual(self.runner.crashed, 2)
+ self.assertEqual(self.runner.check_for_crashes(), 2)
+ self.assertEqual(self.runner.crashed, 4)
+
+ check_for_crashes.return_value = 0
+ self.assertEqual(self.runner.check_for_crashes(), 0)
+ self.assertEqual(self.runner.crashed, 4)