зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1596939 Part 3 - Pause new service workers for the target's origin, r=jlast.
Depends on D54293 Differential Revision: https://phabricator.services.mozilla.com/D54298 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ad3914884b
Коммит
44cd7a73e5
|
@ -15,6 +15,14 @@ const EMPTY_URL = (URL_ROOT + "resources/service-workers/empty.html").replace(
|
|||
"test2.example.com"
|
||||
);
|
||||
|
||||
// FIXME bug 1575427 this rejection is very common.
|
||||
const { PromiseTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/PromiseTestUtils.jsm"
|
||||
);
|
||||
PromiseTestUtils.whitelistRejectionsGlobally(
|
||||
/this._frontCreationListeners is null/
|
||||
);
|
||||
|
||||
add_task(async function() {
|
||||
await enableApplicationPanel();
|
||||
|
||||
|
|
|
@ -50,14 +50,12 @@ function setupEvents(dependencies: Dependencies) {
|
|||
sourceQueue.initialize(actions);
|
||||
|
||||
addThreadEventListeners(threadFront);
|
||||
tabTarget.on("workerListChanged", () => threadListChanged("worker"));
|
||||
debuggerClient.mainRoot.on("processListChanged", () =>
|
||||
threadListChanged("contentProcess")
|
||||
);
|
||||
tabTarget.on("workerListChanged", () => threadListChanged());
|
||||
debuggerClient.mainRoot.on("processListChanged", () => threadListChanged());
|
||||
|
||||
if (features.windowlessServiceWorkers || attachAllTargets(tabTarget)) {
|
||||
const workersListener = new WorkersListener(debuggerClient.mainRoot);
|
||||
workersListener.addListener(() => threadListChanged("worker"));
|
||||
workersListener.addListener(() => threadListChanged());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,8 +112,8 @@ function newSource(threadFront: ThreadFront, { source }: SourcePacket) {
|
|||
});
|
||||
}
|
||||
|
||||
function threadListChanged(type) {
|
||||
actions.updateThreads(type);
|
||||
function threadListChanged() {
|
||||
actions.updateThreads();
|
||||
}
|
||||
|
||||
function replayFramePositions(
|
||||
|
|
|
@ -90,6 +90,7 @@ async function listWorkerTargets(args: Args) {
|
|||
} else {
|
||||
workers = (await currentTarget.listWorkers()).workers;
|
||||
if (currentTarget.url && features.windowlessServiceWorkers) {
|
||||
allWorkers = await debuggerClient.mainRoot.listAllWorkerTargets();
|
||||
const {
|
||||
registrations,
|
||||
} = await debuggerClient.mainRoot.listServiceWorkerRegistrations();
|
||||
|
@ -100,10 +101,16 @@ async function listWorkerTargets(args: Args) {
|
|||
}
|
||||
|
||||
for (const front of serviceWorkerRegistrations) {
|
||||
const { activeWorker, waitingWorker, installingWorker } = front;
|
||||
const {
|
||||
activeWorker,
|
||||
waitingWorker,
|
||||
installingWorker,
|
||||
evaluatingWorker,
|
||||
} = front;
|
||||
await maybeMarkServiceWorker(activeWorker, "active");
|
||||
await maybeMarkServiceWorker(waitingWorker, "waiting");
|
||||
await maybeMarkServiceWorker(installingWorker, "installing");
|
||||
await maybeMarkServiceWorker(evaluatingWorker, "evaluating");
|
||||
}
|
||||
|
||||
async function maybeMarkServiceWorker(info, status) {
|
||||
|
@ -111,9 +118,6 @@ async function listWorkerTargets(args: Args) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!allWorkers) {
|
||||
allWorkers = await debuggerClient.mainRoot.listAllWorkerTargets();
|
||||
}
|
||||
const worker = allWorkers.find(front => front && front.id == info.id);
|
||||
if (!worker) {
|
||||
return;
|
||||
|
@ -128,20 +132,37 @@ async function listWorkerTargets(args: Args) {
|
|||
return workers;
|
||||
}
|
||||
|
||||
async function listProcessTargets(args: Args) {
|
||||
const { currentTarget, debuggerClient } = args;
|
||||
if (!attachAllTargets(currentTarget)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
async function getAllProcessTargets(args) {
|
||||
const { debuggerClient } = args;
|
||||
const { processes } = await debuggerClient.mainRoot.listProcesses();
|
||||
const targets = await Promise.all(
|
||||
return Promise.all(
|
||||
processes
|
||||
.filter(descriptor => !descriptor.isParent)
|
||||
.map(descriptor => descriptor.getTarget())
|
||||
);
|
||||
}
|
||||
|
||||
return targets;
|
||||
async function listProcessTargets(args: Args) {
|
||||
const { currentTarget } = args;
|
||||
if (!attachAllTargets(currentTarget)) {
|
||||
if (currentTarget.url && features.windowlessServiceWorkers) {
|
||||
// Service workers associated with our target's origin need to pause until
|
||||
// we attach, regardless of which process they are running in.
|
||||
const origin = new URL(currentTarget.url).origin;
|
||||
const targets = await getAllProcessTargets(args);
|
||||
try {
|
||||
await Promise.all(
|
||||
targets.map(t => t.pauseMatchingServiceWorkers({ origin }))
|
||||
);
|
||||
} catch (e) {
|
||||
// Old servers without pauseMatchingServiceWorkers will throw.
|
||||
// @backward-compatibility: remove in Firefox 75
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
return getAllProcessTargets(args);
|
||||
}
|
||||
|
||||
export async function updateTargets(args: Args) {
|
||||
|
|
|
@ -7,6 +7,14 @@ async function checkWorkerThreads(dbg, count) {
|
|||
ok(true, `Have ${count} threads`);
|
||||
}
|
||||
|
||||
async function checkWorkerStatus(dbg, status) {
|
||||
await waitUntil(() => {
|
||||
const threads = dbg.selectors.getThreads();
|
||||
return threads.some(t => t.serviceWorkerStatus == status);
|
||||
});
|
||||
ok(true, `Have thread with status ${status}`);
|
||||
}
|
||||
|
||||
// Test that we can detect a new service worker and hit breakpoints that we've
|
||||
// set in it.
|
||||
add_task(async function() {
|
||||
|
@ -31,8 +39,9 @@ add_task(async function() {
|
|||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 13);
|
||||
|
||||
// Leave the breakpoint in place for the next subtest.
|
||||
// Leave the breakpoint and worker in place for the next subtest.
|
||||
await resume(dbg);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
|
@ -61,6 +70,7 @@ add_task(async function() {
|
|||
invokeInTab("unregisterWorker");
|
||||
|
||||
await checkWorkerThreads(dbg, 0);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
|
@ -73,6 +83,7 @@ add_task(async function() {
|
|||
|
||||
invokeInTab("registerWorker");
|
||||
await checkWorkerThreads(dbg, 1);
|
||||
await checkWorkerStatus(dbg, "active");
|
||||
|
||||
const firstTab = gBrowser.selectedTab;
|
||||
|
||||
|
@ -101,9 +112,13 @@ add_task(async function() {
|
|||
ok(content0.value.includes("newServiceWorker") != content1.value.includes("newServiceWorker"),
|
||||
"Got two different sources for service worker");
|
||||
|
||||
// Add a breakpoint for the next subtest.
|
||||
await addBreakpoint(dbg, "service-worker.sjs", 2);
|
||||
|
||||
invokeInTab("unregisterWorker");
|
||||
|
||||
await checkWorkerThreads(dbg, 0);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
await removeTab(firstTab);
|
||||
await removeTab(secondTab);
|
||||
|
||||
|
@ -111,3 +126,41 @@ add_task(async function() {
|
|||
await addTab(EXAMPLE_URL + "service-worker.sjs?setStatus=");
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
||||
// Test setting breakpoints while the service worker is starting up.
|
||||
add_task(async function() {
|
||||
info("Subtest #4");
|
||||
|
||||
const toolbox = await openNewTabAndToolbox(EXAMPLE_URL + "doc-service-workers.html", "jsdebugger");
|
||||
const dbg = createDebuggerContext(toolbox);
|
||||
|
||||
invokeInTab("registerWorker");
|
||||
await checkWorkerThreads(dbg, 1);
|
||||
|
||||
await waitForSource(dbg, "service-worker.sjs");
|
||||
const workerSource = findSource(dbg, "service-worker.sjs");
|
||||
|
||||
await waitForBreakpointCount(dbg, 1);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 2);
|
||||
await checkWorkerStatus(dbg, "evaluating");
|
||||
|
||||
await addBreakpoint(dbg, "service-worker.sjs", 19);
|
||||
await resume(dbg);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 19);
|
||||
await checkWorkerStatus(dbg, "installing");
|
||||
|
||||
await addBreakpoint(dbg, "service-worker.sjs", 5);
|
||||
await resume(dbg);
|
||||
await waitForPaused(dbg);
|
||||
assertPausedAtSourceAndLine(dbg, workerSource.id, 5);
|
||||
await checkWorkerStatus(dbg, "active");
|
||||
|
||||
await resume(dbg);
|
||||
invokeInTab("unregisterWorker");
|
||||
|
||||
await checkWorkerThreads(dbg, 0);
|
||||
await waitForRequestsToSettle(dbg);
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
|
@ -19,6 +19,10 @@ self.addEventListener("fetch", event => {
|
|||
event.respondWith(response);
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener("install", event => {
|
||||
dump("Install\\n");
|
||||
});
|
||||
`;
|
||||
|
||||
function handleRequest(request, response) {
|
||||
|
@ -30,17 +34,5 @@ function handleRequest(request, response) {
|
|||
}
|
||||
|
||||
const status = getState("status");
|
||||
|
||||
let newBody = body.replace("STATUS", status);
|
||||
|
||||
if (status == "stuckInstall") {
|
||||
newBody += `
|
||||
self.addEventListener("install", event => {
|
||||
dump("Install\\n");
|
||||
event.waitUntil(new Promise(resolve => {}));
|
||||
});
|
||||
`;
|
||||
}
|
||||
|
||||
response.write(newBody);
|
||||
response.write(body.replace("STATUS", status));
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче