Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: chrome/content/tests/synchronizer.js

Issue 11144022: Add tests for the Notification module (Closed)
Left Patch Set: Created July 18, 2013, 12:23 p.m.
Right Patch Set: Test downloading (changes by Wladimir) Created July 18, 2013, 5:58 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Right: Side by side diff | Download
LEFTRIGHT
(no file at all)
1 (function() 1 (function()
2 { 2 {
3 let testRunner = null; 3 let testRunner = null;
4 let server = null; 4 let server = null;
5 let randomResult = 0.5; 5 let randomResult = 0.5;
6 6
7 const MILLIS_IN_SECOND = 1000;
8 const MILLIS_IN_MINUTE = 60 * MILLIS_IN_SECOND;
9 const MILLIS_IN_HOUR = 60 * MILLIS_IN_MINUTE;
10 const MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
11
12 module("Synchronizer", { 7 module("Synchronizer", {
13 QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakRef erence]),
14
15 setup: function() 8 setup: function()
16 { 9 {
17 testRunner = this; 10 testRunner = this;
18 11
19 prepareFilterComponents.call(this); 12 prepareFilterComponents.call(this);
20 preparePrefs.call(this); 13 preparePrefs.call(this);
21 14 setupVirtualTime.call(this, function(wrapTimer)
22 let SynchronizerGlobal = Cu.getGlobalForObject(Synchronizer); 15 {
23 let SynchronizerModule = getModuleGlobal("synchronizer"); 16 let SynchronizerModule = getModuleGlobal("synchronizer");
24 let DownloaderGlobal = Cu.getGlobalForObject(SynchronizerModule.downloader ); 17 SynchronizerModule.downloader._timer = wrapTimer(SynchronizerModule.down loader._timer);
18 }, "synchronizer", "downloader");
25 19
26 server = new nsHttpServer(); 20 server = new nsHttpServer();
27 server.start(1234); 21 server.start(1234);
28 22
29 let currentTime = 100000 * MILLIS_IN_HOUR;
30 let startTime = currentTime;
31 let scheduledTasks = [];
32
33 // Replace Date.now() function
34 this._origNow = SynchronizerGlobal.Date.now;
35 SynchronizerGlobal.Date.now = DownloaderGlobal.Date.now = function() curre ntTime;
36
37 // Replace Math.random() function 23 // Replace Math.random() function
24 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader") );
38 this._origRandom = DownloaderGlobal.Math.random; 25 this._origRandom = DownloaderGlobal.Math.random;
39 DownloaderGlobal.Math.random = function() randomResult; 26 DownloaderGlobal.Math.random = function() randomResult;
40 27 randomResult = 0.5;
Felix Dahlke 2013/07/19 14:30:41 As in notification.js - it looks like this is alwa
Wladimir Palant 2013/07/19 14:58:49 Not really, one of the tests changes it - and this
41 // Replace global timer variable
42 let timer = {__proto__: SynchronizerModule.downloader._timer, delay: 0.1 * MILLIS_IN_HOUR};
43 let callback = timer.callback;
44 timer.handler = function() { callback.notify(timer); };
45 timer.nextExecution = currentTime + timer.delay;
46 scheduledTasks.push(timer);
47 SynchronizerModule.downloader._timer.cancel();
48 SynchronizerModule.downloader._timer = timer;
49
50 // Register observer to track outstanding requests
51 this._outstandingRequests = 0;
52 Services.obs.addObserver(this, "http-on-modify-request", true);
53 Services.obs.addObserver(this, "http-on-examine-response", true);
54
55 this.runScheduledTasks = function(maxHours, initial, skip)
56 {
57 if (typeof maxHours != "number")
58 throw new Error("Numerical parameter expected");
59 if (typeof initial != "number")
60 initial = 0;
61 if (typeof skip != "number")
62 skip = 0;
63
64 startTime = currentTime;
65 if (initial >= 0)
66 {
67 this._runScheduledTasks(initial);
68 maxHours -= initial;
69 }
70 if (skip)
71 {
72 this._skipTasks(skip);
73 maxHours -= skip;
74 }
75 this._runScheduledTasks(maxHours);
76 }
77
78 this._runScheduledTasks = function(maxHours)
79 {
80 let endTime = currentTime + maxHours * MILLIS_IN_HOUR;
81 while (true)
82 {
83 let nextTask = null;
84 for each (let task in scheduledTasks)
85 {
86 if (!nextTask || nextTask.nextExecution > task.nextExecution)
87 nextTask = task;
88 }
89 if (!nextTask || nextTask.nextExecution > endTime)
90 break;
91
92 currentTime = nextTask.nextExecution;
93 nextTask.handler();
94
95 // Let all asynchronous actions finish
96 let thread = Services.tm.currentThread;
97 let loopStartTime = Date.now();
98
99 while (this._outstandingRequests > 0 || thread.hasPendingEvents())
100 {
101 thread.processNextEvent(true);
102
103 if (Date.now() - loopStartTime > 5000)
104 throw new Error("Synchronizer stuck downloading subscriptions");
105 }
106
107 if (nextTask.type == Components.interfaces.nsITimer.TYPE_ONE_SHOT)
108 scheduledTasks = scheduledTasks.filter(function(task) task != nextTa sk);
109 else
110 nextTask.nextExecution = currentTime + nextTask.delay;
111 }
112
113 currentTime = endTime;
114 }
115
116 this._skipTasks = function(hours)
117 {
118 let newTasks = [];
119 currentTime += hours * MILLIS_IN_HOUR;
120 for each (let task in scheduledTasks)
121 {
122 if (task.nextExecution >= currentTime)
123 newTasks.push(task);
124 else if (task.type != Components.interfaces.nsITimer.TYPE_ONE_SHOT)
125 {
126 task.nextExecution = currentTime;
127 newTasks.push(task);
128 }
129 }
130 scheduledTasks = newTasks;
131 }
132
133 this.getTimeOffset = function() (currentTime - startTime) / MILLIS_IN_HOUR ;
134
135 this.__defineGetter__("currentTime", function() currentTime);
136 },
137
138 observe: function(subject, topic, data)
139 {
140 let orig = this._outstandingRequests;
141 if (topic == "http-on-modify-request")
142 this._outstandingRequests++;
143 else if (topic == "http-on-examine-response")
144 this._outstandingRequests--;
145 }, 28 },
146 29
147 teardown: function() 30 teardown: function()
148 { 31 {
149 restoreFilterComponents.call(this); 32 restoreFilterComponents.call(this);
150 restorePrefs.call(this); 33 restorePrefs.call(this);
34 restoreVirtualTime.call(this);
151 35
152 stop(); 36 stop();
153 server.stop(function() 37 server.stop(function()
154 { 38 {
155 server = null; 39 server = null;
156 start(); 40 start();
157 }); 41 });
158 42
159 if (this._origNow)
160 {
161 let SynchronizerGlobal = Cu.getGlobalForObject(Synchronizer);
162 let SynchronizerModule = getModuleGlobal("synchronizer");
163 let DownloaderGlobal = Cu.getGlobalForObject(SynchronizerModule.download er);
164 SynchronizerGlobal.Date.now = DownloaderGlobal.Date.now = this._origNow;
165 delete this._origNow;
166 }
167
168 if (this._origRandom) 43 if (this._origRandom)
169 { 44 {
170 let SynchronizerModule = getModuleGlobal("synchronizer"); 45 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader "));
171 let DownloaderGlobal = Cu.getGlobalForObject(SynchronizerModule.download er);
172 DownloaderGlobal.Math.random = this._origRandom; 46 DownloaderGlobal.Math.random = this._origRandom;
173 delete this._origRandom; 47 delete this._origRandom;
174 } 48 }
175 49
176 Synchronizer.init(); 50 Synchronizer.init();
177 } 51 }
178 }); 52 });
179 53
180 function resetSubscription(subscription) 54 function resetSubscription(subscription)
181 { 55 {
182 FilterStorage.updateSubscriptionFilters(subscription, []); 56 FilterStorage.updateSubscriptionFilters(subscription, []);
183 subscription.lastCheck = subscription.lastDownload = 57 subscription.lastCheck = subscription.lastDownload =
184 subscription.version = subscription.lastSuccess = 58 subscription.version = subscription.lastSuccess =
185 subscription.expires = subscription.softExpiration = 0; 59 subscription.expires = subscription.softExpiration = 0;
186 subscription.title = ""; 60 subscription.title = "";
187 subscription.homepage = null; 61 subscription.homepage = null;
188 subscription.errors = 0; 62 subscription.errors = 0;
189 subscription.downloadStatus = null; 63 subscription.downloadStatus = null;
190 subscription.requiredVersion = null; 64 subscription.requiredVersion = null;
191 } 65 }
192 66
193 test("Downloads of one subscription", function() 67 test("Downloads of one subscription", function()
194 { 68 {
195 // Always use average download interval
196 randomResult = 0.5;
197
198 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 69 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
199 FilterStorage.addSubscription(subscription); 70 FilterStorage.addSubscription(subscription);
200 71
201 let requests = []; 72 let requests = [];
202 function handler(metadata, response) 73 function handler(metadata, response)
203 { 74 {
204 requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path] ); 75 requests.push([testRunner.getTimeOffset(), metadata.method, metadata.path] );
205 76
206 response.setStatusLine("1.1", "200", "OK"); 77 response.setStatusLine("1.1", "200", "OK");
207 response.setHeader("Content-Type", "text/plain"); 78 response.setHeader("Content-Type", "text/plain");
208 79
209 let result = "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"; 80 let result = "[Adblock]\n! ExPiREs: 1day\nfoo\nbar";
210 response.bodyOutputStream.write(result, result.length); 81 response.bodyOutputStream.write(result, result.length);
211 } 82 }
212 83
213 server.registerPathHandler("/subscription", handler); 84 server.registerPathHandler("/subscription", handler);
214 85
215 testRunner.runScheduledTasks(50); 86 testRunner.runScheduledTasks(50);
216 deepEqual(requests, [ 87 deepEqual(requests, [
217 [0.1, "GET", "/subscription"], 88 [0.1, "GET", "/subscription"],
218 [24.1, "GET", "/subscription"], 89 [24.1, "GET", "/subscription"],
219 [48.1, "GET", "/subscription"], 90 [48.1, "GET", "/subscription"],
220 ], "Requests after 50 hours"); 91 ], "Requests after 50 hours");
221 }); 92 });
222 93
223 test("Downloads of two subscriptions", function() 94 test("Downloads of two subscriptions", function()
224 { 95 {
225 // Always use average download interval
226 randomResult = 0.5;
227
228 let subscription1 = Subscription.fromURL("http://127.0.0.1:1234/subscription 1"); 96 let subscription1 = Subscription.fromURL("http://127.0.0.1:1234/subscription 1");
229 FilterStorage.addSubscription(subscription1); 97 FilterStorage.addSubscription(subscription1);
230 98
231 let subscription2 = Subscription.fromURL("http://127.0.0.1:1234/subscription 2"); 99 let subscription2 = Subscription.fromURL("http://127.0.0.1:1234/subscription 2");
232 subscription2.expires = 100 subscription2.expires =
233 subscription2.softExpiration = 101 subscription2.softExpiration =
234 (testRunner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND; 102 (testRunner.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND;
235 FilterStorage.addSubscription(subscription2); 103 FilterStorage.addSubscription(subscription2);
236 104
237 let requests = []; 105 let requests = [];
(...skipping 17 matching lines...) Expand all
255 [2.1, "GET", "/subscription2"], 123 [2.1, "GET", "/subscription2"],
256 [24.1, "GET", "/subscription1"], 124 [24.1, "GET", "/subscription1"],
257 [26.1, "GET", "/subscription2"], 125 [26.1, "GET", "/subscription2"],
258 [48.1, "GET", "/subscription1"], 126 [48.1, "GET", "/subscription1"],
259 [50.1, "GET", "/subscription2"], 127 [50.1, "GET", "/subscription2"],
260 ], "Requests after 55 hours"); 128 ], "Requests after 55 hours");
261 }); 129 });
262 130
263 test("Download result, various subscription headers", function() 131 test("Download result, various subscription headers", function()
264 { 132 {
265 // Always use average download interval
266 randomResult = 0.5;
267
268 let test; 133 let test;
269 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 134 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
270 FilterStorage.addSubscription(subscription); 135 FilterStorage.addSubscription(subscription);
271 136
272 function handler(metadata, response) 137 function handler(metadata, response)
273 { 138 {
274 response.setStatusLine("1.1", "200", "OK"); 139 response.setStatusLine("1.1", "200", "OK");
275 140
276 // Wrong content type shouldn't matter 141 // Wrong content type shouldn't matter
277 response.setHeader("Content-Type", "text/xml"); 142 response.setHeader("Content-Type", "text/xml");
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 testRunner.runScheduledTasks(maxHours, test.skipAfter, test.skip); 292 testRunner.runScheduledTasks(maxHours, test.skipAfter, test.skip);
428 293
429 let randomAddendum = (randomResult == 0.5 ? "" : " with Math.random() retu rning " + randomResult); 294 let randomAddendum = (randomResult == 0.5 ? "" : " with Math.random() retu rning " + randomResult);
430 let skipAddendum = (typeof test.skip != "number" ? "" : " skipping " + tes t.skip + " hours after " + test.skipAfter + " hours"); 295 let skipAddendum = (typeof test.skip != "number" ? "" : " skipping " + tes t.skip + " hours after " + test.skipAfter + " hours");
431 deepEqual(requests, test.requests, "Requests for \"" + test.expiration + " \"" + randomAddendum + skipAddendum); 296 deepEqual(requests, test.requests, "Requests for \"" + test.expiration + " \"" + randomAddendum + skipAddendum);
432 } 297 }
433 }); 298 });
434 299
435 test("Checksum verification", function() 300 test("Checksum verification", function()
436 { 301 {
437 // Always use average download interval
438 randomResult = 0.5;
439
440 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 302 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
441 FilterStorage.addSubscription(subscription); 303 FilterStorage.addSubscription(subscription);
442 304
443 let testName, subscriptionBody, expectedResult; 305 let testName, subscriptionBody, expectedResult;
444 let tests = [ 306 let tests = [
445 ["Correct checksum", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\nfoo\n bar\n", true], 307 ["Correct checksum", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\nfoo\n bar\n", true],
446 ["Wrong checksum", "[Adblock]\n! Checksum: wrongggny6Fn24b7JHsq/A\nfoo\nba r\n", false], 308 ["Wrong checksum", "[Adblock]\n! Checksum: wrongggny6Fn24b7JHsq/A\nfoo\nba r\n", false],
447 ["Empty lines ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\n\n foo\n\nbar\n\n", true], 309 ["Empty lines ignored", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\n\n foo\n\nbar\n\n", true],
448 ["CR LF line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn 24b7JHsq/A\nfoo\r\nbar\r\n", true], 310 ["CR LF line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn 24b7JHsq/A\nfoo\r\nbar\r\n", true],
449 ["CR line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b 7JHsq/A\nfoo\rbar\r", true], 311 ["CR line breaks treated like LR", "[Adblock]\n! Checksum: e/JCmqXny6Fn24b 7JHsq/A\nfoo\rbar\r", true],
(...skipping 18 matching lines...) Expand all
468 for each ([testName, subscriptionBody, expectedResult] in tests) 330 for each ([testName, subscriptionBody, expectedResult] in tests)
469 { 331 {
470 resetSubscription(subscription); 332 resetSubscription(subscription);
471 testRunner.runScheduledTasks(2); 333 testRunner.runScheduledTasks(2);
472 equal(subscription.downloadStatus, expectedResult ? "synchronize_ok" : "sy nchronize_checksum_mismatch", testName); 334 equal(subscription.downloadStatus, expectedResult ? "synchronize_ok" : "sy nchronize_checksum_mismatch", testName);
473 } 335 }
474 }); 336 });
475 337
476 test("Special comments", function() 338 test("Special comments", function()
477 { 339 {
478 // Always use average download interval
479 randomResult = 0.5;
480
481 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 340 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
482 FilterStorage.addSubscription(subscription); 341 FilterStorage.addSubscription(subscription);
483 342
484 let comment, check; 343 let comment, check;
485 let tests = [ 344 let tests = [
486 ["! Homepage: http://example.com/", function() equal(subscription.homepage , "http://example.com/", "Valid homepage comment")], 345 ["! Homepage: http://example.com/", function() equal(subscription.homepage , "http://example.com/", "Valid homepage comment")],
487 ["! Homepage: ssh://example.com/", function() equal(subscription.homepage, null, "Invalid homepage comment")], 346 ["! Homepage: ssh://example.com/", function() equal(subscription.homepage, null, "Invalid homepage comment")],
488 ["! Title: foo", function() 347 ["! Title: foo", function()
489 { 348 {
490 equal(subscription.title, "foo", "Title comment"); 349 equal(subscription.title, "foo", "Title comment");
(...skipping 16 matching lines...) Expand all
507 { 366 {
508 resetSubscription(subscription); 367 resetSubscription(subscription);
509 testRunner.runScheduledTasks(2); 368 testRunner.runScheduledTasks(2);
510 check(); 369 check();
511 deepEqual(subscription.filters, [Filter.fromText("foo"), Filter.fromText(" bar")], "Special comment not added to filters"); 370 deepEqual(subscription.filters, [Filter.fromText("foo"), Filter.fromText(" bar")], "Special comment not added to filters");
512 } 371 }
513 }); 372 });
514 373
515 test("Redirects", function() 374 test("Redirects", function()
516 { 375 {
517 // Always use average download interval
518 randomResult = 0.5;
519
520 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 376 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
521 FilterStorage.addSubscription(subscription); 377 FilterStorage.addSubscription(subscription);
522 378
523 function redirect_handler(metadata, response) 379 function redirect_handler(metadata, response)
524 { 380 {
525 response.setStatusLine("1.1", "200", "OK"); 381 response.setStatusLine("1.1", "200", "OK");
526 response.setHeader("Content-Type", "text/plain"); 382 response.setHeader("Content-Type", "text/plain");
527 383
528 let result = "[Adblock]\nfoo\n!Redirect: http://127.0.0.1:1234/redirected\ nbar"; 384 let result = "[Adblock]\nfoo\n!Redirect: http://127.0.0.1:1234/redirected\ nbar";
529 response.bodyOutputStream.write(result, result.length); 385 response.bodyOutputStream.write(result, result.length);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 423 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
568 FilterStorage.addSubscription(subscription); 424 FilterStorage.addSubscription(subscription);
569 425
570 testRunner.runScheduledTasks(2); 426 testRunner.runScheduledTasks(2);
571 equal(FilterStorage.subscriptions[0], subscription, "Redirect not followed o n redirect loop"); 427 equal(FilterStorage.subscriptions[0], subscription, "Redirect not followed o n redirect loop");
572 equal(subscription.downloadStatus, "synchronize_connection_error", "Download status after redirect loop"); 428 equal(subscription.downloadStatus, "synchronize_connection_error", "Download status after redirect loop");
573 }); 429 });
574 430
575 test("Fallback", function() 431 test("Fallback", function()
576 { 432 {
577 // Always use average download interval
578 randomResult = 0.5;
579
580 Prefs.subscriptions_fallbackerrors = 3; 433 Prefs.subscriptions_fallbackerrors = 3;
581 Prefs.subscriptions_fallbackurl = "http://127.0.0.1:1234/fallback?%SUBSCRIPT ION%&%CHANNELSTATUS%&%RESPONSESTATUS%"; 434 Prefs.subscriptions_fallbackurl = "http://127.0.0.1:1234/fallback?%SUBSCRIPT ION%&%CHANNELSTATUS%&%RESPONSESTATUS%";
582 435
583 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 436 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
584 FilterStorage.addSubscription(subscription); 437 FilterStorage.addSubscription(subscription);
585 438
586 // No valid response from fallback 439 // No valid response from fallback
587 440
588 let requests = []; 441 let requests = [];
589 function handler(metadata, response) 442 function handler(metadata, response)
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 resetSubscription(subscription); 551 resetSubscription(subscription);
699 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]); 552 FilterStorage.removeSubscription(FilterStorage.subscriptions[0]);
700 FilterStorage.addSubscription(subscription); 553 FilterStorage.addSubscription(subscription);
701 554
702 testRunner.runScheduledTasks(100); 555 testRunner.runScheduledTasks(100);
703 equal(FilterStorage.subscriptions[0].url, "http://127.0.0.1:1234/redirected" , "Fallback can still redirect even after a redirect loop"); 556 equal(FilterStorage.subscriptions[0].url, "http://127.0.0.1:1234/redirected" , "Fallback can still redirect even after a redirect loop");
704 }); 557 });
705 558
706 test("State fields", function() 559 test("State fields", function()
707 { 560 {
708 // Always use average download interval
709 randomResult = 0.5;
710
711 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" ); 561 let subscription = Subscription.fromURL("http://127.0.0.1:1234/subscription" );
712 FilterStorage.addSubscription(subscription); 562 FilterStorage.addSubscription(subscription);
713 563
714 server.registerPathHandler("/subscription", function successHandler(metadata , response) 564 server.registerPathHandler("/subscription", function successHandler(metadata , response)
715 { 565 {
716 response.setStatusLine("1.1", "200", "OK"); 566 response.setStatusLine("1.1", "200", "OK");
717 response.setHeader("Content-Type", "text/plain"); 567 response.setHeader("Content-Type", "text/plain");
718 568
719 let result = "[Adblock]\n! Expires: 2 hours\nfoo\nbar"; 569 let result = "[Adblock]\n! Expires: 2 hours\nfoo\nbar";
720 response.bodyOutputStream.write(result, result.length); 570 response.bodyOutputStream.write(result, result.length);
(...skipping 15 matching lines...) Expand all
736 586
737 testRunner.runScheduledTasks(2); 587 testRunner.runScheduledTasks(2);
738 588
739 equal(subscription.downloadStatus, "synchronize_connection_error", "download Status after download error"); 589 equal(subscription.downloadStatus, "synchronize_connection_error", "download Status after download error");
740 equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + 2.1 * MILLIS _IN_HOUR, "lastDownload after download error"); 590 equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + 2.1 * MILLIS _IN_HOUR, "lastDownload after download error");
741 equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + 0.1 * MILLIS_ IN_HOUR, "lastSuccess after download error"); 591 equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + 0.1 * MILLIS_ IN_HOUR, "lastSuccess after download error");
742 equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + 3.1 * MILLIS_IN _HOUR, "lastCheck after download error"); 592 equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + 3.1 * MILLIS_IN _HOUR, "lastCheck after download error");
743 equal(subscription.errors, 1, "errors after download error"); 593 equal(subscription.errors, 1, "errors after download error");
744 }); 594 });
745 })(); 595 })();
LEFTRIGHT

Powered by Google App Engine
This is Rietveld