netwerk/test/unit/test_seer.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 var Cc = Components.classes;
michael@0 2 var Ci = Components.interfaces;
michael@0 3 var Cu = Components.utils;
michael@0 4 var Cr = Components.results;
michael@0 5
michael@0 6 Cu.import("resource://gre/modules/Services.jsm");
michael@0 7 Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 8
michael@0 9 var seer = null;
michael@0 10 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
michael@0 11 var profile = null;
michael@0 12
michael@0 13 function extract_origin(uri) {
michael@0 14 var o = uri.scheme + "://" + uri.asciiHost;
michael@0 15 if (uri.port !== -1) {
michael@0 16 o = o + ":" + uri.port;
michael@0 17 }
michael@0 18 return o;
michael@0 19 }
michael@0 20
michael@0 21 var LoadContext = function _loadContext() {
michael@0 22 };
michael@0 23
michael@0 24 LoadContext.prototype = {
michael@0 25 usePrivateBrowsing: false,
michael@0 26
michael@0 27 getInterface: function loadContext_getInterface(iid) {
michael@0 28 return this.QueryInterface(iid);
michael@0 29 },
michael@0 30
michael@0 31 QueryInterface: function loadContext_QueryInterface(iid) {
michael@0 32 if (iid.equals(Ci.nsINetworkSeerVerifier) ||
michael@0 33 iid.equals(Ci.nsILoadContext)) {
michael@0 34 return this;
michael@0 35 }
michael@0 36
michael@0 37 throw Cr.NS_ERROR_NO_INTERFACE;
michael@0 38 }
michael@0 39 };
michael@0 40
michael@0 41 var load_context = new LoadContext();
michael@0 42
michael@0 43 var Verifier = function _verifier(testing, expected_preconnects, expected_preresolves) {
michael@0 44 this.verifying = testing;
michael@0 45 this.expected_preconnects = expected_preconnects;
michael@0 46 this.expected_preresolves = expected_preresolves;
michael@0 47 };
michael@0 48
michael@0 49 Verifier.prototype = {
michael@0 50 verifying: null,
michael@0 51 expected_preconnects: null,
michael@0 52 expected_preresolves: null,
michael@0 53
michael@0 54 getInterface: function verifier_getInterface(iid) {
michael@0 55 return this.QueryInterface(iid);
michael@0 56 },
michael@0 57
michael@0 58 QueryInterface: function verifier_QueryInterface(iid) {
michael@0 59 if (iid.equals(Ci.nsINetworkSeerVerifier) ||
michael@0 60 iid.equals(Ci.nsISupports)) {
michael@0 61 return this;
michael@0 62 }
michael@0 63
michael@0 64 throw Cr.NS_ERROR_NO_INTERFACE;
michael@0 65 },
michael@0 66
michael@0 67 maybe_run_next_test: function verifier_maybe_run_next_test() {
michael@0 68 if (this.expected_preconnects.length === 0 &&
michael@0 69 this.expected_preresolves.length === 0) {
michael@0 70 do_check_true(true, "Well this is unexpected...");
michael@0 71 run_next_test();
michael@0 72 }
michael@0 73 },
michael@0 74
michael@0 75 onPredictPreconnect: function verifier_onPredictPreconnect(uri) {
michael@0 76 var origin = extract_origin(uri);
michael@0 77 var index = this.expected_preconnects.indexOf(origin);
michael@0 78 if (index == -1) {
michael@0 79 do_check_true(false, "Got preconnect for unexpected uri " + origin);
michael@0 80 } else {
michael@0 81 this.expected_preconnects.splice(index, 1);
michael@0 82 }
michael@0 83 this.maybe_run_next_test();
michael@0 84 },
michael@0 85
michael@0 86 onPredictDNS: function verifier_onPredictDNS(uri) {
michael@0 87 var origin = extract_origin(uri);
michael@0 88 var index = this.expected_preresolves.indexOf(origin);
michael@0 89 if (index == -1) {
michael@0 90 do_check_true(false, "Got preresolve for unexpected uri " + origin);
michael@0 91 } else {
michael@0 92 this.expected_preresolves.splice(index, 1);
michael@0 93 }
michael@0 94 this.maybe_run_next_test();
michael@0 95 }
michael@0 96 };
michael@0 97
michael@0 98 function reset_seer() {
michael@0 99 seer.reset();
michael@0 100 }
michael@0 101
michael@0 102 function newURI(s) {
michael@0 103 return ios.newURI(s, null, null);
michael@0 104 }
michael@0 105
michael@0 106 function test_link_hover() {
michael@0 107 reset_seer();
michael@0 108 var uri = newURI("http://localhost:4444/foo/bar");
michael@0 109 var referrer = newURI("http://localhost:4444/foo");
michael@0 110 var preconns = ["http://localhost:4444"];
michael@0 111
michael@0 112 var verifier = new Verifier("hover", preconns, []);
michael@0 113 seer.predict(uri, referrer, seer.PREDICT_LINK, load_context, verifier);
michael@0 114 }
michael@0 115
michael@0 116 function test_pageload() {
michael@0 117 reset_seer();
michael@0 118 var toplevel = "http://localhost:4444/index.html";
michael@0 119 var subresources = [
michael@0 120 "http://localhost:4444/style.css",
michael@0 121 "http://localhost:4443/jquery.js",
michael@0 122 "http://localhost:4444/image.png"
michael@0 123 ];
michael@0 124
michael@0 125 var tluri = newURI(toplevel);
michael@0 126 seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
michael@0 127 var preconns = [];
michael@0 128 for (var i = 0; i < subresources.length; i++) {
michael@0 129 var sruri = newURI(subresources[i]);
michael@0 130 seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
michael@0 131 preconns.push(extract_origin(sruri));
michael@0 132 }
michael@0 133
michael@0 134 var verifier = new Verifier("pageload", preconns, []);
michael@0 135 seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, verifier);
michael@0 136 }
michael@0 137
michael@0 138 function test_redirect() {
michael@0 139 reset_seer();
michael@0 140 var initial = "http://localhost:4443/redirect";
michael@0 141 var target = "http://localhost:4444/index.html";
michael@0 142 var subresources = [
michael@0 143 "http://localhost:4444/style.css",
michael@0 144 "http://localhost:4443/jquery.js",
michael@0 145 "http://localhost:4444/image.png"
michael@0 146 ];
michael@0 147
michael@0 148 var inituri = newURI(initial);
michael@0 149 var targeturi = newURI(target);
michael@0 150 seer.learn(inituri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
michael@0 151 seer.learn(targeturi, inituri, seer.LEARN_LOAD_REDIRECT, load_context);
michael@0 152 seer.learn(targeturi, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
michael@0 153
michael@0 154 var preconns = [];
michael@0 155 preconns.push(extract_origin(targeturi));
michael@0 156 for (var i = 0; i < subresources.length; i++) {
michael@0 157 var sruri = newURI(subresources[i]);
michael@0 158 seer.learn(sruri, targeturi, seer.LEARN_LOAD_SUBRESOURCE, load_context);
michael@0 159 preconns.push(extract_origin(sruri));
michael@0 160 }
michael@0 161
michael@0 162 var verifier = new Verifier("redirect", preconns, []);
michael@0 163 seer.predict(inituri, null, seer.PREDICT_LOAD, load_context, verifier);
michael@0 164 }
michael@0 165
michael@0 166 function test_startup() {
michael@0 167 reset_seer();
michael@0 168 var uris = [
michael@0 169 "http://localhost:4444/startup",
michael@0 170 "http://localhost:4443/startup"
michael@0 171 ];
michael@0 172 var preconns = [];
michael@0 173 for (var i = 0; i < uris.length; i++) {
michael@0 174 var uri = newURI(uris[i]);
michael@0 175 seer.learn(uri, null, seer.LEARN_STARTUP, load_context);
michael@0 176 preconns.push(extract_origin(uri));
michael@0 177 }
michael@0 178
michael@0 179 var verifier = new Verifier("startup", preconns, []);
michael@0 180 seer.predict(null, null, seer.PREDICT_STARTUP, load_context, verifier);
michael@0 181 }
michael@0 182
michael@0 183 // A class used to guarantee serialization of SQL queries so we can properly
michael@0 184 // update last hit times on subresources to ensure the seer tries to do DNS
michael@0 185 // preresolve on them instead of preconnecting
michael@0 186 var DnsContinueVerifier = function _dnsContinueVerifier(subresource, tluri, preresolves) {
michael@0 187 this.subresource = subresource;
michael@0 188 this.tluri = tluri;
michael@0 189 this.preresolves = preresolves;
michael@0 190 };
michael@0 191
michael@0 192 DnsContinueVerifier.prototype = {
michael@0 193 subresource: null,
michael@0 194 tluri: null,
michael@0 195 preresolves: null,
michael@0 196
michael@0 197 getInterface: function _dnsContinueVerifier_getInterface(iid) {
michael@0 198 return this.QueryInterface(iid);
michael@0 199 },
michael@0 200
michael@0 201 QueryInterface: function _dnsContinueVerifier_QueryInterface(iid) {
michael@0 202 if (iid.equals(Ci.nsISupports) ||
michael@0 203 iid.equals(Ci.nsINetworkSeerVerifier)) {
michael@0 204 return this;
michael@0 205 }
michael@0 206
michael@0 207 throw Cr.NS_ERROR_NO_INTERFACE;
michael@0 208 },
michael@0 209
michael@0 210 onPredictPreconnect: function _dnsContinueVerifier_onPredictPreconnect() {
michael@0 211 // This means that the seer has learned and done our "checkpoint" prediction
michael@0 212 // Now we can get on with the prediction we actually want to test
michael@0 213
michael@0 214 // tstamp is 10 days older than now - just over 1 week, which will ensure we
michael@0 215 // hit our cutoff for dns vs. preconnect. This is all in usec, hence the
michael@0 216 // x1000 on the Date object value.
michael@0 217 var tstamp = (new Date().valueOf() * 1000) - (10 * 86400 * 1000000);
michael@0 218
michael@0 219 seer.prepareForDnsTest(tstamp, this.subresource);
michael@0 220
michael@0 221 var verifier = new Verifier("dns", [], this.preresolves);
michael@0 222 seer.predict(this.tluri, null, seer.PREDICT_LOAD, load_context, verifier);
michael@0 223 },
michael@0 224
michael@0 225 onPredictDNS: function _dnsContinueVerifier_onPredictDNS() {
michael@0 226 do_check_true(false, "Shouldn't have gotten a preresolve prediction here!");
michael@0 227 }
michael@0 228 };
michael@0 229
michael@0 230 function test_dns() {
michael@0 231 reset_seer();
michael@0 232 var toplevel = "http://localhost:4444/index.html";
michael@0 233 var subresource = "http://localhost:4443/jquery.js";
michael@0 234
michael@0 235 var tluri = newURI(toplevel);
michael@0 236 seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
michael@0 237 var sruri = newURI(subresource);
michael@0 238 seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
michael@0 239
michael@0 240 var preresolves = [extract_origin(sruri)];
michael@0 241 var continue_verifier = new DnsContinueVerifier(subresource, tluri, preresolves);
michael@0 242 // Fire off a prediction that will do preconnects so we know when the seer
michael@0 243 // thread has gotten to the point where we can update the database manually
michael@0 244 seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, continue_verifier);
michael@0 245 }
michael@0 246
michael@0 247 function test_origin() {
michael@0 248 reset_seer();
michael@0 249 var toplevel = "http://localhost:4444/index.html";
michael@0 250 var subresources = [
michael@0 251 "http://localhost:4444/style.css",
michael@0 252 "http://localhost:4443/jquery.js",
michael@0 253 "http://localhost:4444/image.png"
michael@0 254 ];
michael@0 255
michael@0 256 var tluri = newURI(toplevel);
michael@0 257 seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
michael@0 258 var preconns = [];
michael@0 259 for (var i = 0; i < subresources.length; i++) {
michael@0 260 var sruri = newURI(subresources[i]);
michael@0 261 seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
michael@0 262 var origin = extract_origin(sruri);
michael@0 263 if (preconns.indexOf(origin) === -1) {
michael@0 264 preconns.push(origin);
michael@0 265 }
michael@0 266 }
michael@0 267
michael@0 268 var loaduri = newURI("http://localhost:4444/anotherpage.html");
michael@0 269 var verifier = new Verifier("origin", preconns, []);
michael@0 270 seer.predict(loaduri, null, seer.PREDICT_LOAD, load_context, verifier);
michael@0 271 }
michael@0 272
michael@0 273 var tests = [
michael@0 274 test_link_hover,
michael@0 275 test_pageload,
michael@0 276 test_redirect,
michael@0 277 test_startup,
michael@0 278 test_dns,
michael@0 279 test_origin
michael@0 280 ];
michael@0 281
michael@0 282 function run_test() {
michael@0 283 tests.forEach(add_test);
michael@0 284 profile = do_get_profile();
michael@0 285 seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
michael@0 286 do_register_cleanup(reset_seer);
michael@0 287 run_next_test();
michael@0 288 }

mercurial