Skip to content

Commit

Permalink
Bug 1392408 Part 6 - Add test for capturing worker stacks in net moni…
Browse files Browse the repository at this point in the history
…tor, r=ochameau.

--HG--
extra : rebase_source : 4d4c0e454dbe607462875a655aa407cfc9d57075
  • Loading branch information
bhackett1024 committed Apr 19, 2019
1 parent 0a2217b commit 239349e
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 39 deletions.
4 changes: 4 additions & 0 deletions devtools/client/netmonitor/test/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ support-files =
html_copy-as-curl.html
html_curl-utils.html
html_open-request-in-tab.html
html_worker-test-page.html
js_worker-test.js
js_worker-test2.js
sjs_content-type-test-server.sjs
sjs_cors-test-server.sjs
sjs_https-redirect-test-server.sjs
Expand Down Expand Up @@ -218,3 +221,4 @@ skip-if = true # TODO: fix the test
[browser_net_truncate.js]
[browser_net_view-source-debugger.js]
[browser_net_waterfall-click.js]
[browser_net_worker_stacks.js]
40 changes: 1 addition & 39 deletions devtools/client/netmonitor/test/browser_net_cause.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ add_task(async function() {
const { document, store, windowRequire, connector } = monitor.panelWin;
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
const {
getDisplayedRequests,
getSortedRequests,
} = windowRequire("devtools/client/netmonitor/src/selectors/index");

Expand All @@ -110,44 +109,7 @@ add_task(async function() {
is(store.getState().requests.requests.size, EXPECTED_REQUESTS.length,
"All the page events should be recorded.");

EXPECTED_REQUESTS.forEach((spec, i) => {
const { method, url, causeType, causeUri, stack } = spec;

const requestItem = getSortedRequests(store.getState()).get(i);
verifyRequestItemTarget(
document,
getDisplayedRequests(store.getState()),
requestItem,
method,
url,
{ cause: { type: causeType, loadingDocumentUri: causeUri } }
);

const stacktrace = requestItem.stacktrace;
const stackLen = stacktrace ? stacktrace.length : 0;

if (stack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,
`Request #${i} (${causeType}) has a stacktrace with ${stackLen} items`);

// if "stack" is array, check the details about the top stack frames
if (Array.isArray(stack)) {
stack.forEach((frame, j) => {
is(stacktrace[j].functionName, frame.fn,
`Request #${i} has the correct function on JS stack frame #${j}`);
is(stacktrace[j].filename.split("/").pop(), frame.file,
`Request #${i} has the correct file on JS stack frame #${j}`);
is(stacktrace[j].lineNumber, frame.line,
`Request #${i} has the correct line number on JS stack frame #${j}`);
is(stacktrace[j].asyncCause, frame.asyncCause,
`Request #${i} has the correct async cause on JS stack frame #${j}`);
});
}
} else {
is(stackLen, 0, `Request #${i} (${causeType}) has an empty stacktrace`);
}
});
validateRequests(EXPECTED_REQUESTS, monitor);

// Sort the requests by cause and check the order
EventUtils.sendMouseEvent({ type: "click" },
Expand Down
100 changes: 100 additions & 0 deletions devtools/client/netmonitor/test/browser_net_worker_stacks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Test that we get stack traces for the network requests made when starting or
// running worker threads.

const TOP_FILE_NAME = "html_worker-test-page.html";
const TOP_URL = EXAMPLE_URL + TOP_FILE_NAME;
const WORKER_FILE_NAME = "js_worker-test.js";
const WORKER_URL = EXAMPLE_URL + WORKER_FILE_NAME;

const EXPECTED_REQUESTS = [
{
method: "GET",
url: TOP_URL,
causeType: "document",
causeUri: null,
stack: true,
},
{
method: "GET",
url: WORKER_URL,
causeType: "script",
causeUri: TOP_URL,
stack: [
{ fn: "startWorkerInner", file: TOP_FILE_NAME, line: 11 },
{ fn: "startWorker", file: TOP_FILE_NAME, line: 8 },
{ file: TOP_FILE_NAME, line: 4 },
],
},
{
method: "GET",
url: EXAMPLE_URL + "missing1.js",
causeType: "script",
causeUri: TOP_URL,
stack: [
{ fn: "importScriptsFromWorker", file: WORKER_FILE_NAME, line: 14 },
{ file: WORKER_FILE_NAME, line: 10 },
],
},
{
method: "GET",
url: EXAMPLE_URL + "missing2.js",
causeType: "script",
causeUri: TOP_URL,
stack: [
{ fn: "importScriptsFromWorker", file: WORKER_FILE_NAME, line: 14 },
{ file: WORKER_FILE_NAME, line: 10 },
],
},
{
method: "GET",
url: EXAMPLE_URL + "js_worker-test2.js",
causeType: "script",
causeUri: TOP_URL,
stack: [
{ fn: "startWorkerFromWorker", file: WORKER_FILE_NAME, line: 7 },
{ file: WORKER_FILE_NAME, line: 3 },
],
},
{
method: "GET",
url: EXAMPLE_URL + "missing.json",
causeType: "xhr",
causeUri: TOP_URL,
stack: [
{ fn: "createJSONRequest", file: WORKER_FILE_NAME, line: 22 },
{ file: WORKER_FILE_NAME, line: 18 },
],
},
];

add_task(async function() {
// Load a different URL first to instantiate the network monitor before we
// load the page we're really interested in.
const { tab, monitor } = await initNetMonitor(SIMPLE_URL);

const { store, windowRequire, connector } = monitor.panelWin;
const {
getSortedRequests,
} = windowRequire("devtools/client/netmonitor/src/selectors/index");

BrowserTestUtils.loadURI(tab.linkedBrowser, TOP_URL);

await waitForNetworkEvents(monitor, EXPECTED_REQUESTS.length);

is(store.getState().requests.requests.size, EXPECTED_REQUESTS.length,
"All the page events should be recorded.");

// Wait for stack traces from all requests.
const requests = getSortedRequests(store.getState());
await Promise.all(requests.map(requestItem =>
connector.requestData(requestItem.id, "stackTrace")));

validateRequests(EXPECTED_REQUESTS, monitor);

await teardown(monitor);
});
47 changes: 47 additions & 0 deletions devtools/client/netmonitor/test/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -867,3 +867,50 @@ function queryTelemetryEvents(query) {
// Return the `extra` field (which is event[5]e).
return filtersChangedEvents.map(event => event[5]);
}

function validateRequests(requests, monitor) {
const { document, store, windowRequire } = monitor.panelWin;

const {
getDisplayedRequests,
} = windowRequire("devtools/client/netmonitor/src/selectors/index");

requests.forEach((spec, i) => {
const { method, url, causeType, causeUri, stack } = spec;

const requestItem = getSortedRequests(store.getState()).get(i);
verifyRequestItemTarget(
document,
getDisplayedRequests(store.getState()),
requestItem,
method,
url,
{ cause: { type: causeType, loadingDocumentUri: causeUri } }
);

const stacktrace = requestItem.stacktrace;
const stackLen = stacktrace ? stacktrace.length : 0;

if (stack) {
ok(stacktrace, `Request #${i} has a stacktrace`);
ok(stackLen > 0,
`Request #${i} (${causeType}) has a stacktrace with ${stackLen} items`);

// if "stack" is array, check the details about the top stack frames
if (Array.isArray(stack)) {
stack.forEach((frame, j) => {
is(stacktrace[j].functionName, frame.fn,
`Request #${i} has the correct function on JS stack frame #${j}`);
is(stacktrace[j].filename.split("/").pop(), frame.file,
`Request #${i} has the correct file on JS stack frame #${j}`);
is(stacktrace[j].lineNumber, frame.line,
`Request #${i} has the correct line number on JS stack frame #${j}`);
is(stacktrace[j].asyncCause, frame.asyncCause,
`Request #${i} has the correct async cause on JS stack frame #${j}`);
});
}
} else {
is(stackLen, 0, `Request #${i} (${causeType}) has an empty stacktrace`);
}
});
}
13 changes: 13 additions & 0 deletions devtools/client/netmonitor/test/html_worker-test-page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
/* eslint-disable no-unused-vars */
"use strict";
startWorker();

var w;
function startWorker() {
startWorkerInner();
}
function startWorkerInner() {
w = new Worker("js_worker-test.js");
}
</script>
24 changes: 24 additions & 0 deletions devtools/client/netmonitor/test/js_worker-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable no-unused-vars, no-undef */
"use strict";
startWorkerFromWorker();

var w;
function startWorkerFromWorker() {
w = new Worker("js_worker-test2.js");
}

importScriptsFromWorker();

function importScriptsFromWorker() {
try {
importScripts("missing1.js", "missing2.js");
} catch (e) {}
}

createJSONRequest();

function createJSONRequest() {
const request = new XMLHttpRequest();
request.open("GET", "missing.json", true);
request.send(null);
}
3 changes: 3 additions & 0 deletions devtools/client/netmonitor/test/js_worker-test2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"use strict";

console.log("I AM A WORKER");

0 comments on commit 239349e

Please sign in to comment.