Bug 527003 - adding tests for accessibility service shutdown (both e10s and non-e10s). r=surkov
MozReview-Commit-ID: Kq34ZYdSJoj
--- a/accessible/tests/browser/browser.ini
+++ b/accessible/tests/browser/browser.ini
@@ -1,9 +1,17 @@
[DEFAULT]
support-files =
head.js
shared-head.js
[browser_shutdown_multi_reference.js]
+[browser_shutdown_parent_own_reference.js]
+skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_remote_no_reference.js]
+skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_remote_only.js]
+skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
+[browser_shutdown_remote_own_reference.js]
+skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_scope_lifecycle.js]
[browser_shutdown_start_restart.js]
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_parent_own_reference.js
@@ -0,0 +1,72 @@
+/* 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/. */
+
+'use strict';
+
+add_task(function* () {
+ // Making sure that the e10s is enabled on Windows for testing.
+ yield setE10sPrefs();
+
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: `data:text/html,
+ <html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Accessibility Test</title>
+ </head>
+ <body></body>
+ </html>`
+ }, function*(browser) {
+ info('Creating a service in parent and waiting for service to be created ' +
+ 'in content');
+ // Create a11y service in the main process. This will trigger creating of
+ // the a11y service in parent as well.
+ let parentA11yInit = initPromise();
+ let contentA11yInit = initPromise(browser);
+ let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+ Ci.nsIAccessibilityService);
+ ok(accService, 'Service initialized in parent');
+ yield Promise.all([parentA11yInit, contentA11yInit]);
+
+ info('Adding additional reference to accessibility service in content ' +
+ 'process');
+ // Add a new reference to the a11y service inside the content process.
+ loadFrameScripts(browser, `let accService = Components.classes[
+ '@mozilla.org/accessibilityService;1'].getService(
+ Components.interfaces.nsIAccessibilityService);`);
+
+ info('Trying to shut down a service in content and making sure it stays ' +
+ 'alive as it was started by parent');
+ let contentCanShutdown = false;
+ // This promise will resolve only if contentCanShutdown flag is set to true.
+ // If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
+ // it can be shut down, the promise will reject.
+ let contentA11yShutdown = new Promise((resolve, reject) =>
+ shutdownPromise(browser).then(flag => contentCanShutdown ?
+ resolve() : reject('Accessible service was shut down incorrectly')));
+ // Remove a11y service reference in content and force garbage collection.
+ // This should not trigger shutdown since a11y was originally initialized by
+ // the main process.
+ loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
+
+ // Have some breathing room between a11y service shutdowns.
+ yield new Promise(resolve => executeSoon(resolve));
+
+ info('Removing a service in parent');
+ // Now allow a11y service to shutdown in content.
+ contentCanShutdown = true;
+ // Remove the a11y service reference in the main process.
+ let parentA11yShutdown = shutdownPromise();
+ accService = null;
+ ok(!accService, 'Service is removed in parent');
+ // Force garbage collection that should trigger shutdown in both parent and
+ // content.
+ forceGC();
+ yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
+
+ // Unsetting e10s related preferences.
+ yield unsetE10sPrefs();
+ });
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_remote_no_reference.js
@@ -0,0 +1,48 @@
+/* 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/. */
+
+'use strict';
+
+add_task(function* () {
+ // Making sure that the e10s is enabled on Windows for testing.
+ yield setE10sPrefs();
+
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: `data:text/html,
+ <html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Accessibility Test</title>
+ </head>
+ <body></body>
+ </html>`
+ }, function*(browser) {
+ info('Creating a service in parent and waiting for service to be created ' +
+ 'in content');
+ // Create a11y service in the main process. This will trigger creating of
+ // the a11y service in parent as well.
+ let parentA11yInit = initPromise();
+ let contentA11yInit = initPromise(browser);
+ let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+ Ci.nsIAccessibilityService);
+ ok(accService, 'Service initialized in parent');
+ yield Promise.all([parentA11yInit, contentA11yInit]);
+
+ info('Removing a service in parent and waiting for service to be shut ' +
+ 'down in content');
+ // Remove a11y service reference in the main process.
+ let parentA11yShutdown = shutdownPromise();
+ let contentA11yShutdown = shutdownPromise(browser);
+ accService = null;
+ ok(!accService, 'Service is removed in parent');
+ // Force garbage collection that should trigger shutdown in both main and
+ // content process.
+ forceGC();
+ yield Promise.all([parentA11yShutdown, contentA11yShutdown]);
+ });
+
+ // Unsetting e10s related preferences.
+ yield unsetE10sPrefs();
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_remote_only.js
@@ -0,0 +1,40 @@
+/* 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/. */
+
+'use strict';
+
+add_task(function* () {
+ // Making sure that the e10s is enabled on Windows for testing.
+ yield setE10sPrefs();
+
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: `data:text/html,
+ <html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Accessibility Test</title>
+ </head>
+ <body></body>
+ </html>`
+ }, function*(browser) {
+ info('Creating a service in content');
+ // Create a11y service in the content process.
+ let a11yInit = initPromise(browser);
+ loadFrameScripts(browser, `let accService = Components.classes[
+ '@mozilla.org/accessibilityService;1'].getService(
+ Components.interfaces.nsIAccessibilityService);`);
+ yield a11yInit;
+
+ info('Removing a service in content');
+ // Remove a11y service reference from the content process.
+ let a11yShutdown = shutdownPromise(browser);
+ // Force garbage collection that should trigger shutdown.
+ loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
+ yield a11yShutdown;
+
+ // Unsetting e10s related preferences.
+ yield unsetE10sPrefs();
+ });
+});
new file mode 100644
--- /dev/null
+++ b/accessible/tests/browser/browser_shutdown_remote_own_reference.js
@@ -0,0 +1,75 @@
+/* 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/. */
+
+'use strict';
+
+add_task(function* () {
+ // Making sure that the e10s is enabled on Windows for testing.
+ yield setE10sPrefs();
+
+ yield BrowserTestUtils.withNewTab({
+ gBrowser,
+ url: `data:text/html,
+ <html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>Accessibility Test</title>
+ </head>
+ <body></body>
+ </html>`
+ }, function*(browser) {
+ info('Creating a service in parent and waiting for service to be created ' +
+ 'in content');
+ // Create a11y service in the main process. This will trigger creating of
+ // the a11y service in parent as well.
+ let parentA11yInit = initPromise();
+ let contentA11yInit = initPromise(browser);
+ let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
+ Ci.nsIAccessibilityService);
+ ok(accService, 'Service initialized in parent');
+ yield Promise.all([parentA11yInit, contentA11yInit]);
+
+ info('Adding additional reference to accessibility service in content ' +
+ 'process');
+ // Add a new reference to the a11y service inside the content process.
+ loadFrameScripts(browser, `let accService = Components.classes[
+ '@mozilla.org/accessibilityService;1'].getService(
+ Components.interfaces.nsIAccessibilityService);`);
+
+ info('Shutting down a service in parent and making sure the one in ' +
+ 'content stays alive');
+ let contentCanShutdown = false;
+ let parentA11yShutdown = shutdownPromise();
+ // This promise will resolve only if contentCanShutdown flag is set to true.
+ // If 'a11y-init-or-shutdown' event with '0' flag (in content) comes before
+ // it can be shut down, the promise will reject.
+ let contentA11yShutdown = new Promise((resolve, reject) =>
+ shutdownPromise(browser).then(flag => contentCanShutdown ?
+ resolve() : reject('Accessible service was shut down incorrectly')));
+ // Remove a11y service reference in the main process and force garbage
+ // collection. This should not trigger shutdown in content since a11y
+ // service is used by XPCOM.
+ accService = null;
+ ok(!accService, 'Service is removed in parent');
+ // Force garbage collection that should not trigger shutdown because there
+ // is a reference in a content process.
+ forceGC();
+ loadFrameScripts(browser, `Components.utils.forceGC();`);
+ yield parentA11yShutdown;
+
+ // Have some breathing room between a11y service shutdowns.
+ yield new Promise(resolve => executeSoon(resolve));
+
+ info('Removing a service in content');
+ // Now allow a11y service to shutdown in content.
+ contentCanShutdown = true;
+ // Remove last reference to a11y service in content and force garbage
+ // collection that should trigger shutdown.
+ loadFrameScripts(browser, `accService = null; Components.utils.forceGC();`);
+ yield contentA11yShutdown;
+
+ // Unsetting e10s related preferences.
+ yield unsetE10sPrefs();
+ });
+});
--- a/accessible/tests/browser/browser_shutdown_scope_lifecycle.js
+++ b/accessible/tests/browser/browser_shutdown_scope_lifecycle.js
@@ -1,15 +1,15 @@
/* 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/. */
'use strict';
-add_task(function* testScopeLifecycle() {
+add_task(function* () {
// Create a11y service inside of the function scope. Its reference should be
// released once the anonimous function is called.
let a11yInitThenShutdown = initPromise().then(shutdownPromise);
(function() {
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
--- a/accessible/tests/browser/browser_shutdown_start_restart.js
+++ b/accessible/tests/browser/browser_shutdown_start_restart.js
@@ -1,15 +1,15 @@
/* 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/. */
'use strict';
-add_task(function* testStartAndRestart() {
+add_task(function* () {
info('Creating a service');
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');