gecko/dom/cache/test/mochitest/worker_wrapper.js
Ehsan Akhgari fe88009867 Bug 1142772 - Interleave the DOM Cache tests run through the mini-framework; r=bkelly
Here are the changes needed to achieve this:

* We tag each message posted to the framework with a context argument.
  context can be one of "Window", "Worker" or "ServiceWorker".  In the
  places where we handle messages, we only handle the ones corresponding
  to the context that we expect.
* We use Promise.all in order to interleave the execution of the tests.
  This has the nice property of actually getting the tests run
  simultaneously on multi-core machines.
* For ease of debugging test failures, we print the context from which
  each test message is coming from.
* In order for the tests that are run in parallel to not step on each
  other's toes, we introduce a global `context' variable that the test
  script can use to create names that do not clash with concurrent
  test runs.  For example, instead of `caches.open("foo")', one must now
  use: `caches.open("foo" + context)'.
* The existing tests are modified based on the above.
* When running the tests in parallel, the service worker may end up
  controlling both frame.html and message_receiver.html.  The hunk at
  the end of worker_wrapper.js is intended to ensure that we will
  always be communicating with message_receiver.html.
* An order argument has been added to runTests which can be set to
  "sequential" in order to run the tests in different contexts in
  parallel.  If the argument is omitted, the default is "parallel".
2015-03-13 14:32:02 -04:00

130 lines
3.2 KiB
JavaScript

// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
//
// ServiceWorker equivalent of worker_wrapper.js.
var client;
var context;
function ok(a, msg) {
client.postMessage({type: 'status', status: !!a,
msg: a + ": " + msg, context: context});
}
function is(a, b, msg) {
client.postMessage({type: 'status', status: a === b,
msg: a + " === " + b + ": " + msg, context: context });
}
function workerTestArrayEquals(a, b) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length != b.length) {
return false;
}
for (var i = 0, n = a.length; i < n; ++i) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function testDone() {
client.postMessage({ type: 'finish', context: context });
}
function workerTestGetPrefs(prefs, cb) {
addEventListener('message', function workerTestGetPrefsCB(e) {
if (e.data.type != 'returnPrefs' ||
!workerTestArrayEquals(prefs, e.data.prefs)) {
return;
}
removeEventListener('message', workerTestGetPrefsCB);
cb(e.data.result);
});
client.postMessage({
type: 'getPrefs',
context: context,
prefs: prefs
});
}
function workerTestGetPermissions(permissions, cb) {
addEventListener('message', function workerTestGetPermissionsCB(e) {
if (e.data.type != 'returnPermissions' ||
!workerTestArrayEquals(permissions, e.data.permissions)) {
return;
}
removeEventListener('message', workerTestGetPermissionsCB);
cb(e.data.result);
});
client.postMessage({
type: 'getPermissions',
context: context,
permissions: permissions
});
}
function workerTestGetVersion(cb) {
addEventListener('message', function workerTestGetVersionCB(e) {
if (e.data.type !== 'returnVersion') {
return;
}
removeEventListener('message', workerTestGetVersionCB);
cb(e.data.result);
});
client.postMessage({
context: context,
type: 'getVersion'
});
}
function workerTestGetUserAgent(cb) {
addEventListener('message', function workerTestGetUserAgentCB(e) {
if (e.data.type !== 'returnUserAgent') {
return;
}
removeEventListener('message', workerTestGetUserAgentCB);
cb(e.data.result);
});
client.postMessage({
context: context,
type: 'getUserAgent'
});
}
addEventListener('message', function workerWrapperOnMessage(e) {
removeEventListener('message', workerWrapperOnMessage);
var data = e.data;
function runScript() {
try {
importScripts(data.script);
} catch(e) {
client.postMessage({
type: 'status',
status: false,
context: context,
msg: 'worker failed to import ' + data.script + "; error: " + e.message
});
}
}
if ("ServiceWorker" in self) {
self.clients.matchAll().then(function(clients) {
for (var i = 0; i < clients.length; ++i) {
if (clients[i].url.indexOf("message_receiver.html") > -1) {
client = clients[i];
break;
}
}
if (!client) {
dump("We couldn't find the message_receiver window, the test will fail\n");
}
context = "ServiceWorker";
runScript();
});
} else {
client = self;
context = "Worker";
runScript();
}
});