Bug 1857386 [wpt PR 42383] - Update wpt metadata, a=testonly
[gecko.git] / netwerk / test / unit / test_stale-while-revalidate_max-age-0.js
blob01bb6639bc442e201970243f3c6150651cf8434c
1 /*
3 Tests the Cache-control: stale-while-revalidate response directive.
5 Purpose is to check we perform the background revalidation when max-age=0 but
6 the window is set and we hit it.
8 * Make request #1.
9   - response is from the server and version=1
10   - max-age=0, stale-while-revalidate=9999
11 * Switch version of the data on the server and prolong the max-age to not let req #3
12   do a bck reval at the end of the test (prevent leaks/shutdown races.)
13 * Make request #2 in 2 seconds (entry should be expired by that time, but fall into
14   the reval window.)
15   - response is from the cache, version=1
16   - a new background request should be made for the data
17 * Wait for "http-on-background-revalidation" notifying finish of the background reval.
18 * Make request #3.
19   - response is from the cache, version=2
20 * Done.
24 "use strict";
26 const { HttpServer } = ChromeUtils.importESModule(
27   "resource://testing-common/httpd.sys.mjs"
30 let max_age;
31 let version;
32 let generate_response = ver => `response version=${ver}`;
34 function test_handler(metadata, response) {
35   const originalBody = generate_response(version);
36   response.setHeader("Content-Type", "text/html", false);
37   response.setHeader(
38     "Cache-control",
39     `max-age=${max_age}, stale-while-revalidate=9999`,
40     false
41   );
42   response.setStatusLine(metadata.httpVersion, 200, "OK");
43   response.bodyOutputStream.write(originalBody, originalBody.length);
46 function make_channel(url) {
47   return NetUtil.newChannel({
48     uri: url,
49     loadUsingSystemPrincipal: true,
50   }).QueryInterface(Ci.nsIHttpChannel);
53 async function get_response(channel, fromCache) {
54   return new Promise(resolve => {
55     channel.asyncOpen(
56       new ChannelListener((request, buffer, ctx, isFromCache) => {
57         ok(fromCache == isFromCache, `got response from cache = ${fromCache}`);
58         resolve(buffer);
59       })
60     );
61   });
64 async function sleep(time) {
65   return new Promise(resolve => {
66     do_timeout(time * 1000, resolve);
67   });
70 async function stop_server(httpserver) {
71   return new Promise(resolve => {
72     httpserver.stop(resolve);
73   });
76 async function background_reval_promise() {
77   return new Promise(resolve => {
78     Services.obs.addObserver(resolve, "http-on-background-revalidation");
79   });
82 add_task(async function () {
83   let httpserver = new HttpServer();
84   httpserver.registerPathHandler("/testdir", test_handler);
85   httpserver.start(-1);
86   const PORT = httpserver.identity.primaryPort;
87   const URI = `http://localhost:${PORT}/testdir`;
89   let response;
91   version = 1;
92   max_age = 0;
93   response = await get_response(make_channel(URI), false);
94   ok(response == generate_response(1), "got response ver 1");
96   await sleep(2);
98   // must specifically wait for the internal channel to finish the reval to make
99   // the test race-free.
100   let reval_done = background_reval_promise();
102   version = 2;
103   max_age = 100;
104   response = await get_response(make_channel(URI), true);
105   ok(response == generate_response(1), "got response ver 1");
107   await reval_done;
109   response = await get_response(make_channel(URI), true);
110   ok(response == generate_response(2), "got response ver 2");
112   await stop_server(httpserver);