Bug 1611651 - Add test for stale-while-revalidate loop bug a=jcristau
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 07 Mar 2020 16:59:16 +0000
changeset 580698 33cb6654c64b4dd3b106588589a12e4adb079823
parent 580697 13656732b5d46f99eb1050e65c330e01db575015
child 580699 f39beaef9ee199b3c118c5c7892fd3d92cc17860
push id12925
push usermalexandru@mozilla.com
push dateThu, 26 Mar 2020 11:24:04 +0000
treeherdermozilla-beta@acafefc48432 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcristau
bugs1611651
milestone75.0
Bug 1611651 - Add test for stale-while-revalidate loop bug a=jcristau Differential Revision: https://phabricator.services.mozilla.com/D64397
netwerk/test/unit/test_stale-while-revalidate_loop.js
netwerk/test/unit/xpcshell.ini
testing/xpcshell/moz-http2/moz-http2.js
copy from netwerk/test/unit/test_stale-while-revalidate_positive.js
copy to netwerk/test/unit/test_stale-while-revalidate_loop.js
--- a/netwerk/test/unit/test_stale-while-revalidate_positive.js
+++ b/netwerk/test/unit/test_stale-while-revalidate_loop.js
@@ -1,111 +1,46 @@
 /*
 
 Tests the Cache-control: stale-while-revalidate response directive.
 
-Purpose is to check we perform the background revalidation when the window is set
-and we hit it.
-
-* Make request #1.
-  - response is from the server and version=1
-  - max-age=1, stale-while-revalidate=9999
-* Switch version of the data on the server and prolong the max-age to not let req #3
-  do a bck reval at the end of the test (prevent leaks/shutdown races.)
-* Make request #2 in 2 seconds (entry should be expired by that time, but fall into
-  the reval window.)
-  - response is from the cache, version=1
-  - a new background request should be made for the data
-* Wait for "http-on-background-revalidation" notifying finish of the background reval.
-* Make request #3.
-  - response is from the cache, version=2
-* Done.
+Loads a HTTPS resource with the stale-while-revalidate and tries to load it
+twice.
 
 */
 
 "use strict";
 
-const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js");
-
-let max_age;
-let version;
-let generate_response = ver => `response version=${ver}`;
-
-function test_handler(metadata, response) {
-  const originalBody = generate_response(version);
-  response.setHeader("Content-Type", "text/html", false);
-  response.setHeader(
-    "Cache-control",
-    `max-age=${max_age}, stale-while-revalidate=9999`,
-    false
-  );
-  response.setStatusLine(metadata.httpVersion, 200, "OK");
-  response.bodyOutputStream.write(originalBody, originalBody.length);
-}
-
 function make_channel(url) {
   return NetUtil.newChannel({
     uri: url,
     loadUsingSystemPrincipal: true,
   }).QueryInterface(Ci.nsIHttpChannel);
 }
 
 async function get_response(channel, fromCache) {
   return new Promise(resolve => {
     channel.asyncOpen(
       new ChannelListener((request, buffer, ctx, isFromCache) => {
-        ok(fromCache == isFromCache, `got response from cache = ${fromCache}`);
         resolve(buffer);
       })
     );
   });
 }
 
-async function sleep(time) {
-  return new Promise(resolve => {
-    do_timeout(time * 1000, resolve);
-  });
-}
-
-async function stop_server(httpserver) {
-  return new Promise(resolve => {
-    httpserver.stop(resolve);
-  });
-}
-
-async function background_reval_promise() {
-  return new Promise(resolve => {
-    Services.obs.addObserver(resolve, "http-on-background-revalidation");
-  });
-}
-
 add_task(async function() {
-  let httpserver = new HttpServer();
-  httpserver.registerPathHandler("/testdir", test_handler);
-  httpserver.start(-1);
-  const PORT = httpserver.identity.primaryPort;
-  const URI = `http://localhost:${PORT}/testdir`;
+  do_get_profile();
+  let env = Cc["@mozilla.org/process/environment;1"].getService(
+    Ci.nsIEnvironment
+  );
+  const PORT = env.get("MOZHTTP2_PORT");
+  const URI = `https://localhost:${PORT}/stale-while-revalidate-loop-test`;
 
-  let response;
-
-  version = 1;
-  max_age = 1;
-  response = await get_response(make_channel(URI), false);
-  ok(response == generate_response(1), "got response ver 1");
-
-  await sleep(max_age + 1);
-
-  // must specifically wait for the internal channel to finish the reval to make
-  // the test race-free.
-  let reval_done = background_reval_promise();
+  let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
+    Ci.nsIX509CertDB
+  );
+  addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u");
 
-  version = 2;
-  max_age = 100;
-  response = await get_response(make_channel(URI), true);
-  ok(response == generate_response(1), "got response ver 1");
-
-  await reval_done;
-
-  response = await get_response(make_channel(URI), true);
-  ok(response == generate_response(2), "got response ver 2");
-
-  await stop_server(httpserver);
+  let response = await get_response(make_channel(URI), false);
+  ok(response == "1", "got response ver 1");
+  response = await get_response(make_channel(URI), false);
+  ok(response == "1", "got response ver 1");
 });
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -400,16 +400,17 @@ skip-if = tsan # Bug 1614708
 run-sequentially = node server exceptions dont replay well
 [test_esni_dns_fetch.js]
 [test_network_connectivity_service.js]
 [test_suspend_channel_on_authRetry.js]
 [test_suspend_channel_on_examine_merged_response.js]
 [test_bug1527293.js]
 [test_stale-while-revalidate_negative.js]
 [test_stale-while-revalidate_positive.js]
+[test_stale-while-revalidate_loop.js]
 [test_stale-while-revalidate_max-age-0.js]
 [test_http1-proxy.js]
 [test_http2-proxy.js]
 run-sequentially = one http2 node proxy is used for all tests, this test is using global session counter
 skip-if = os == "android"
 [test_head_request_no_response_body.js]
 [test_disabled_ftp.js]
 [test_cache_204_response.js]
--- a/testing/xpcshell/moz-http2/moz-http2.js
+++ b/testing/xpcshell/moz-http2/moz-http2.js
@@ -859,16 +859,27 @@ function handleRequest(req, res) {
     res.end("");
     return;
   } else if (u.pathname === "/.well-known/http-opportunistic") {
     res.setHeader("Cache-Control", "no-cache");
     res.setHeader("Content-Type", "application/json");
     res.writeHead(200, "OK");
     res.end('["http://' + req.headers.host + '"]');
     return;
+  } else if (u.pathname === "/stale-while-revalidate-loop-test") {
+    res.setHeader(
+      "Cache-Control",
+      "s-maxage=86400, stale-while-revalidate=86400, immutable"
+    );
+    res.setHeader("Content-Type", "text/plain; charset=utf-8");
+    res.setHeader("X-Content-Type-Options", "nosniff");
+    res.setHeader("Content-Length", "1");
+    res.writeHead(200, "OK");
+    res.end("1");
+    return;
   }
 
   // for PushService tests.
   else if (u.pathname === "/pushSubscriptionSuccess/subscribe") {
     res.setHeader(
       "Location",
       "https://localhost:" + serverPort + "/pushSubscriptionSuccesss"
     );