Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: tools/page_cycler/webpagereplay/extension/background.js

Issue 9956045: Add Web Page Replay test to page cycler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Implement review suggestions. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // start.js sends a "start" message to set this.
6 window.benchmarkConfiguration = {};
7
8 // The callback (e.g. report writer) is set via AddBenchmarckCallback.
9 window.benchmarkCallback;
10
11 // Url to load before loading target page.
12 var kWaitUrl = "http://wprwprwpr/web-page-replay-generate-200";
13
14 // Constant StatCounter Names
15 var kTcpReadBytes = "tcp.read_bytes";
16 var kTcpWriteBytes = "tcp.write_bytes";
17 var kRequestCount = "HttpNetworkTransaction.Count";
18 var kConnectCount = "tcp.connect";
19
20 function CHECK(expr, comment) {
21 if (!expr) {
22 console.log(comment);
23 alert(comment);
24 }
25 }
26
27 function Result() {
28 var me_ = this;
29 this.url = "";
30 this.paint_time = 0;
tonyg 2012/04/17 11:04:45 This is actually the time of the first paint event
slamm_google 2012/04/17 20:47:16 I am so used to staring at Python code. Thanks for
31 this.read_bytes_kb = 0;
32 this.write_bytes_kb = 0;
33 this.num_requests = 0;
34 this.num_connects = 0;
35 this.timing = {}; // window.performance.timing
36 this.getTotalTime = function() {
37 var totalTime = 0
38 if (me_.timing.navigationStart && me_.timing.loadEventEnd) {
39 totalTime = me_.timing.loadEventEnd - me_.timing.navigationStart;
40 }
41 return Math.max(0, totalTime);
tonyg 2012/04/17 11:04:45 Should we actually add a: CHECK(totalTime >= 0)
slamm_google 2012/04/17 20:47:16 Good suggestion. Done.
42 }
43 }
44
45 // Collect all the results for a session (i.e. different pages).
46 function ResultsCollection() {
47 var results_ = [];
48 var pages_ = [];
49 var pageResults_ = {};
50
51 this.addResult = function(result) {
52 results_.push(result);
53 var url = result.url;
54 if (!(url in pageResults_)) {
55 pages_.push(url);
56 pageResults_[url] = [];
57 }
58 pageResults_[url].push(result);
59 }
60
61 this.getPages = function() {
62 return pages_;
63 }
64
65 this.getResults = function() {
66 return results_;
67 }
68
69 this.getTotalTimes = function() {
70 return results_.map(function (t) { return t.getTotalTime(); });
71 }
72 }
73
74 // Load a url in the default tab and record the time.
75 function PageLoader(url, resultReadyCallback) {
76 var me_ = this;
77 var url_ = url;
78 var resultReadyCallback_ = resultReadyCallback;
79
80 // If it record mode, wait a little longer for lazy loaded resources.
81 var postLoadGraceMs_ = window.isRecordMode ? 5000 : 0;
82 var loadInterval_ = window.loadInterval;
83 var checkInterval_ = window.checkInterval;
84 var timeout_ = window.timeout;
85 var maxLoadChecks_ = window.maxLoadChecks;
86
87 var preloadFunc_;
88 var timeoutId_;
89 var isFinished_;
90 var result_;
91
92 var initialReadBytes_;
93 var initialWriteBytes_;
94 var initialRequestCount_;
95 var initialConnectCount_;
96
97 this.result = function() { return result_; };
98
99 this.run = function() {
100 timeoutId_ = null;
101 isFinished_ = false;
102 result_ = null;
103 initialReadBytes_ = chrome.benchmarking.counter(kTcpReadBytes);
104 initialWriteBytes_ = chrome.benchmarking.counter(kTcpWriteBytes);
105 initialRequestCount_ = chrome.benchmarking.counter(kRequestCount);
106 initialConnectCount_ = chrome.benchmarking.counter(kConnectCount);
107
108 if (me_.preloadFunc_) {
109 me_.preloadFunc_(me_.load_);
110 } else {
111 me_.load_();
112 }
113 };
114
115 this.setClearAll = function() {
116 me_.preloadFunc_ = me_.clearAll_;
117 };
118
119 this.setClearConnections = function() {
120 me_.preloadFunc_ = me_.clearConnections_;
121 };
122
123 this.clearAll_ = function(callback) {
124 chrome.tabs.getSelected(null, function(tab) {
125 chrome.tabs.update(tab.id, {"url": kWaitUrl}, function() {
126 chrome.benchmarking.clearHostResolverCache();
127 chrome.benchmarking.clearPredictorCache();
128 chrome.benchmarking.closeConnections();
129 var dataToRemove = {
130 "appcache": true,
131 "cache": true,
132 "cookies": true,
133 "downloads": true,
134 "fileSystems": true,
135 "formData": true,
136 "history": true,
137 "indexedDB": true,
138 "localStorage": true,
139 "passwords": true,
140 "pluginData": true,
141 "webSQL": true
142 };
143 // Add any items new to the API.
144 for (var prop in chrome.browsingData) {
145 var dataName = prop.replace("remove", "");
146 if (dataName && dataName != prop) {
147 dataName = dataName.charAt(0).toLowerCase() +
148 dataName.substr(1);
149 if (!dataToRemove.hasOwnProperty(dataName)) {
150 console.log("New browsingData API item: " + dataName);
151 dataToRemove[dataName] = true;
152 }
153 }
154 }
155 chrome.browsingData.remove({}, dataToRemove, callback);
156 });
157 });
158 };
159
160 this.clearConnections_ = function(callback) {
161 chrome.benchmarking.closeConnections();
162 callback();
163 };
164
165 this.load_ = function() {
166 console.log("LOAD started: " + url_);
167 setTimeout(function() {
168 chrome.extension.onRequest.addListener(me_.finishLoad_);
169 timeoutId_ = setTimeout(function() {
170 me_.finishLoad_({"loadTimes": null, "timing": null});
171 }, timeout_);
172 chrome.tabs.getSelected(null, function(tab) {
173 chrome.tabs.update(tab.id, {"url": url_});
174 });
175 }, loadInterval_);
176 };
177
178 this.finishLoad_ = function(msg) {
179 if (!isFinished_) {
180 isFinished_ = true;
181 clearTimeout(timeoutId_);
182 chrome.extension.onRequest.removeListener(me_.finishLoad_);
183 me_.saveResult_(msg.loadTimes, msg.timing);
184 }
185 };
186
187 this.saveResult_ = function(loadTimes, timing) {
188 result_ = new Result()
189 result_.url = url_;
190 if (!loadTimes || !timing) {
191 console.log("LOAD INCOMPLETE: " + url_);
192 } else {
193 console.log("LOAD complete: " + url_);
194 result_.timing = timing;
195 var baseTime = timing.navigationStart;
196 CHECK(baseTime);
197 result_.paint_time = Math.max(0,
198 Math.round((1000.0 * loadTimes.firstPaintTime) - baseTime));
199 }
200 result_.read_bytes_kb = (chrome.benchmarking.counter(kTcpReadBytes) -
201 initialReadBytes_) / 1024;
202 result_.write_bytes_kb = (chrome.benchmarking.counter(kTcpWriteBytes) -
203 initialWriteBytes_) / 1024;
204 result_.num_requests = (chrome.benchmarking.counter(kRequestCount) -
205 initialRequestCount_);
206 result_.num_connects = (chrome.benchmarking.counter(kConnectCount) -
207 initialConnectCount_);
208 setTimeout(function() { resultReadyCallback_(me_); }, postLoadGraceMs_);
209 };
210 }
211
212 // Load page sets and prepare performance results.
213 function SessionLoader(resultsReadyCallback) {
214 var me_ = this;
215 var resultsReadyCallback_ = resultsReadyCallback;
216 var pageSets_ = benchmarkConfiguration.pageSets;
217 var iterations_ = window.iterations;
218 var retries_ = window.retries;
219
220 var pageLoaders_ = [];
221 var resultsCollection_ = new ResultsCollection();
222 var loaderIndex_ = 0;
223 var retryIndex_ = 0;
224 var iterationIndex_ = 0;
225
226 this.run = function() {
227 me_.createLoaders_();
228 me_.loadPage_();
229 }
230
231 this.getResultsCollection = function() {
232 return resultsCollection_;
233 }
234
235 this.createLoaders_ = function() {
236 // Each url becomes one benchmark.
237 for (var i = 0; i < pageSets_.length; i++) {
238 for (var j = 0; j < pageSets_[i].length; j++) {
239 // Remove extra space at the beginning or end of a url.
240 var url = pageSets_[i][j].trim();
241 // Alert about and ignore blank page which does not get loaded.
242 if (url == "about:blank") {
243 alert("blank page loaded!");
244 } else if (!url.match(/https?:\/\//)) {
245 // Alert about url that is not in scheme http:// or https://.
246 alert("Skipping url without http:// or https://: " + url);
247 } else {
248 var loader = new PageLoader(url, me_.handleResult_)
249 if (j == 0) {
250 // Clear all browser data for the first page in a sub list.
251 loader.setClearAll();
252 } else {
253 // Otherwise, only clear the connections.
254 loader.setClearConnections();
255 }
256 pageLoaders_.push(loader);
257 }
258 }
259 }
260 }
261
262 this.loadPage_ = function() {
263 console.log("LOAD url " + (loaderIndex_ + 1) + " of " +
264 pageLoaders_.length +
265 ", iteration " + (iterationIndex_ + 1) + " of " +
266 iterations_);
267 pageLoaders_[loaderIndex_].run();
268 }
269
270 this.handleResult_ = function(loader) {
271 var result = loader.result();
272 resultsCollection_.addResult(result);
273 var totalTime = result.getTotalTime();
274 if (!totalTime && retryIndex_ < retries_) {
275 retryIndex_++;
276 console.log("LOAD retry, " + retryIndex_);
277 } else {
278 retryIndex_ = 0;
279 console.log("RESULTS url " + (loaderIndex_ + 1) + " of " +
280 pageLoaders_.length +
281 ", iteration " + (iterationIndex_ + 1) + " of " +
282 iterations_ + ": " + totalTime);
283 loaderIndex_++;
284 if (loaderIndex_ >= pageLoaders_.length) {
285 iterationIndex_++;
286 if (iterationIndex_ < iterations_) {
287 loaderIndex_ = 0;
288 } else {
289 resultsReadyCallback_(me_);
290 return;
291 }
292 }
293 }
294 me_.loadPage_();
295 }
296 }
297
298 function AddBenchmarkCallback(callback) {
299 window.benchmarkCallback = callback;
300 }
301
302 function Run() {
303 window.checkInterval = 500;
304 window.loadInterval = 1000;
305 window.timeout = 20000; // max ms before killing page.
306 window.retries = 0;
307 window.isRecordMode = benchmarkConfiguration.isRecordMode;
308 if (window.isRecordMode) {
309 window.iterations = 1;
310 window.timeout = 40000;
311 window.retries = 2;
312 } else {
313 window.iterations = benchmarkConfiguration["iterations"] || 3;
314 }
315 var sessionLoader = new SessionLoader(benchmarkCallback);
316 console.log("pageSets: " + JSON.stringify(benchmarkConfiguration.pageSets));
317 sessionLoader.run();
318 }
319
320 chrome.extension.onConnect.addListener(function(port) {
321 port.onMessage.addListener(function(data) {
322 if (data.message == "start") {
323 window.benchmarkConfiguration = data.benchmark;
324 Run()
325 }
326 });
327 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698