netwerk/test/unit/test_seer.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/netwerk/test/unit/test_seer.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,288 @@
     1.4 +var Cc = Components.classes;
     1.5 +var Ci = Components.interfaces;
     1.6 +var Cu = Components.utils;
     1.7 +var Cr = Components.results;
     1.8 +
     1.9 +Cu.import("resource://gre/modules/Services.jsm");
    1.10 +Cu.import("resource://gre/modules/FileUtils.jsm");
    1.11 +
    1.12 +var seer = null;
    1.13 +var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
    1.14 +var profile = null;
    1.15 +
    1.16 +function extract_origin(uri) {
    1.17 +  var o = uri.scheme + "://" + uri.asciiHost;
    1.18 +  if (uri.port !== -1) {
    1.19 +    o = o + ":" + uri.port;
    1.20 +  }
    1.21 +  return o;
    1.22 +}
    1.23 +
    1.24 +var LoadContext = function _loadContext() {
    1.25 +};
    1.26 +
    1.27 +LoadContext.prototype = {
    1.28 +  usePrivateBrowsing: false,
    1.29 +
    1.30 +  getInterface: function loadContext_getInterface(iid) {
    1.31 +    return this.QueryInterface(iid);
    1.32 +  },
    1.33 +
    1.34 +  QueryInterface: function loadContext_QueryInterface(iid) {
    1.35 +    if (iid.equals(Ci.nsINetworkSeerVerifier) ||
    1.36 +        iid.equals(Ci.nsILoadContext)) {
    1.37 +      return this;
    1.38 +    }
    1.39 +
    1.40 +    throw Cr.NS_ERROR_NO_INTERFACE;
    1.41 +  }
    1.42 +};
    1.43 +
    1.44 +var load_context = new LoadContext();
    1.45 +
    1.46 +var Verifier = function _verifier(testing, expected_preconnects, expected_preresolves) {
    1.47 +  this.verifying = testing;
    1.48 +  this.expected_preconnects = expected_preconnects;
    1.49 +  this.expected_preresolves = expected_preresolves;
    1.50 +};
    1.51 +
    1.52 +Verifier.prototype = {
    1.53 +  verifying: null,
    1.54 +  expected_preconnects: null,
    1.55 +  expected_preresolves: null,
    1.56 +
    1.57 +  getInterface: function verifier_getInterface(iid) {
    1.58 +    return this.QueryInterface(iid);
    1.59 +  },
    1.60 +
    1.61 +  QueryInterface: function verifier_QueryInterface(iid) {
    1.62 +    if (iid.equals(Ci.nsINetworkSeerVerifier) ||
    1.63 +        iid.equals(Ci.nsISupports)) {
    1.64 +      return this;
    1.65 +    }
    1.66 +
    1.67 +    throw Cr.NS_ERROR_NO_INTERFACE;
    1.68 +  },
    1.69 +
    1.70 +  maybe_run_next_test: function verifier_maybe_run_next_test() {
    1.71 +    if (this.expected_preconnects.length === 0 &&
    1.72 +        this.expected_preresolves.length === 0) {
    1.73 +      do_check_true(true, "Well this is unexpected...");
    1.74 +      run_next_test();
    1.75 +    }
    1.76 +  },
    1.77 +
    1.78 +  onPredictPreconnect: function verifier_onPredictPreconnect(uri) {
    1.79 +    var origin = extract_origin(uri);
    1.80 +    var index = this.expected_preconnects.indexOf(origin);
    1.81 +    if (index == -1) {
    1.82 +      do_check_true(false, "Got preconnect for unexpected uri " + origin);
    1.83 +    } else {
    1.84 +      this.expected_preconnects.splice(index, 1);
    1.85 +    }
    1.86 +    this.maybe_run_next_test();
    1.87 +  },
    1.88 +
    1.89 +  onPredictDNS: function verifier_onPredictDNS(uri) {
    1.90 +    var origin = extract_origin(uri);
    1.91 +    var index = this.expected_preresolves.indexOf(origin);
    1.92 +    if (index == -1) {
    1.93 +      do_check_true(false, "Got preresolve for unexpected uri " + origin);
    1.94 +    } else {
    1.95 +      this.expected_preresolves.splice(index, 1);
    1.96 +    }
    1.97 +    this.maybe_run_next_test();
    1.98 +  }
    1.99 +};
   1.100 +
   1.101 +function reset_seer() {
   1.102 +  seer.reset();
   1.103 +}
   1.104 +
   1.105 +function newURI(s) {
   1.106 +  return ios.newURI(s, null, null);
   1.107 +}
   1.108 +
   1.109 +function test_link_hover() {
   1.110 +  reset_seer();
   1.111 +  var uri = newURI("http://localhost:4444/foo/bar");
   1.112 +  var referrer = newURI("http://localhost:4444/foo");
   1.113 +  var preconns = ["http://localhost:4444"];
   1.114 +
   1.115 +  var verifier = new Verifier("hover", preconns, []);
   1.116 +  seer.predict(uri, referrer, seer.PREDICT_LINK, load_context, verifier);
   1.117 +}
   1.118 +
   1.119 +function test_pageload() {
   1.120 +  reset_seer();
   1.121 +  var toplevel = "http://localhost:4444/index.html";
   1.122 +  var subresources = [
   1.123 +    "http://localhost:4444/style.css",
   1.124 +    "http://localhost:4443/jquery.js",
   1.125 +    "http://localhost:4444/image.png"
   1.126 +  ];
   1.127 +
   1.128 +  var tluri = newURI(toplevel);
   1.129 +  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
   1.130 +  var preconns = [];
   1.131 +  for (var i = 0; i < subresources.length; i++) {
   1.132 +    var sruri = newURI(subresources[i]);
   1.133 +    seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
   1.134 +    preconns.push(extract_origin(sruri));
   1.135 +  }
   1.136 +
   1.137 +  var verifier = new Verifier("pageload", preconns, []);
   1.138 +  seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, verifier);
   1.139 +}
   1.140 +
   1.141 +function test_redirect() {
   1.142 +  reset_seer();
   1.143 +  var initial = "http://localhost:4443/redirect";
   1.144 +  var target = "http://localhost:4444/index.html";
   1.145 +  var subresources = [
   1.146 +    "http://localhost:4444/style.css",
   1.147 +    "http://localhost:4443/jquery.js",
   1.148 +    "http://localhost:4444/image.png"
   1.149 +  ];
   1.150 +
   1.151 +  var inituri = newURI(initial);
   1.152 +  var targeturi = newURI(target);
   1.153 +  seer.learn(inituri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
   1.154 +  seer.learn(targeturi, inituri, seer.LEARN_LOAD_REDIRECT, load_context);
   1.155 +  seer.learn(targeturi, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
   1.156 +
   1.157 +  var preconns = [];
   1.158 +  preconns.push(extract_origin(targeturi));
   1.159 +  for (var i = 0; i < subresources.length; i++) {
   1.160 +    var sruri = newURI(subresources[i]);
   1.161 +    seer.learn(sruri, targeturi, seer.LEARN_LOAD_SUBRESOURCE, load_context);
   1.162 +    preconns.push(extract_origin(sruri));
   1.163 +  }
   1.164 +
   1.165 +  var verifier = new Verifier("redirect", preconns, []);
   1.166 +  seer.predict(inituri, null, seer.PREDICT_LOAD, load_context, verifier);
   1.167 +}
   1.168 +
   1.169 +function test_startup() {
   1.170 +  reset_seer();
   1.171 +  var uris = [
   1.172 +    "http://localhost:4444/startup",
   1.173 +    "http://localhost:4443/startup"
   1.174 +  ];
   1.175 +  var preconns = [];
   1.176 +  for (var i = 0; i < uris.length; i++) {
   1.177 +    var uri = newURI(uris[i]);
   1.178 +    seer.learn(uri, null, seer.LEARN_STARTUP, load_context);
   1.179 +    preconns.push(extract_origin(uri));
   1.180 +  }
   1.181 +
   1.182 +  var verifier = new Verifier("startup", preconns, []);
   1.183 +  seer.predict(null, null, seer.PREDICT_STARTUP, load_context, verifier);
   1.184 +}
   1.185 +
   1.186 +// A class used to guarantee serialization of SQL queries so we can properly
   1.187 +// update last hit times on subresources to ensure the seer tries to do DNS
   1.188 +// preresolve on them instead of preconnecting
   1.189 +var DnsContinueVerifier = function _dnsContinueVerifier(subresource, tluri, preresolves) {
   1.190 +  this.subresource = subresource;
   1.191 +  this.tluri = tluri;
   1.192 +  this.preresolves = preresolves;
   1.193 +};
   1.194 +
   1.195 +DnsContinueVerifier.prototype = {
   1.196 +  subresource: null,
   1.197 +  tluri: null,
   1.198 +  preresolves: null,
   1.199 +
   1.200 +  getInterface: function _dnsContinueVerifier_getInterface(iid) {
   1.201 +    return this.QueryInterface(iid);
   1.202 +  },
   1.203 +
   1.204 +  QueryInterface: function _dnsContinueVerifier_QueryInterface(iid) {
   1.205 +    if (iid.equals(Ci.nsISupports) ||
   1.206 +        iid.equals(Ci.nsINetworkSeerVerifier)) {
   1.207 +      return this;
   1.208 +    }
   1.209 +
   1.210 +    throw Cr.NS_ERROR_NO_INTERFACE;
   1.211 +  },
   1.212 +
   1.213 +  onPredictPreconnect: function _dnsContinueVerifier_onPredictPreconnect() {
   1.214 +    // This means that the seer has learned and done our "checkpoint" prediction
   1.215 +    // Now we can get on with the prediction we actually want to test
   1.216 +
   1.217 +    // tstamp is 10 days older than now - just over 1 week, which will ensure we
   1.218 +    // hit our cutoff for dns vs. preconnect. This is all in usec, hence the
   1.219 +    // x1000 on the Date object value.
   1.220 +    var tstamp = (new Date().valueOf() * 1000) - (10 * 86400 * 1000000);
   1.221 +
   1.222 +    seer.prepareForDnsTest(tstamp, this.subresource);
   1.223 +
   1.224 +    var verifier = new Verifier("dns", [], this.preresolves);
   1.225 +    seer.predict(this.tluri, null, seer.PREDICT_LOAD, load_context, verifier);
   1.226 +  },
   1.227 +
   1.228 +  onPredictDNS: function _dnsContinueVerifier_onPredictDNS() {
   1.229 +    do_check_true(false, "Shouldn't have gotten a preresolve prediction here!");
   1.230 +  }
   1.231 +};
   1.232 +
   1.233 +function test_dns() {
   1.234 +  reset_seer();
   1.235 +  var toplevel = "http://localhost:4444/index.html";
   1.236 +  var subresource = "http://localhost:4443/jquery.js";
   1.237 +
   1.238 +  var tluri = newURI(toplevel);
   1.239 +  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
   1.240 +  var sruri = newURI(subresource);
   1.241 +  seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
   1.242 +
   1.243 +  var preresolves = [extract_origin(sruri)];
   1.244 +  var continue_verifier = new DnsContinueVerifier(subresource, tluri, preresolves);
   1.245 +  // Fire off a prediction that will do preconnects so we know when the seer
   1.246 +  // thread has gotten to the point where we can update the database manually
   1.247 +  seer.predict(tluri, null, seer.PREDICT_LOAD, load_context, continue_verifier);
   1.248 +}
   1.249 +
   1.250 +function test_origin() {
   1.251 +  reset_seer();
   1.252 +  var toplevel = "http://localhost:4444/index.html";
   1.253 +  var subresources = [
   1.254 +    "http://localhost:4444/style.css",
   1.255 +    "http://localhost:4443/jquery.js",
   1.256 +    "http://localhost:4444/image.png"
   1.257 +  ];
   1.258 +
   1.259 +  var tluri = newURI(toplevel);
   1.260 +  seer.learn(tluri, null, seer.LEARN_LOAD_TOPLEVEL, load_context);
   1.261 +  var preconns = [];
   1.262 +  for (var i = 0; i < subresources.length; i++) {
   1.263 +    var sruri = newURI(subresources[i]);
   1.264 +    seer.learn(sruri, tluri, seer.LEARN_LOAD_SUBRESOURCE, load_context);
   1.265 +    var origin = extract_origin(sruri);
   1.266 +    if (preconns.indexOf(origin) === -1) {
   1.267 +      preconns.push(origin);
   1.268 +    }
   1.269 +  }
   1.270 +
   1.271 +  var loaduri = newURI("http://localhost:4444/anotherpage.html");
   1.272 +  var verifier = new Verifier("origin", preconns, []);
   1.273 +  seer.predict(loaduri, null, seer.PREDICT_LOAD, load_context, verifier);
   1.274 +}
   1.275 +
   1.276 +var tests = [
   1.277 +  test_link_hover,
   1.278 +  test_pageload,
   1.279 +  test_redirect,
   1.280 +  test_startup,
   1.281 +  test_dns,
   1.282 +  test_origin
   1.283 +];
   1.284 +
   1.285 +function run_test() {
   1.286 +  tests.forEach(add_test);
   1.287 +  profile = do_get_profile();
   1.288 +  seer = Cc["@mozilla.org/network/seer;1"].getService(Ci.nsINetworkSeer);
   1.289 +  do_register_cleanup(reset_seer);
   1.290 +  run_next_test();
   1.291 +}

mercurial