Backed out changeset b71c8c052463 (bug 1943846) for causing mass failures. CLOSED...
[gecko.git] / netwerk / test / unit / test_stale-while-revalidate_positive.js
blob45dc0d305a2ffc30edf69283ab6cc8a206702ff7
1 /*
3 Tests the Cache-control: stale-while-revalidate response directive.
5 Purpose is to check we perform the background revalidation when the window is set
6 and we hit it.
8 * Make request #1.
9 - response is from the server and version=1
10 - max-age=1, 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
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 Assert.equal(
58 fromCache,
59 isFromCache,
60 `got response from cache = ${fromCache}`
62 resolve(buffer);
65 });
68 async function sleep(time) {
69 return new Promise(resolve => {
70 do_timeout(time * 1000, resolve);
71 });
74 async function stop_server(httpserver) {
75 return new Promise(resolve => {
76 httpserver.stop(resolve);
77 });
80 async function background_reval_promise() {
81 return new Promise(resolve => {
82 Services.obs.addObserver(resolve, "http-on-background-revalidation");
83 });
86 add_task(async function () {
87 let httpserver = new HttpServer();
88 httpserver.registerPathHandler("/testdir", test_handler);
89 httpserver.start(-1);
90 const PORT = httpserver.identity.primaryPort;
91 const URI = `http://localhost:${PORT}/testdir`;
93 let response;
95 version = 1;
96 max_age = 1;
97 response = await get_response(make_channel(URI), false);
98 Assert.equal(response, generate_response(1), "got response ver 1");
100 await sleep(max_age + 1);
102 // must specifically wait for the internal channel to finish the reval to make
103 // the test race-free.
104 let reval_done = background_reval_promise();
106 version = 2;
107 max_age = 100;
108 response = await get_response(make_channel(URI), true);
109 Assert.equal(response, generate_response(1), "got response ver 1");
111 await reval_done;
113 response = await get_response(make_channel(URI), true);
114 Assert.equal(response, generate_response(2), "got response ver 2");
116 await stop_server(httpserver);