Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* 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/. */
/**
* Test that we emit network markers accordingly.
* In this file we'll test the redirect cases.
*/
add_task(async function test_network_markers_service_worker_setup() {
// Disabling cache makes the result more predictable especially in verify mode.
await SpecialPowers.pushPrefEnv({
set: [
["browser.cache.disk.enable", false],
["browser.cache.memory.enable", false],
],
});
});
add_task(async function test_network_markers_redirect_simple() {
// In this test, we request an HTML page that gets redirected. This is a
// top-level navigation.
Assert.ok(
!Services.profiler.IsActive(),
"The profiler is not currently active"
);
startProfilerForMarkerTests();
const targetFileNameWithCacheBust = "simple.html";
const url =
BASE_URL_HTTPS +
"redirect.sjs?" +
encodeURIComponent(targetFileNameWithCacheBust);
const targetUrl = BASE_URL_HTTPS + targetFileNameWithCacheBust;
await BrowserTestUtils.withNewTab(url, async contentBrowser => {
const contentPid = await SpecialPowers.spawn(
contentBrowser,
[],
() => Services.appinfo.processID
);
const { parentThread, contentThread } = await stopProfilerNowAndGetThreads(
contentPid
);
const parentNetworkMarkers = getInflatedNetworkMarkers(parentThread);
const contentNetworkMarkers = getInflatedNetworkMarkers(contentThread);
info(JSON.stringify(parentNetworkMarkers, null, 2));
info(JSON.stringify(contentNetworkMarkers, null, 2));
Assert.equal(
parentNetworkMarkers.length,
4,
`We should get 2 pairs of network markers in the parent thread.`
);
/* It looks like that for a redirection for the top level navigation, the
* content thread sees the markers for the second request only.
* See Bug 1692879. */
Assert.equal(
contentNetworkMarkers.length,
2,
`We should get one pair of network markers in the content thread.`
);
const parentRedirectMarker = parentNetworkMarkers[1];
const parentStopMarker = parentNetworkMarkers[3];
// There's no content redirect marker for the reason outlined above.
const contentStopMarker = contentNetworkMarkers[1];
Assert.objectContains(parentRedirectMarker, {
name: Expect.stringMatches(`Load \\d+:.*${escapeStringRegexp(url)}`),
data: Expect.objectContainsOnly({
type: "Network",
status: "STATUS_REDIRECT",
URI: url,
RedirectURI: targetUrl,
requestMethod: "GET",
contentType: null,
startTime: Expect.number(),
endTime: Expect.number(),
domainLookupStart: Expect.number(),
domainLookupEnd: Expect.number(),
connectStart: Expect.number(),
tcpConnectEnd: Expect.number(),
connectEnd: Expect.number(),
requestStart: Expect.number(),
responseStart: Expect.number(),
responseEnd: Expect.number(),
id: Expect.number(),
redirectId: parentStopMarker.data.id,
pri: Expect.number(),
cache: Expect.stringMatches(/Missed|Unresolved/),
redirectType: "Permanent",
isHttpToHttpsRedirect: false,
}),
});
const expectedProperties = {
name: Expect.stringMatches(
`Load \\d+:.*${escapeStringRegexp(targetUrl)}`
),
};
const expectedDataProperties = {
type: "Network",
status: "STATUS_STOP",
URI: targetUrl,
requestMethod: "GET",
contentType: "text/html",
startTime: Expect.number(),
endTime: Expect.number(),
domainLookupStart: Expect.number(),
domainLookupEnd: Expect.number(),
connectStart: Expect.number(),
tcpConnectEnd: Expect.number(),
connectEnd: Expect.number(),
requestStart: Expect.number(),
responseStart: Expect.number(),
responseEnd: Expect.number(),
id: Expect.number(),
count: Expect.number(),
pri: Expect.number(),
};
Assert.objectContains(parentStopMarker, expectedProperties);
Assert.objectContains(contentStopMarker, expectedProperties);
// The cache information is missing from the content marker, it's only part
// of the parent marker. See Bug 1544821.
Assert.objectContainsOnly(parentStopMarker.data, {
...expectedDataProperties,
// Because the request races with the cache, these 2 values are valid:
// "Missed" when the cache answered before we get a result from the network.
// "Unresolved" when we got a response from the network before the cache subsystem.
cache: Expect.stringMatches(/^(Missed|Unresolved)$/),
});
Assert.objectContainsOnly(contentStopMarker.data, expectedDataProperties);
});
});
add_task(async function test_network_markers_redirect_resources() {
// In this test we request an HTML file that itself contains resources that
// are redirected.
Assert.ok(
!Services.profiler.IsActive(),
"The profiler is not currently active"
);
startProfilerForMarkerTests();
const url =
BASE_URL_HTTPS + "page_with_resources.html?cacheBust=" + Math.random();
await BrowserTestUtils.withNewTab(url, async contentBrowser => {
const contentPid = await SpecialPowers.spawn(
contentBrowser,
[],
() => Services.appinfo.processID
);
const { parentThread, contentThread } = await stopProfilerNowAndGetThreads(
contentPid
);
const parentNetworkMarkers = getInflatedNetworkMarkers(parentThread);
const contentNetworkMarkers = getInflatedNetworkMarkers(contentThread);
info(JSON.stringify(parentNetworkMarkers, null, 2));
info(JSON.stringify(contentNetworkMarkers, null, 2));
Assert.equal(
parentNetworkMarkers.length,
8,
`We should get 4 pairs of network markers in the parent thread.`
// 1 - The main page
// 2 - The SVG
// 3 - The redirected request for the second SVG request.
// 4 - The SVG, again
);
/* In this second test, the top level navigation request isn't redirected.
* Contrary to Bug 1692879 we get all network markers for redirected
* resources. */
Assert.equal(
contentNetworkMarkers.length,
8,
`We should get 4 pairs of network markers in the content thread.`
);
// The same resource firefox-logo-nightly.svg is requested twice, but the
// second time it is redirected.
// We're not interested in the main page, as we test that in other files.
// In this page we're only interested in the marker for requested resources.
const parentPairs = getPairsOfNetworkMarkers(parentNetworkMarkers);
const contentPairs = getPairsOfNetworkMarkers(contentNetworkMarkers);
// First, make sure we properly matched all start with stop markers. This
// means that both arrays should contain only arrays of 2 elements.
parentPairs.forEach(pair =>
Assert.equal(
pair.length,
2,
`For the URL ${pair[0].data.URI} we should get 2 markers in the parent process.`
)
);
contentPairs.forEach(pair =>
Assert.equal(
pair.length,
2,
`For the URL ${pair[0].data.URI} we should get 2 markers in the content process.`
)
);
const parentFirstStopMarker = parentPairs[1][1];
const parentRedirectMarker = parentPairs[2][1];
const parentSecondStopMarker = parentPairs[3][1];
const contentFirstStopMarker = contentPairs[1][1];
const contentRedirectMarker = contentPairs[2][1];
const contentSecondStopMarker = contentPairs[3][1];
const expectedCommonDataProperties = {
type: "Network",
requestMethod: "GET",
startTime: Expect.number(),
endTime: Expect.number(),
id: Expect.number(),
pri: Expect.number(),
innerWindowID: Expect.number(),
requestStart: Expect.number(),
responseStart: Expect.number(),
responseEnd: Expect.number(),
};
// These properties are present when a connection is fully opened. This is
// most often the case, unless we're in verify mode, because in that case
// we run the same tests several times in the same Firefox and they might be
// cached, or in chaos mode Firefox may make all requests sequentially on
// the same connection.
// In these cases, these properties won't always be present.
const expectedConnectionProperties = {
domainLookupStart: Expect.number(),
domainLookupEnd: Expect.number(),
connectStart: Expect.number(),
tcpConnectEnd: Expect.number(),
connectEnd: Expect.number(),
};
const expectedPropertiesForStopMarker = {
name: Expect.stringMatches(/Load \d+:.*\/firefox-logo-nightly\.svg/),
};
const expectedDataPropertiesForStopMarker = {
...expectedCommonDataProperties,
status: "STATUS_STOP",
URI: Expect.stringContains("/firefox-logo-nightly.svg"),
contentType: "image/svg+xml",
count: Expect.number(),
};
const expectedPropertiesForRedirectMarker = {
name: Expect.stringMatches(
/Load \d+:.*\/redirect.sjs\?firefox-logo-nightly\.svg/
),
};
const expectedDataPropertiesForRedirectMarker = {
...expectedCommonDataProperties,
...expectedConnectionProperties,
status: "STATUS_REDIRECT",
URI: Expect.stringContains("/redirect.sjs?firefox-logo-nightly.svg"),
RedirectURI: Expect.stringContains("/firefox-logo-nightly.svg"),
contentType: null,
redirectType: "Permanent",
isHttpToHttpsRedirect: false,
};
Assert.objectContains(
parentFirstStopMarker,
expectedPropertiesForStopMarker
);
Assert.objectContainsOnly(parentFirstStopMarker.data, {
...expectedDataPropertiesForStopMarker,
...expectedConnectionProperties,
// The cache information is missing from the content marker, it's only part
// of the parent marker. See Bug 1544821.
// Also, because the request races with the cache, these 2 values are valid:
// "Missed" when the cache answered before we get a result from the network.
// "Unresolved" when we got a response from the network before the cache subsystem.
cache: Expect.stringMatches(/^(Missed|Unresolved)$/),
});
Assert.objectContains(
contentFirstStopMarker,
expectedPropertiesForStopMarker
);
Assert.objectContainsOnly(contentFirstStopMarker.data, {
...expectedDataPropertiesForStopMarker,
...expectedConnectionProperties,
});
Assert.objectContains(
parentRedirectMarker,
expectedPropertiesForRedirectMarker
);
Assert.objectContainsOnly(parentRedirectMarker.data, {
...expectedDataPropertiesForRedirectMarker,
redirectId: parentSecondStopMarker.data.id,
// See above for the full explanation about the cache property.
cache: Expect.stringMatches(/^(Missed|Unresolved)$/),
});
Assert.objectContains(
contentRedirectMarker,
expectedPropertiesForRedirectMarker
);
Assert.objectContainsOnly(contentRedirectMarker.data, {
...expectedDataPropertiesForRedirectMarker,
redirectId: contentSecondStopMarker.data.id,
});
Assert.objectContains(
parentSecondStopMarker,
expectedPropertiesForStopMarker
);
// In Test-Verify mode, sometimes the properties from
// `expectedConnectionProperties` are missing. That's why they're not
// included here, and objectContains is used instead of objectContainsOnly
// like above.
Assert.objectContains(parentSecondStopMarker.data, {
...expectedDataPropertiesForStopMarker,
// The "count" property is absent from the content marker.
count: Expect.number(),
// See above for the full explanation about the cache property.
cache: Expect.stringMatches(/^(Missed|Unresolved)$/),
});
Assert.objectContains(
contentSecondStopMarker,
expectedPropertiesForStopMarker
);
Assert.objectContains(
contentSecondStopMarker.data,
expectedDataPropertiesForStopMarker
);
});
});