[Pkg-mozext-commits] [requestpolicy] 57/80: Marionette: detect Console and Logging errors
David Prévot
taffit at moszumanska.debian.org
Sun Jul 5 15:02:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository requestpolicy.
commit 1837bca02fa13b129503a9a849be648ffd095acd
Author: Martin Kimmerle <dev at 256k.de>
Date: Mon Jun 22 03:24:37 2015 +0200
Marionette: detect Console and Logging errors
The new `RequestPolicyTestCase` class will check for Logging
errors and Console errors after each test in its `tearDown`
method. It will be the base class for all test cases.
Error detection is done in the `ErrorDetection` classes,
whose functions are again checked by the tests in the
"test_error_detection.py" file. The DevHelper's ConsoleObserver
has been extended so that the error count can be reset.
In the "addons" library's `RequestPolicy` class, the enable,
disable etc. functions directly check for logging/console
errors. In this manner, a failed shutdown/startup can be
detected immediately.
---
src/content/lib/logger.jsm | 80 ++++++++++++++++++++++
.../dev-helper/content/console-observer.jsm | 6 +-
.../marionette/rp_puppeteer/api/error_detection.py | 70 +++++++++++++++++++
tests/marionette/rp_puppeteer/tests/manifest.ini | 1 +
tests/marionette/rp_puppeteer/tests/test_addons.py | 8 +--
.../rp_puppeteer/tests/test_error_detection.py | 45 ++++++++++++
tests/marionette/rp_puppeteer/tests/test_prefs.py | 6 +-
tests/marionette/rp_puppeteer/ui/addons.py | 42 ++++++++++--
tests/marionette/rp_ui_harness/__init__.py | 4 ++
tests/marionette/rp_ui_harness/testcases.py | 49 +++++++++++++
tests/marionette/tests/test_restartlessness.py | 6 +-
tests/marionette/tests/test_setup_page.py | 4 +-
12 files changed, 302 insertions(+), 19 deletions(-)
diff --git a/src/content/lib/logger.jsm b/src/content/lib/logger.jsm
index fb2bd18..c6bebcf 100644
--- a/src/content/lib/logger.jsm
+++ b/src/content/lib/logger.jsm
@@ -199,3 +199,83 @@ let Logger = (function() {
return self;
}());
+
+// #ifdef UNIT_TESTING
+
+/**
+ * Triggers errors for a RequestPolicy unit test.
+ * It's used to test Error Detection from the unit tests.
+ */
+var UnitTestObserver = (function (self) {
+
+ var loggingErrorTopic = "requestpolicy-trigger-logging-error";
+ var consoleErrorTopic = "requestpolicy-trigger-console-error";
+
+ self.startup = function () {
+ Services.obs.addObserver(self, loggingErrorTopic, false);
+ Services.obs.addObserver(self, consoleErrorTopic, false);
+ };
+
+ self.shutdown = function () {
+ Services.obs.removeObserver(self, loggingErrorTopic);
+ Services.obs.removeObserver(self, consoleErrorTopic);
+ };
+
+ /**
+ * Split a string like
+ * "foo:bar:baz"
+ * to two strings:
+ * ["foo", "bar:baz"]
+ * Only the first colon counts.
+ */
+ function splitColon(aString) {
+ var index = aString.indexOf(":");
+ if (index === -1) {
+ return [aString, ""]
+ }
+ var part1 = aString.substr(0, index);
+ var part2 = aString.substr(index + 1);
+ return [part1, part2];
+ }
+
+ self.observe = function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case loggingErrorTopic:
+ let [logLevel, logMessage] = splitColon(aData);
+
+ if (logLevel === "warning") {
+ Logger.warning(Logger.TYPE_ERROR, logMessage);
+ } else if (logLevel === "severe") {
+ Logger.severe(Logger.TYPE_INTERNAL, logMessage);
+ }
+ break;
+
+ case consoleErrorTopic:
+ if (aData === "ReferenceError") {
+ runAsync(produceReferenceError);
+ }
+ break;
+
+ default:
+ break;
+ }
+ };
+
+ function produceReferenceError() {
+ var localVar = nonexistantVariable;
+ }
+
+ function runAsync(aFunction) {
+ var runnable = {run: aFunction};
+ Services.tm.currentThread.dispatch(runnable,
+ Ci.nsIEventTarget.DISPATCH_NORMAL);
+ }
+
+ return self;
+})({});
+
+ProcessEnvironment.addStartupFunction(Environment.LEVELS.BACKEND,
+ UnitTestObserver.startup);
+ProcessEnvironment.addShutdownFunction(Environment.LEVELS.BACKEND,
+ UnitTestObserver.shutdown);
+// #endif
diff --git a/tests/helper-addons/dev-helper/content/console-observer.jsm b/tests/helper-addons/dev-helper/content/console-observer.jsm
index 4ad7d8b..3ddfb7b 100644
--- a/tests/helper-addons/dev-helper/content/console-observer.jsm
+++ b/tests/helper-addons/dev-helper/content/console-observer.jsm
@@ -56,8 +56,12 @@ var ConsoleObserver = (function (self) {
return numErrors;
};
- self.startup = function () {
+ self.reset = function () {
numErrors = 0;
+ };
+
+ self.startup = function () {
+ self.reset();
Services.console.registerListener(self);
};
diff --git a/tests/marionette/rp_puppeteer/api/error_detection.py b/tests/marionette/rp_puppeteer/api/error_detection.py
new file mode 100644
index 0000000..1c8f68c
--- /dev/null
+++ b/tests/marionette/rp_puppeteer/api/error_detection.py
@@ -0,0 +1,70 @@
+# 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/.
+
+from firefox_puppeteer.base import BaseLib
+from firefox_puppeteer.api.prefs import Preferences
+
+ERROR_COUNT_PREF = "extensions.requestpolicy.unitTesting.errorCount"
+
+
+class ErrorDetection(BaseLib):
+ def _notify_observers(self, topic, data):
+ with self.marionette.using_context("chrome"):
+ self.marionette.execute_script(
+ """
+ Components.utils.import("resource://gre/modules/Services.jsm");
+ Services.obs.notifyObservers(null, "{}", "{}");
+ """.format(topic, data))
+
+ def get_error_count(self):
+ raise NotImplementedError
+
+ def reset_error_count(self):
+ raise NotImplementedError
+
+ def trigger_error(self):
+ raise NotImplementedError
+
+
+class LoggingErrorDetection(ErrorDetection):
+ def __init__(self, marionette_getter):
+ BaseLib.__init__(self, marionette_getter)
+
+ self.prefs = Preferences(marionette_getter)
+
+ def get_error_count(self):
+ return self.prefs.get_pref(ERROR_COUNT_PREF)
+
+ def reset_error_count(self):
+ self.prefs.set_pref(ERROR_COUNT_PREF, 0)
+
+ def trigger_error(self, error_type, msg="[Marionette unit test]"):
+ self._notify_observers("requestpolicy-trigger-logging-error",
+ "{}:{}".format(error_type, msg))
+
+
+class ConsoleErrorDetection(ErrorDetection):
+ def get_error_count(self):
+ with self.marionette.using_context("chrome"):
+ return self.marionette.execute_script(
+ """
+ let scope = {};
+ Components.utils.import("chrome://rpc-dev-helper/" +
+ "content/console-observer.jsm", scope);
+ return scope.ConsoleObserver.getNumErrors();
+ """)
+
+ def reset_error_count(self):
+ with self.marionette.using_context("chrome"):
+ return self.marionette.execute_script(
+ """
+ let scope = {};
+ Components.utils.import("chrome://rpc-dev-helper/content/" +
+ "console-observer.jsm", scope);
+ scope.ConsoleObserver.reset();
+ """)
+
+ def trigger_error(self, error_type):
+ self._notify_observers("requestpolicy-trigger-console-error",
+ error_type)
diff --git a/tests/marionette/rp_puppeteer/tests/manifest.ini b/tests/marionette/rp_puppeteer/tests/manifest.ini
index c0e5d78..ed6a809 100644
--- a/tests/marionette/rp_puppeteer/tests/manifest.ini
+++ b/tests/marionette/rp_puppeteer/tests/manifest.ini
@@ -1,2 +1,3 @@
[test_addons.py]
+[test_error_detection.py]
[test_prefs.py]
diff --git a/tests/marionette/rp_puppeteer/tests/test_addons.py b/tests/marionette/rp_puppeteer/tests/test_addons.py
index 673bd3f..e28fba3 100644
--- a/tests/marionette/rp_puppeteer/tests/test_addons.py
+++ b/tests/marionette/rp_puppeteer/tests/test_addons.py
@@ -2,7 +2,7 @@
# 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/.
-from firefox_ui_harness import FirefoxTestCase
+from rp_ui_harness import RequestPolicyTestCase
from rp_puppeteer.ui.addons import Addons, AboutAddonsTab
@@ -11,7 +11,7 @@ ADDON_ID = "dummy-ext at requestpolicy.org"
INSTALL_URL = "http://localhost/link.html?.dist/dummy-ext.xpi"
-class AddonsTestCase(FirefoxTestCase):
+class AddonsTestCase(RequestPolicyTestCase):
def selected_tab_is_about_addons(self):
location = self.browser.tabbar.selected_tab.location
return location == "about:addons"
@@ -122,7 +122,7 @@ class TestAddons(AddonsTestCase):
class TestAboutAddons(AddonsTestCase):
def setUp(self):
- FirefoxTestCase.setUp(self)
+ RequestPolicyTestCase.setUp(self)
Addons(lambda: self.marionette).install_addon(INSTALL_URL)
@@ -136,7 +136,7 @@ class TestAboutAddons(AddonsTestCase):
self.about_addons.remove_addon(self.addon)
self.about_addons.close_tab()
finally:
- FirefoxTestCase.tearDown(self)
+ RequestPolicyTestCase.tearDown(self)
@property
def addon(self):
diff --git a/tests/marionette/rp_puppeteer/tests/test_error_detection.py b/tests/marionette/rp_puppeteer/tests/test_error_detection.py
new file mode 100644
index 0000000..2259bb2
--- /dev/null
+++ b/tests/marionette/rp_puppeteer/tests/test_error_detection.py
@@ -0,0 +1,45 @@
+# 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/.
+
+from rp_ui_harness import RequestPolicyTestCase
+from rp_puppeteer.api.error_detection import (LoggingErrorDetection,
+ ConsoleErrorDetection)
+
+
+class TestErrorDetection(RequestPolicyTestCase):
+ def test_logging_error_detection(self):
+ error_detect = LoggingErrorDetection(lambda: self.marionette)
+
+ previous_value = error_detect.get_error_count()
+
+ self.assertIsNotNone(previous_value,
+ msg="The pref for the error count exists.")
+
+ error_detect.trigger_error(
+ "warning", msg="[Marionette] test_logging_error_detection")
+ self.assertEqual(error_detect.get_error_count(), previous_value + 1,
+ msg="The error has been detected.")
+
+ error_detect.trigger_error(
+ "severe", msg="[Marionette] test_logging_error_detection")
+ self.assertEqual(error_detect.get_error_count(), previous_value + 2,
+ msg="The severe log message has been detected.")
+
+ error_detect.reset_error_count()
+ self.assertEqual(error_detect.get_error_count(), 0,
+ msg="The Logging error count has been reset.")
+
+ def test_console_error_detection(self):
+ error_detect = ConsoleErrorDetection(lambda: self.marionette)
+
+ self.assertEqual(error_detect.get_error_count(), 0,
+ msg="The Console error count is zero.")
+
+ error_detect.trigger_error("ReferenceError")
+ self.assertEqual(error_detect.get_error_count(), 1,
+ msg="The Console error count has increased.")
+
+ error_detect.reset_error_count()
+ self.assertEqual(error_detect.get_error_count(), 0,
+ msg="The Console error count has been reset.")
diff --git a/tests/marionette/rp_puppeteer/tests/test_prefs.py b/tests/marionette/rp_puppeteer/tests/test_prefs.py
index e128474..58ae98d 100644
--- a/tests/marionette/rp_puppeteer/tests/test_prefs.py
+++ b/tests/marionette/rp_puppeteer/tests/test_prefs.py
@@ -2,15 +2,15 @@
# 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/.
-from firefox_ui_harness import FirefoxTestCase
+from rp_ui_harness import RequestPolicyTestCase
from rp_puppeteer.api.prefs import using_pref
-class TestPrefs(FirefoxTestCase):
+class TestPrefs(RequestPolicyTestCase):
def setUp(self):
- FirefoxTestCase.setUp(self)
+ RequestPolicyTestCase.setUp(self)
self.new_pref = 'marionette.unittest.using_pref'
diff --git a/tests/marionette/rp_puppeteer/ui/addons.py b/tests/marionette/rp_puppeteer/ui/addons.py
index 67845f7..830acce 100644
--- a/tests/marionette/rp_puppeteer/ui/addons.py
+++ b/tests/marionette/rp_puppeteer/ui/addons.py
@@ -6,6 +6,8 @@ from marionette_driver.errors import NoSuchElementException
from marionette_driver.wait import Wait
from firefox_puppeteer.base import BaseLib
from firefox_puppeteer.ui.windows import Windows
+from rp_puppeteer.api.error_detection import (LoggingErrorDetection,
+ ConsoleErrorDetection)
from contextlib import contextmanager
@@ -68,22 +70,50 @@ class RequestPolicy(BaseLib):
self.addons = Addons(marionette_getter)
+ self.logging_error_detect = LoggingErrorDetection(marionette_getter)
+ self.console_error_detect = ConsoleErrorDetection(marionette_getter)
+
+ @contextmanager
+ def _ensure_no_errors(self):
+ logging_errors_before = self.logging_error_detect.get_error_count()
+ console_errors_before = self.console_error_detect.get_error_count()
+ yield
+ logging_error_count = (self.logging_error_detect.get_error_count() -
+ logging_errors_before)
+ console_error_count = (self.console_error_detect.get_error_count() -
+ console_errors_before)
+ if logging_error_count > 0 and console_error_count > 0:
+ raise Exception("There have been {} Logging errors and "
+ "{} Console errors!".format(logging_error_count,
+ console_error_count))
+ elif logging_error_count > 0:
+ raise Exception("There have been {} Logging "
+ "errors!".format(logging_error_count))
+ elif console_error_count > 0:
+ raise Exception("There have been {} Console "
+ "errors!".format(console_error_count))
+
@contextmanager
def install_in_two_steps(self):
- with self.addons.install_addon_in_two_steps(self.install_url):
- yield
+ with self._ensure_no_errors():
+ with self.addons.install_addon_in_two_steps(self.install_url):
+ yield
def install(self):
- self.addons.install_addon(self.install_url)
+ with self._ensure_no_errors():
+ self.addons.install_addon(self.install_url)
def remove(self):
- self.addons.remove_addon_by_id(self.addon_id)
+ with self._ensure_no_errors():
+ self.addons.remove_addon_by_id(self.addon_id)
def enable(self):
- self.addons.enable_addon_by_id(self.addon_id)
+ with self._ensure_no_errors():
+ self.addons.enable_addon_by_id(self.addon_id)
def disable(self):
- self.addons.disable_addon_by_id(self.addon_id)
+ with self._ensure_no_errors():
+ self.addons.disable_addon_by_id(self.addon_id)
def is_installed(self):
return self.addons.is_addon_installed(self.addon_id)
diff --git a/tests/marionette/rp_ui_harness/__init__.py b/tests/marionette/rp_ui_harness/__init__.py
index 8b13789..c1f6d17 100644
--- a/tests/marionette/rp_ui_harness/__init__.py
+++ b/tests/marionette/rp_ui_harness/__init__.py
@@ -1 +1,5 @@
+# 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/.
+from testcases import RequestPolicyTestCase
diff --git a/tests/marionette/rp_ui_harness/testcases.py b/tests/marionette/rp_ui_harness/testcases.py
new file mode 100644
index 0000000..9bd4d1d
--- /dev/null
+++ b/tests/marionette/rp_ui_harness/testcases.py
@@ -0,0 +1,49 @@
+# 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/.
+
+from firefox_ui_harness import FirefoxTestCase
+
+from rp_puppeteer.api.error_detection import (LoggingErrorDetection,
+ ConsoleErrorDetection)
+
+
+class RequestPolicyTestCase(FirefoxTestCase):
+ """Base testcase class for RequestPolicy Marionette tests.
+ """
+
+ def __init__(self, *args, **kwargs):
+ FirefoxTestCase.__init__(self, *args, **kwargs)
+
+
+ def _check_error_counts(self):
+ self.assertEqual(self.logging_error_detect.get_error_count(), 0,
+ msg="The Logging error count is zero.")
+ self.assertEqual(self.console_error_detect.get_error_count(), 0,
+ msg="The Console error count is zero.")
+
+ def _reset_error_counts(self):
+ self.logging_error_detect.reset_error_count()
+ self.console_error_detect.reset_error_count()
+
+ def _check_and_reset_error_counts(self):
+ try:
+ self._check_error_counts()
+ finally:
+ self._reset_error_counts()
+
+
+ def setUp(self, *args, **kwargs):
+ FirefoxTestCase.setUp(self, *args, **kwargs)
+
+ marionette_getter = lambda: self.marionette
+ self.logging_error_detect = LoggingErrorDetection(marionette_getter)
+ self.console_error_detect = ConsoleErrorDetection(marionette_getter)
+
+ self._check_and_reset_error_counts()
+
+ def tearDown(self, *args, **kwargs):
+ try:
+ self._check_and_reset_error_counts()
+ finally:
+ FirefoxTestCase.tearDown(self, *args, **kwargs)
diff --git a/tests/marionette/tests/test_restartlessness.py b/tests/marionette/tests/test_restartlessness.py
index a634397..c77d36e 100644
--- a/tests/marionette/tests/test_restartlessness.py
+++ b/tests/marionette/tests/test_restartlessness.py
@@ -2,7 +2,7 @@
# 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/.
-from firefox_ui_harness import FirefoxTestCase
+from rp_ui_harness import RequestPolicyTestCase
from rp_puppeteer.ui.addons import RequestPolicy
PREF_WELCOME_WIN_SHOWN = "extensions.requestpolicy.welcomeWindowShown"
@@ -10,13 +10,13 @@ RP_ID = "rpcontinued at non-amo.requestpolicy.org"
INSTALL_URL = "http://localhost/link.html?.dist/requestpolicy-unit-testing.xpi"
-class TestRequestPolicyRestartlessness(FirefoxTestCase):
+class TestRequestPolicyRestartlessness(RequestPolicyTestCase):
"""These tests ensure that RequestPolicy can be uninstalled/installed and
disabled/enabled restartless.
"""
def setUp(self):
- FirefoxTestCase.setUp(self)
+ RequestPolicyTestCase.setUp(self)
self.rp = RequestPolicy(lambda: self.marionette)
def test_disable_enable(self):
diff --git a/tests/marionette/tests/test_setup_page.py b/tests/marionette/tests/test_setup_page.py
index 80292fa..b7480fd 100644
--- a/tests/marionette/tests/test_setup_page.py
+++ b/tests/marionette/tests/test_setup_page.py
@@ -2,7 +2,7 @@
# 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/.
-from firefox_ui_harness import FirefoxTestCase
+from rp_ui_harness import RequestPolicyTestCase
from marionette_driver.wait import Wait
from rp_puppeteer.ui.addons import RequestPolicy
@@ -10,7 +10,7 @@ from rp_puppeteer.ui.addons import RequestPolicy
PREF_WELCOME_WIN_SHOWN = "extensions.requestpolicy.welcomeWindowShown"
-class TestSetupPageShowingUp(FirefoxTestCase):
+class TestSetupPageShowingUp(RequestPolicyTestCase):
def _get_setup_tab(self):
# TODO: Search in all windows for setup tabs.
# Assert there isn't more than one setup tab.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/requestpolicy.git
More information about the Pkg-mozext-commits
mailing list