test_dom_quota_try.js (4746B)
1 /** 2 * Any copyright is dedicated to the Public Domain. 3 * http://creativecommons.org/publicdomain/zero/1.0/ 4 */ 5 6 const { AppConstants } = ChromeUtils.importESModule( 7 "resource://gre/modules/AppConstants.sys.mjs" 8 ); 9 10 const { TelemetryTestUtils } = ChromeUtils.importESModule( 11 "resource://testing-common/TelemetryTestUtils.sys.mjs" 12 ); 13 14 // This is a list of all extra keys that are exposed to telemetry. Please only 15 // add things to this list with great care and proper code review from relevant 16 // module owner/peers and proper data review from data stewards. 17 const allowedExtraKeys = [ 18 "context", 19 "frame_id", 20 "process_id", 21 "result", 22 "seq", 23 "severity", 24 "source_file", 25 "source_line", 26 "stack_id", 27 ]; 28 29 const originSchemes = [ 30 "http", 31 "https", 32 "ftp", 33 "ws", 34 "wss", 35 "gopher", 36 "blob", 37 "file", 38 "data", 39 ]; 40 41 const testcases = [ 42 // Test temporary storage initialization with and without a broken origin 43 // directory. 44 { 45 async setup(expectedInitResult) { 46 Services.prefs.setBoolPref("dom.quotaManager.loadQuotaFromCache", false); 47 Services.prefs.setBoolPref( 48 "dom.quotaManager.loadQuotaFromSecondaryCache", 49 false 50 ); 51 52 let request = init(); 53 await requestFinished(request); 54 55 request = initTemporaryStorage(); 56 await requestFinished(request); 57 58 request = initTemporaryOrigin( 59 "default", 60 getPrincipal("https://example.com") 61 ); 62 await requestFinished(request); 63 64 const usageFile = getRelativeFile( 65 "storage/default/https+++example.com/ls/usage" 66 ); 67 68 if (!expectedInitResult) { 69 usageFile.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755); 70 } else { 71 usageFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o666); 72 } 73 74 // XXX It would be nice to have a method which shuts down temporary 75 // storage only. Now we have to shut down entire storage (including 76 // temporary storage) and then initialize storage again. 77 request = reset(); 78 await requestFinished(request); 79 80 request = init(); 81 await requestFinished(request); 82 }, 83 initFunction: initTemporaryStorage, 84 getExpectedNumberOfEvents() { 85 if (AppConstants.EARLY_BETA_OR_EARLIER || AppConstants.DEBUG) { 86 if (AppConstants.NIGHTLY_BUILD) { 87 return { 88 initFailure: 10, 89 initSuccess: 0, 90 }; 91 } 92 93 return { 94 initFailure: 15, 95 initSuccess: 0, 96 }; 97 } 98 99 return { 100 initFailure: 0, 101 initSuccess: 0, 102 }; 103 }, 104 async cleanup() { 105 const request = clear(); 106 await requestFinished(request); 107 108 Services.prefs.setBoolPref("dom.quotaManager.loadQuotaFromCache", true); 109 }, 110 }, 111 ]; 112 113 function verifyEvents(expectedNumberOfEvents) { 114 const events = TelemetryTestUtils.getEvents({ 115 category: "dom.quota.try", 116 method: "error", 117 }); 118 119 is( 120 events.length, 121 expectedNumberOfEvents, 122 "The number of events must match the expected number of events" 123 ); 124 125 for (const event of events) { 126 for (const extraKey in event.extra) { 127 ok( 128 allowedExtraKeys.includes(extraKey), 129 `The extra key ${extraKey} must be in the allow list` 130 ); 131 132 const extraValue = event.extra[extraKey]; 133 134 // These are extra paranoia checks to ensure extra values don't contain 135 // origin like strings. 136 for (const suffix of ["://", "+++"]) { 137 ok( 138 originSchemes.every( 139 originScheme => !extraValue.includes(originScheme + suffix) 140 ), 141 `The extra value ${extraValue} must not contain origin like strings` 142 ); 143 } 144 } 145 } 146 } 147 148 async function testSteps() { 149 for (const testcase of testcases) { 150 for (const expectedInitResult of [false, true]) { 151 // Clear all events. 152 Services.telemetry.clearEvents(); 153 154 info( 155 `Verifying the events when the initialization ` + 156 `${expectedInitResult ? "succeeds" : "fails"}` 157 ); 158 159 await testcase.setup(expectedInitResult); 160 161 const msg = `Should ${expectedInitResult ? "not " : ""} have thrown`; 162 163 let request = testcase.initFunction(); 164 try { 165 await requestFinished(request); 166 ok(expectedInitResult, msg); 167 } catch (ex) { 168 ok(!expectedInitResult, msg); 169 } 170 171 const expectedNumberOfEventsObject = testcase.getExpectedNumberOfEvents 172 ? testcase.getExpectedNumberOfEvents() 173 : testcase.expectedNumberOfEvents; 174 175 const expectedNumberOfEvents = expectedInitResult 176 ? expectedNumberOfEventsObject.initSuccess 177 : expectedNumberOfEventsObject.initFailure; 178 179 verifyEvents(expectedNumberOfEvents); 180 181 await testcase.cleanup(); 182 } 183 } 184 }