summaryrefslogtreecommitdiffstats
path: root/dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js')
-rw-r--r--dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js180
1 files changed, 180 insertions, 0 deletions
diff --git a/dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js b/dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js
new file mode 100644
index 0000000000..28bb2d63b4
--- /dev/null
+++ b/dom/quota/test/xpcshell/telemetry/test_dom_quota_try.js
@@ -0,0 +1,180 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+const { TelemetryTestUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/TelemetryTestUtils.sys.mjs"
+);
+
+// This is a list of all extra keys that are exposed to telemetry. Please only
+// add things to this list with great care and proper code review from relevant
+// module owner/peers and proper data review from data stewards.
+const allowedExtraKeys = [
+ "context",
+ "frame_id",
+ "process_id",
+ "result",
+ "seq",
+ "severity",
+ "source_file",
+ "source_line",
+ "stack_id",
+];
+
+const originSchemes = [
+ "http",
+ "https",
+ "ftp",
+ "ws",
+ "wss",
+ "gopher",
+ "blob",
+ "file",
+ "data",
+];
+
+const testcases = [
+ // Test temporary storage initialization with and without a broken origin
+ // directory.
+ {
+ async setup(expectedInitResult) {
+ Services.prefs.setBoolPref("dom.quotaManager.loadQuotaFromCache", false);
+
+ let request = init();
+ await requestFinished(request);
+
+ request = initTemporaryStorage();
+ await requestFinished(request);
+
+ request = initTemporaryOrigin(
+ "default",
+ getPrincipal("https://example.com")
+ );
+ await requestFinished(request);
+
+ const usageFile = getRelativeFile(
+ "storage/default/https+++example.com/ls/usage"
+ );
+
+ if (!expectedInitResult) {
+ usageFile.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
+ } else {
+ usageFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666);
+ }
+
+ // XXX It would be nice to have a method which shuts down temporary
+ // storage only. Now we have to shut down entire storage (including
+ // temporary storage) and then initialize storage again.
+ request = reset();
+ await requestFinished(request);
+
+ request = init();
+ await requestFinished(request);
+ },
+ initFunction: initTemporaryStorage,
+ getExpectedNumberOfEvents() {
+ if (AppConstants.EARLY_BETA_OR_EARLIER || AppConstants.DEBUG) {
+ if (AppConstants.NIGHTLY_BUILD) {
+ return {
+ initFailure: 9,
+ initSuccess: 0,
+ };
+ }
+
+ return {
+ initFailure: 14,
+ initSuccess: 0,
+ };
+ }
+
+ return {
+ initFailure: 0,
+ initSuccess: 0,
+ };
+ },
+ async cleanup() {
+ const request = clear();
+ await requestFinished(request);
+
+ Services.prefs.setBoolPref("dom.quotaManager.loadQuotaFromCache", true);
+ },
+ },
+];
+
+function verifyEvents(expectedNumberOfEvents) {
+ const events = TelemetryTestUtils.getEvents({
+ category: "dom.quota.try",
+ method: "error",
+ });
+
+ is(
+ events.length,
+ expectedNumberOfEvents,
+ "The number of events must match the expected number of events"
+ );
+
+ for (const event of events) {
+ for (const extraKey in event.extra) {
+ ok(
+ allowedExtraKeys.includes(extraKey),
+ `The extra key ${extraKey} must be in the allow list`
+ );
+
+ const extraValue = event.extra[extraKey];
+
+ // These are extra paranoia checks to ensure extra values don't contain
+ // origin like strings.
+ for (const suffix of ["://", "+++"]) {
+ ok(
+ originSchemes.every(
+ originScheme => !extraValue.includes(originScheme + suffix)
+ ),
+ `The extra value ${extraValue} must not contain origin like strings`
+ );
+ }
+ }
+ }
+}
+
+async function testSteps() {
+ for (const testcase of testcases) {
+ for (const expectedInitResult of [false, true]) {
+ // Clear all events.
+ Services.telemetry.clearEvents();
+
+ info(
+ `Verifying the events when the initialization ` +
+ `${expectedInitResult ? "succeeds" : "fails"}`
+ );
+
+ await testcase.setup(expectedInitResult);
+
+ const msg = `Should ${expectedInitResult ? "not " : ""} have thrown`;
+
+ let request = testcase.initFunction();
+ try {
+ await requestFinished(request);
+ ok(expectedInitResult, msg);
+ } catch (ex) {
+ ok(!expectedInitResult, msg);
+ }
+
+ const expectedNumberOfEventsObject = testcase.getExpectedNumberOfEvents
+ ? testcase.getExpectedNumberOfEvents()
+ : testcase.expectedNumberOfEvents;
+
+ const expectedNumberOfEvents = expectedInitResult
+ ? expectedNumberOfEventsObject.initSuccess
+ : expectedNumberOfEventsObject.initFailure;
+
+ verifyEvents(expectedNumberOfEvents);
+
+ await testcase.cleanup();
+ }
+ }
+}