test_rcwn_always_cache_new_content.js (3375B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ 3 */ 4 5 "use strict"; 6 7 const { HttpServer } = ChromeUtils.importESModule( 8 "resource://testing-common/httpd.sys.mjs" 9 ); 10 11 var httpserver = new HttpServer(); 12 httpserver.start(-1); 13 const PORT = httpserver.identity.primaryPort; 14 15 function make_channel(url) { 16 return NetUtil.newChannel({ 17 uri: url, 18 loadUsingSystemPrincipal: true, 19 }).QueryInterface(Ci.nsIHttpChannel); 20 } 21 22 let gFirstResponseBody = "first version"; 23 let gSecondResponseBody = "second version"; 24 let gRequestCounter = 0; 25 26 function test_handler(metadata, response) { 27 response.setHeader("Content-Type", "text/plain"); 28 response.setHeader("Cache-Control", "max-age=3600"); 29 response.setHeader("ETag", "test-etag1"); 30 31 switch (gRequestCounter) { 32 case 0: 33 response.bodyOutputStream.write( 34 gFirstResponseBody, 35 gFirstResponseBody.length 36 ); 37 break; 38 case 1: 39 response.bodyOutputStream.write( 40 gSecondResponseBody, 41 gSecondResponseBody.length 42 ); 43 break; 44 default: 45 do_throw("Unexpected request"); 46 } 47 response.setStatusLine(metadata.httpVersion, 200, "OK"); 48 } 49 50 function checkContent(request, buffer, context, isFromCache) { 51 let isRacing = request.QueryInterface(Ci.nsICacheInfoChannel).isRacing(); 52 switch (gRequestCounter) { 53 case 0: 54 Assert.equal(buffer, gFirstResponseBody); 55 Assert.ok(!isFromCache); 56 Assert.ok(!isRacing); 57 break; 58 case 1: 59 Assert.equal(buffer, gSecondResponseBody); 60 Assert.ok(!isFromCache); 61 Assert.ok(isRacing); 62 break; 63 case 2: 64 Assert.equal(buffer, gSecondResponseBody); 65 Assert.ok(isFromCache); 66 Assert.ok(!isRacing); 67 break; 68 default: 69 do_throw("Unexpected request"); 70 } 71 72 gRequestCounter++; 73 executeSoon(() => { 74 testGenerator.next(); 75 }); 76 } 77 78 function run_test() { 79 do_get_profile(); 80 // In this test, we race the requests manually using |TriggerNetwork|, 81 // therefore we should disable racing in the HttpChannel first. 82 Services.prefs.setBoolPref("network.http.rcwn.enabled", false); 83 httpserver.registerPathHandler("/rcwn", test_handler); 84 testGenerator.next(); 85 do_test_pending(); 86 } 87 88 let testGenerator = testSteps(); 89 function* testSteps() { 90 // Store first version of the content in the cache. 91 let channel = make_channel("http://localhost:" + PORT + "/rcwn"); 92 channel.asyncOpen(new ChannelListener(checkContent, null)); 93 yield undefined; 94 equal(gRequestCounter, 1); 95 96 // Simulate the network victory by setting high delay for the cache fetch and 97 // triggering the network. 98 channel = make_channel("http://localhost:" + PORT + "/rcwn"); 99 channel 100 .QueryInterface(Ci.nsIRaceCacheWithNetwork) 101 .test_delayCacheEntryOpeningBy(100000); 102 // Trigger network after 50 ms. 103 channel.QueryInterface(Ci.nsIRaceCacheWithNetwork).test_triggerNetwork(50); 104 channel.asyncOpen(new ChannelListener(checkContent, null)); 105 yield undefined; 106 equal(gRequestCounter, 2); 107 108 // Simulate navigation back by specifying VALIDATE_NEVER flag. 109 channel = make_channel("http://localhost:" + PORT + "/rcwn"); 110 channel.loadFlags = Ci.nsIRequest.VALIDATE_NEVER; 111 channel.asyncOpen(new ChannelListener(checkContent, null)); 112 yield undefined; 113 equal(gRequestCounter, 3); 114 115 httpserver.stop(do_test_finished); 116 }