Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_trr_confirmation.js
blob6a51ccb43834cef2cee343c3e2eb9937876ce54c
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/. */
5 "use strict";
7 const { TestUtils } = ChromeUtils.importESModule(
8 "resource://testing-common/TestUtils.sys.mjs"
9 );
11 async function waitForConfirmationState(state, msToWait = 0) {
12 await TestUtils.waitForCondition(
13 () => Services.dns.currentTrrConfirmationState == state,
14 `Timed out waiting for ${state}. Currently ${Services.dns.currentTrrConfirmationState}`,
16 msToWait
18 equal(
19 Services.dns.currentTrrConfirmationState,
20 state,
21 "expected confirmation state"
25 const CONFIRM_OFF = 0;
26 const CONFIRM_TRYING_OK = 1;
27 const CONFIRM_OK = 2;
28 const CONFIRM_FAILED = 3;
29 const CONFIRM_TRYING_FAILED = 4;
30 const CONFIRM_DISABLED = 5;
32 function setup() {
33 trr_test_setup();
34 Services.prefs.setBoolPref("network.trr.skip-check-for-blocked-host", true);
37 setup();
38 registerCleanupFunction(async () => {
39 trr_clear_prefs();
40 Services.prefs.clearUserPref("network.trr.skip-check-for-blocked-host");
41 });
43 let trrServer = null;
44 add_task(async function start_trr_server() {
45 trrServer = new TRRServer();
46 registerCleanupFunction(async () => {
47 await trrServer.stop();
48 });
49 await trrServer.start();
50 dump(`port = ${trrServer.port()}\n`);
52 await trrServer.registerDoHAnswers(`faily.com`, "NS", {
53 answers: [
55 name: "faily.com",
56 ttl: 55,
57 type: "NS",
58 flush: false,
59 data: "ns.faily.com",
62 });
64 for (let i = 0; i < 15; i++) {
65 await trrServer.registerDoHAnswers(`failing-domain${i}.faily.com`, "A", {
66 error: 600,
67 });
68 await trrServer.registerDoHAnswers(`failing-domain${i}.faily.com`, "AAAA", {
69 error: 600,
70 });
72 });
74 function trigger15Failures() {
75 // We need to clear the cache in case a previous call to this method
76 // put the results in the DNS cache.
77 Services.dns.clearCache(true);
79 let dnsRequests = [];
80 // There are actually two TRR requests sent for A and AAAA records, so doing
81 // DNS query 10 times should be enough to trigger confirmation process.
82 for (let i = 0; i < 10; i++) {
83 dnsRequests.push(
84 new TRRDNSListener(`failing-domain${i}.faily.com`, {
85 expectedAnswer: "127.0.0.1",
90 return Promise.all(dnsRequests);
93 async function registerNS(delay) {
94 return trrServer.registerDoHAnswers("confirm.example.com", "NS", {
95 answers: [
97 name: "confirm.example.com",
98 ttl: 55,
99 type: "NS",
100 flush: false,
101 data: "test.com",
104 delay,
108 add_task(async function confirm_off() {
109 Services.prefs.setCharPref(
110 "network.trr.confirmationNS",
111 "confirm.example.com"
113 Services.prefs.setIntPref(
114 "network.trr.mode",
115 Ci.nsIDNSService.MODE_NATIVEONLY
117 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OFF);
118 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRROFF);
119 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OFF);
122 add_task(async function confirm_disabled() {
123 Services.prefs.setCharPref(
124 "network.trr.confirmationNS",
125 "confirm.example.com"
127 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY);
128 equal(Services.dns.currentTrrConfirmationState, CONFIRM_DISABLED);
129 Services.prefs.setCharPref("network.trr.confirmationNS", "skip");
130 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
131 equal(Services.dns.currentTrrConfirmationState, CONFIRM_DISABLED);
134 add_task(async function confirm_ok() {
135 Services.dns.clearCache(true);
136 Services.prefs.setCharPref(
137 "network.trr.confirmationNS",
138 "confirm.example.com"
140 await registerNS(0);
141 await trrServer.registerDoHAnswers("example.com", "A", {
142 answers: [
144 name: "example.com",
145 ttl: 55,
146 type: "A",
147 flush: false,
148 data: "1.2.3.4",
152 Services.prefs.setCharPref(
153 "network.trr.uri",
154 `https://foo.example.com:${trrServer.port()}/dns-query`
156 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
157 equal(
158 Services.dns.currentTrrConfirmationState,
159 CONFIRM_TRYING_OK,
160 "Should be CONFIRM_TRYING_OK"
162 await new TRRDNSListener("example.com", { expectedAnswer: "1.2.3.4" });
163 equal(await trrServer.requestCount("example.com", "A"), 1);
164 await waitForConfirmationState(CONFIRM_OK, 1000);
166 await registerNS(500);
167 Services.prefs.setIntPref(
168 "network.trr.mode",
169 Ci.nsIDNSService.MODE_NATIVEONLY
171 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
172 equal(
173 Services.dns.currentTrrConfirmationState,
174 CONFIRM_TRYING_OK,
175 "Should be CONFIRM_TRYING_OK"
177 await new Promise(resolve => do_timeout(100, resolve));
178 equal(
179 Services.dns.currentTrrConfirmationState,
180 CONFIRM_TRYING_OK,
181 "Confirmation should still be pending"
183 await waitForConfirmationState(CONFIRM_OK, 1000);
186 add_task(async function confirm_timeout() {
187 Services.prefs.setIntPref(
188 "network.trr.mode",
189 Ci.nsIDNSService.MODE_NATIVEONLY
191 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OFF);
192 await registerNS(7000);
193 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
194 equal(
195 Services.dns.currentTrrConfirmationState,
196 CONFIRM_TRYING_OK,
197 "Should be CONFIRM_TRYING_OK"
199 await waitForConfirmationState(CONFIRM_FAILED, 7500);
200 // After the confirmation fails, a timer will periodically trigger a retry
201 // causing the state to go into CONFIRM_TRYING_FAILED.
202 await waitForConfirmationState(CONFIRM_TRYING_FAILED, 500);
205 add_task(async function confirm_fail_fast() {
206 Services.prefs.setIntPref(
207 "network.trr.mode",
208 Ci.nsIDNSService.MODE_NATIVEONLY
210 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OFF);
211 await trrServer.registerDoHAnswers("confirm.example.com", "NS", {
212 error: 404,
214 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
215 equal(
216 Services.dns.currentTrrConfirmationState,
217 CONFIRM_TRYING_OK,
218 "Should be CONFIRM_TRYING_OK"
220 await waitForConfirmationState(CONFIRM_FAILED, 100);
223 add_task(async function multiple_failures() {
224 Services.prefs.setIntPref(
225 "network.trr.mode",
226 Ci.nsIDNSService.MODE_NATIVEONLY
228 Services.prefs.setIntPref("network.trr.max-retry-timeout-ms", 8000);
229 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OFF);
231 await registerNS(100);
232 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
233 equal(
234 Services.dns.currentTrrConfirmationState,
235 CONFIRM_TRYING_OK,
236 "Should be CONFIRM_TRYING_OK"
238 await waitForConfirmationState(CONFIRM_OK, 1000);
239 await registerNS(4000);
240 let failures = trigger15Failures();
241 await waitForConfirmationState(CONFIRM_TRYING_OK, 3000);
242 await failures;
243 // Check that failures during confirmation are ignored.
244 await trigger15Failures();
245 equal(
246 Services.dns.currentTrrConfirmationState,
247 CONFIRM_TRYING_OK,
248 "Should be CONFIRM_TRYING_OK"
250 await waitForConfirmationState(CONFIRM_OK, 8500);
253 add_task(async function test_connectivity_change() {
254 await registerNS(100);
255 Services.prefs.setIntPref(
256 "network.trr.mode",
257 Ci.nsIDNSService.MODE_NATIVEONLY
259 let confirmationCount = await trrServer.requestCount(
260 "confirm.example.com",
261 "NS"
263 Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRFIRST);
264 equal(
265 Services.dns.currentTrrConfirmationState,
266 CONFIRM_TRYING_OK,
267 "Should be CONFIRM_TRYING_OK"
269 await waitForConfirmationState(CONFIRM_OK, 1000);
270 equal(
271 await trrServer.requestCount("confirm.example.com", "NS"),
272 confirmationCount + 1
274 Services.obs.notifyObservers(
275 null,
276 "network:captive-portal-connectivity",
277 "clear"
279 // This means a CP check completed successfully. But no CP was previously
280 // detected, so this is mostly a no-op.
281 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OK);
283 Services.obs.notifyObservers(
284 null,
285 "network:captive-portal-connectivity",
286 "captive"
288 // This basically a successful CP login event. Wasn't captive before.
289 // Still treating as a no-op.
290 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OK);
292 // This makes the TRR service set mCaptiveIsPassed=false
293 Services.obs.notifyObservers(
294 null,
295 "captive-portal-login",
296 "{type: 'captive-portal-login', id: 0, url: 'http://localhost/'}"
299 await registerNS(500);
300 let failures = trigger15Failures();
301 // The failure should cause us to go into CONFIRM_TRYING_OK and do an NS req
302 await waitForConfirmationState(CONFIRM_TRYING_OK, 3000);
303 await failures;
305 // The notification sets mCaptiveIsPassed=true then triggers an entirely new
306 // confirmation.
307 Services.obs.notifyObservers(
308 null,
309 "network:captive-portal-connectivity",
310 "clear"
312 // The notification should cause us to send a new confirmation request
313 equal(
314 Services.dns.currentTrrConfirmationState,
315 CONFIRM_TRYING_OK,
316 "Should be CONFIRM_TRYING_OK"
318 await waitForConfirmationState(CONFIRM_OK, 1000);
319 // two extra confirmation events should have been received by the server
320 equal(
321 await trrServer.requestCount("confirm.example.com", "NS"),
322 confirmationCount + 3
326 add_task(async function test_network_change() {
327 let confirmationCount = await trrServer.requestCount(
328 "confirm.example.com",
329 "NS"
331 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OK);
333 Services.obs.notifyObservers(null, "network:link-status-changed", "up");
334 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OK);
335 equal(
336 await trrServer.requestCount("confirm.example.com", "NS"),
337 confirmationCount
340 let failures = trigger15Failures();
341 // The failure should cause us to go into CONFIRM_TRYING_OK and do an NS req
342 await waitForConfirmationState(CONFIRM_TRYING_OK, 3000);
343 await failures;
344 // The network up event should reset the confirmation to TRYING_OK and do
345 // another NS req
346 Services.obs.notifyObservers(null, "network:link-status-changed", "up");
347 equal(Services.dns.currentTrrConfirmationState, CONFIRM_TRYING_OK);
348 await waitForConfirmationState(CONFIRM_OK, 1000);
349 // two extra confirmation events should have been received by the server
350 equal(
351 await trrServer.requestCount("confirm.example.com", "NS"),
352 confirmationCount + 2
356 add_task(async function test_uri_pref_change() {
357 let confirmationCount = await trrServer.requestCount(
358 "confirm.example.com",
359 "NS"
361 equal(Services.dns.currentTrrConfirmationState, CONFIRM_OK);
362 Services.prefs.setCharPref(
363 "network.trr.uri",
364 `https://foo.example.com:${trrServer.port()}/dns-query?changed`
366 equal(Services.dns.currentTrrConfirmationState, CONFIRM_TRYING_OK);
367 await waitForConfirmationState(CONFIRM_OK, 1000);
368 equal(
369 await trrServer.requestCount("confirm.example.com", "NS"),
370 confirmationCount + 1
374 add_task(async function test_autodetected_uri() {
375 const defaultPrefBranch = Services.prefs.getDefaultBranch("");
376 let defaultURI = defaultPrefBranch.getCharPref(
377 "network.trr.default_provider_uri"
379 defaultPrefBranch.setCharPref(
380 "network.trr.default_provider_uri",
381 `https://foo.example.com:${trrServer.port()}/dns-query?changed`
383 // For setDetectedTrrURI to work we must pretend we are using the default.
384 Services.prefs.clearUserPref("network.trr.uri");
385 await waitForConfirmationState(CONFIRM_OK, 1000);
386 let confirmationCount = await trrServer.requestCount(
387 "confirm.example.com",
388 "NS"
390 Services.dns.setDetectedTrrURI(
391 `https://foo.example.com:${trrServer.port()}/dns-query?changed2`
393 equal(Services.dns.currentTrrConfirmationState, CONFIRM_TRYING_OK);
394 await waitForConfirmationState(CONFIRM_OK, 1000);
395 equal(
396 await trrServer.requestCount("confirm.example.com", "NS"),
397 confirmationCount + 1
400 // reset the default URI
401 defaultPrefBranch.setCharPref("network.trr.default_provider_uri", defaultURI);