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