test_suggestBackendMl.js (4172B)
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 5 // Tests for ML Suggest backend. 6 7 "use strict"; 8 9 ChromeUtils.defineESModuleGetters(this, { 10 MLSuggest: "moz-src:///browser/components/urlbar/private/MLSuggest.sys.mjs", 11 setTimeout: "resource://gre/modules/Timer.sys.mjs", 12 }); 13 14 const ML_PREFS = ["browser.ml.enable", "quicksuggest.mlEnabled"]; 15 16 let gSandbox; 17 let gInitializeStub; 18 let gShutdownStub; 19 20 add_setup(async function init() { 21 // Stub `MLSuggest`. 22 gSandbox = sinon.createSandbox(); 23 gInitializeStub = gSandbox.stub(MLSuggest, "initialize"); 24 gShutdownStub = gSandbox.stub(MLSuggest, "shutdown"); 25 26 // Enable Suggest but not the ML backend yet. 27 await QuickSuggestTestUtils.ensureQuickSuggestInit({ 28 prefs: [ 29 ["suggest.quicksuggest.all", true], 30 ["suggest.quicksuggest.sponsored", true], 31 ], 32 }); 33 }); 34 35 function enableMl(enable) { 36 if (enable) { 37 for (let p of ML_PREFS) { 38 UrlbarPrefs.set(p, true); 39 } 40 } else { 41 // This assumes the prefs are false by default, i.e., the ML backend is 42 // disabled by default. 43 for (let p of ML_PREFS) { 44 UrlbarPrefs.clear(p); 45 } 46 } 47 } 48 49 // Init shouldn't be delayed by default. 50 add_task(async function zeroDelay() { 51 // The init timer is always used, its timeout is just set to zero when init 52 // shouldn't be delayed. To test that there's no large delay, get the current 53 // time, enable ML, wait for `initialize()` to be called, and then make sure 54 // the elapsed time is small. Some CI machines are really slow, so this might 55 // take longer than you think. Use a generous expected upper bound of 1s 56 // (1000ms). 57 let startMs = ChromeUtils.now(); 58 enableMl(true); 59 await TestUtils.waitForCondition( 60 () => gInitializeStub.callCount > 0, 61 "Waiting for initialize to be called" 62 ); 63 64 let elapsedMs = ChromeUtils.now() - startMs; 65 Assert.less( 66 elapsedMs, 67 1000, 68 "initialize should have been called quickly after enabling the backend" 69 ); 70 71 enableMl(false); 72 73 gInitializeStub.resetHistory(); 74 gShutdownStub.resetHistory(); 75 }); 76 77 // Delaying init should work properly. 78 add_task(async function delay() { 79 // Delay by 4s. We use a large timeout because some CI machines are slow. 80 let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature({ 81 quickSuggestMlInitDelaySeconds: 4, 82 }); 83 84 enableMl(true); 85 86 Assert.equal( 87 gInitializeStub.callCount, 88 0, 89 "initialize should not have been called immediately after enabling ML" 90 ); 91 92 await waitSeconds(2); 93 94 Assert.equal( 95 gInitializeStub.callCount, 96 0, 97 "initialize should not have been called after waiting 2s" 98 ); 99 100 // Wait a generous 4 more seconds for a total of 6s. 101 await waitSeconds(4); 102 103 Assert.equal( 104 gInitializeStub.callCount, 105 1, 106 "initialize should have been called after waiting a total of 6s" 107 ); 108 109 enableMl(false); 110 Assert.equal( 111 gShutdownStub.callCount, 112 1, 113 "shutdown should have been called after disabling ML" 114 ); 115 116 gInitializeStub.resetHistory(); 117 gShutdownStub.resetHistory(); 118 119 await cleanUpNimbus(); 120 }); 121 122 // `initialize` should not be called if the backend is disabled before the init 123 // timer fires. 124 add_task(async function disabledBeforeTimerFires() { 125 let cleanUpNimbus = await UrlbarTestUtils.initNimbusFeature({ 126 quickSuggestMlInitDelaySeconds: 3, 127 }); 128 129 enableMl(true); 130 131 // Wait a little for better realism. 132 await waitSeconds(1); 133 134 enableMl(false); 135 Assert.equal( 136 gShutdownStub.callCount, 137 1, 138 "shutdown should have been called after disabling ML" 139 ); 140 141 // Wait a generous 3 more seconds for a total of 4s. 142 await waitSeconds(3); 143 144 Assert.equal( 145 gInitializeStub.callCount, 146 0, 147 "initialize should not have been called after waiting 2s" 148 ); 149 150 gInitializeStub.resetHistory(); 151 gShutdownStub.resetHistory(); 152 153 await cleanUpNimbus(); 154 }); 155 156 async function waitSeconds(s) { 157 info(`Waiting ${s} seconds...`); 158 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 159 await new Promise(r => setTimeout(r, s * 1000)); 160 }