browser_worker_use_counters.js (5674B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 "use strict"; 5 6 const gHttpTestRoot = "https://example.com/browser/dom/workers/test/"; 7 8 function unscream(s) { 9 // Takes SCREAMINGCASE `s` and returns "Screamingcase". 10 return s.charAt(0) + s.slice(1).toLowerCase(); 11 } 12 13 function screamToCamel(s) { 14 // Takes SCREAMING_CASE `s` and returns "screamingCase". 15 const pascal = s.split("_").map(unscream).join(""); 16 return pascal.charAt(0).toLowerCase() + pascal.slice(1); 17 } 18 19 var check_use_counter_worker = async function ( 20 use_counter_name, 21 worker_type, 22 content_task 23 ) { 24 info(`checking ${use_counter_name} use counters for ${worker_type} worker`); 25 26 let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank"); 27 gBrowser.selectedTab = newTab; 28 newTab.linkedBrowser.stop(); 29 30 // Hold on to the current values of the instrumentation we're 31 // interested in. 32 await Services.fog.testFlushAllChildren(); 33 let glean_before = 34 Glean[`useCounterWorker${unscream(worker_type)}`][ 35 screamToCamel(use_counter_name) 36 ].testGetValue(); 37 let glean_destructions_before = 38 Glean.useCounter[ 39 `${worker_type.toLowerCase()}WorkersDestroyed` 40 ].testGetValue(); 41 42 BrowserTestUtils.startLoadingURIString( 43 gBrowser.selectedBrowser, 44 gHttpTestRoot + "file_use_counter_worker.html" 45 ); 46 await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); 47 await content_task(gBrowser.selectedBrowser); 48 49 // Tear down the page. 50 let tabClosed = BrowserTestUtils.waitForTabClosing(newTab); 51 gBrowser.removeTab(newTab); 52 await tabClosed; 53 54 // Grab data again and compare. 55 // We'd like for this to be synchronous, but use counters are reported on 56 // worker destruction which we don't directly observe. 57 // So we check in a quick loop. 58 await BrowserTestUtils.waitForCondition(async () => { 59 await Services.fog.testFlushAllChildren(); 60 return ( 61 glean_before != 62 Glean[`useCounterWorker${unscream(worker_type)}`][ 63 screamToCamel(use_counter_name) 64 ].testGetValue() 65 ); 66 }); 67 let glean_after = 68 Glean[`useCounterWorker${unscream(worker_type)}`][ 69 screamToCamel(use_counter_name) 70 ].testGetValue(); 71 let glean_destructions_after = 72 Glean.useCounter[ 73 `${worker_type.toLowerCase()}WorkersDestroyed` 74 ].testGetValue(); 75 76 is( 77 glean_after, 78 glean_before + 1, 79 `Glean counter ${use_counter_name} for ${worker_type} worker is correct.` 80 ); 81 // There might be other workers created by prior tests get destroyed during 82 // this tests. 83 Assert.greater( 84 glean_destructions_after, 85 glean_destructions_before ?? 0, 86 `Glean ${worker_type} worker counts are correct` 87 ); 88 }; 89 90 add_task(async function test_dedicated_worker() { 91 await check_use_counter_worker("CONSOLE_LOG", "DEDICATED", async browser => { 92 await ContentTask.spawn(browser, {}, function () { 93 return new Promise(resolve => { 94 let worker = new content.Worker("file_use_counter_worker.js"); 95 worker.onmessage = function (e) { 96 if (e.data === "DONE") { 97 worker.terminate(); 98 resolve(); 99 } 100 }; 101 }); 102 }); 103 }); 104 }); 105 106 add_task(async function test_shared_worker() { 107 await check_use_counter_worker("CONSOLE_LOG", "SHARED", async browser => { 108 await ContentTask.spawn(browser, {}, function () { 109 return new Promise(resolve => { 110 let worker = new content.SharedWorker( 111 "file_use_counter_shared_worker.js" 112 ); 113 worker.port.onmessage = function (e) { 114 if (e.data === "DONE") { 115 resolve(); 116 } 117 }; 118 worker.port.postMessage("RUN"); 119 }); 120 }); 121 }); 122 }); 123 124 add_task(async function test_shared_worker_microtask() { 125 await check_use_counter_worker("CONSOLE_LOG", "SHARED", async browser => { 126 await ContentTask.spawn(browser, {}, function () { 127 return new Promise(resolve => { 128 let worker = new content.SharedWorker( 129 "file_use_counter_shared_worker_microtask.js" 130 ); 131 worker.port.onmessage = function (e) { 132 if (e.data === "DONE") { 133 resolve(); 134 } 135 }; 136 worker.port.postMessage("RUN"); 137 }); 138 }); 139 }); 140 }); 141 142 add_task(async function test_service_worker() { 143 await check_use_counter_worker("CONSOLE_LOG", "SERVICE", async browser => { 144 await ContentTask.spawn(browser, {}, function () { 145 let waitForActivated = async function (registration) { 146 return new Promise(resolve => { 147 let worker = 148 registration.installing || 149 registration.waiting || 150 registration.active; 151 if (worker.state === "activated") { 152 resolve(worker); 153 return; 154 } 155 156 worker.addEventListener("statechange", function onStateChange() { 157 if (worker.state === "activated") { 158 worker.removeEventListener("statechange", onStateChange); 159 resolve(worker); 160 } 161 }); 162 }); 163 }; 164 165 return new Promise(resolve => { 166 content.navigator.serviceWorker 167 .register("file_use_counter_service_worker.js") 168 .then(async registration => { 169 content.navigator.serviceWorker.onmessage = function (e) { 170 if (e.data === "DONE") { 171 registration.unregister().then(resolve); 172 } 173 }; 174 let worker = await waitForActivated(registration); 175 worker.postMessage("RUN"); 176 }); 177 }); 178 }); 179 }); 180 });