Bug 934066 - Add a simple parent/child synchronization mechanism for xpcshell tests. r=ted, a=test-only
--- a/dom/tests/unit/test_geolocation_reset_accuracy.js
+++ b/dom/tests/unit/test_geolocation_reset_accuracy.js
@@ -27,16 +27,17 @@ var provider = {
watch: function() {
},
shutdown: function() {
},
setHighAccuracy: function(enable) {
this._isHigh = enable;
if (enable) {
this._seenHigh = true;
+ do_execute_soon(stop_high_accuracy_watch);
}
},
_isHigh: false,
_seenHigh: false
};
let runningInParent = true;
try {
@@ -53,16 +54,19 @@ function successCallback()
}
function errorCallback()
{
do_check_true(false);
do_test_finished();
}
+var geolocation;
+var watchID2;
+
function run_test()
{
if (runningInParent) {
// XPCShell does not get a profile by default. The geolocation service
// depends on the settings service which uses IndexedDB and IndexedDB
// needs a place where it can store databases.
do_get_profile();
@@ -73,28 +77,31 @@ function run_test()
catMan.nsICategoryManager.addCategoryEntry(categoryName, "unit test",
providerContract, false, true);
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
prefs.setBoolPref("geo.testing.ignore_ipc_principal", true);
prefs.setBoolPref("geo.wifi.scan", false);
}
- let geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports);
-
do_test_pending();
+ geolocation = Cc["@mozilla.org/geolocation;1"].createInstance(Ci.nsISupports);
let watchID1 = geolocation.watchPosition(successCallback, errorCallback);
- let watchID2 = geolocation.watchPosition(successCallback, errorCallback,
- {enableHighAccuracy: true});
+ watchID2 = geolocation.watchPosition(successCallback, errorCallback,
+ {enableHighAccuracy: true});
- do_timeout(5000, function() {
+ if (!runningInParent) {
+ do_await_remote_message('high_acc_enabled', stop_high_accuracy_watch);
+ }
+}
+
+function stop_high_accuracy_watch() {
geolocation.clearWatch(watchID2);
- do_timeout(1000, check_results);
- });
+ check_results();
}
function check_results()
{
if (runningInParent) {
// check the provider was set to high accuracy during the test
do_check_true(provider._seenHigh);
// check the provider is not currently set to high accuracy
--- a/dom/tests/unit/test_geolocation_reset_accuracy_wrap.js
+++ b/dom/tests/unit/test_geolocation_reset_accuracy_wrap.js
@@ -27,16 +27,17 @@ var provider = {
watch: function() {
},
shutdown: function() {
},
setHighAccuracy: function(enable) {
this._isHigh = enable;
if (enable) {
this._seenHigh = true;
+ do_send_remote_message('high_acc_enabled');
}
},
_isHigh: false,
_seenHigh: false
};
function run_test()
{
--- a/testing/xpcshell/head.js
+++ b/testing/xpcshell/head.js
@@ -1205,16 +1205,58 @@ function run_test_in_child(testFile, opt
var testPath = do_get_file(testFile).path.replace(/\\/g, "/");
do_test_pending("run in child");
sendCommand("_log('child_test_start', {_message: 'CHILD-TEST-STARTED'}); "
+ "const _TEST_FILE=['" + testPath + "']; _execute_test(); "
+ "_log('child_test_end', {_message: 'CHILD-TEST-COMPLETED'});",
callback);
}
+/**
+ * Execute a given function as soon as a particular cross-process message is received.
+ * Must be paired with do_send_remote_message or equivalent ProcessMessageManager calls.
+ */
+function do_await_remote_message(name, callback)
+{
+ var listener = {
+ receiveMessage: function(message) {
+ if (message.name == name) {
+ mm.removeMessageListener(name, listener);
+ callback();
+ do_test_finished();
+ }
+ }
+ };
+
+ var mm;
+ if (runningInParent) {
+ mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIMessageBroadcaster);
+ } else {
+ mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
+ }
+ do_test_pending();
+ mm.addMessageListener(name, listener);
+}
+
+/**
+ * Asynchronously send a message to all remote processes. Pairs with do_await_remote_message
+ * or equivalent ProcessMessageManager listeners.
+ */
+function do_send_remote_message(name) {
+ var mm;
+ var sender;
+ if (runningInParent) {
+ mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIMessageBroadcaster);
+ sender = 'broadcastAsyncMessage';
+ } else {
+ mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
+ sender = 'sendAsyncMessage';
+ }
+ mm[sender](name);
+}
/**
* Add a test function to the list of tests that are to be run asynchronously.
*
* Each test function must call run_next_test() when it's done. Test files
* should call run_next_test() in their run_test function to execute all
* async tests.
*