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

Delta Between Two Patch Sets: test/synchronizer.js

Issue 29606600: Issue 5146 - Implement DownloadableSubscription parsing in C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Left Patch Set: Added md5 checksum. Reorganized some code. Created Nov. 28, 2017, 10:46 p.m.
Right Patch Set: Removed Md5sum and associated code Created Aug. 14, 2018, 12:38 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
« no previous file with change/comment | « test/stub-modules/utils.js ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH
4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 "use strict";
19
20 let {
21 createSandbox, setupTimerAndXMLHttp, setupRandomResult, unexpectedError, Cr,
22 MILLIS_IN_SECOND, MILLIS_IN_HOUR
23 } = require("./_common");
24
25 let Filter = null;
26 let FilterStorage = null;
27 let Prefs = null;
28 let Subscription = null;
29
30 exports.setUp = function(callback)
31 {
32 let globals = Object.assign({}, setupTimerAndXMLHttp.call(this),
33 setupRandomResult.call(this));
34
35 let sandboxedRequire = createSandbox({globals});
36 (
37 {Filter} = sandboxedRequire("../lib/filterClasses"),
38 {FilterStorage} = sandboxedRequire("../lib/filterStorage"),
39 {Prefs} = sandboxedRequire("./stub-modules/prefs"),
40 {Subscription} = sandboxedRequire("../lib/subscriptionClasses"),
41 sandboxedRequire("../lib/synchronizer")
42 );
43
44 callback();
45 };
46
47 function resetSubscription(subscription)
48 {
49 FilterStorage.clearSubscriptionFilters(subscription);
50 subscription.lastCheck = subscription.lastDownload =
51 subscription.version = subscription.lastSuccess =
52 subscription.expires = subscription.softExpiration = 0;
53 subscription.title = "";
54 subscription.homepage = null;
55 subscription.errors = 0;
56 subscription.downloadStatus = null;
57 subscription.requiredVersion = null;
58 }
59
60 function testFiltersEqual(test, subscription, expected, message)
61 {
62 test.deepEqual(
63 Array.from(subscription.filters, filter => filter.text),
64 expected.map(filter => filter.text));
65 }
66
67 function testSubscriptionEqual(test, sub1, sub2, message)
68 {
69 test.equal(sub1.fixedTitle, sub2.fixedTitle, message);
70 test.equal(sub1.homepage, sub2.homepage, message);
71 }
72
73 let initialDelay = 1 / 60;
74
75 exports.testOneSubscriptionDownloads = function(test)
76 {
77 let subscription = Subscription.fromURL("http://example.com/subscription");
78 FilterStorage.addSubscription(subscription);
79
80 let requests = [];
81 this.registerHandler("/subscription", metadata =>
82 {
83 requests.push([this.getTimeOffset(), metadata.method, metadata.path]);
84 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"];
85 });
86
87 this.runScheduledTasks(50).then(() =>
88 {
89 test.deepEqual(requests, [
90 [0 + initialDelay, "GET", "/subscription"],
91 [24 + initialDelay, "GET", "/subscription"],
92 [48 + initialDelay, "GET", "/subscription"]
93 ], "Requests after 50 hours");
94 }).catch(unexpectedError.bind(test)).then(() => test.done());
95 };
96
97 exports.testTwoSubscriptionsDownloads = function(test)
98 {
99 let subscription1 = Subscription.fromURL("http://example.com/subscription1");
100 FilterStorage.addSubscription(subscription1);
101
102 let subscription2 = Subscription.fromURL("http://example.com/subscription2");
103 subscription2.expires =
104 subscription2.softExpiration =
105 (this.currentTime + 2 * MILLIS_IN_HOUR) / MILLIS_IN_SECOND;
106 FilterStorage.addSubscription(subscription2);
107
108 let requests = [];
109 let handler = metadata =>
110 {
111 requests.push([this.getTimeOffset(), metadata.method, metadata.path]);
112 return [Cr.NS_OK, 200, "[Adblock]\n! ExPiREs: 1day\nfoo\nbar"];
113 };
114
115 this.registerHandler("/subscription1", handler);
116 this.registerHandler("/subscription2", handler);
117
118 this.runScheduledTasks(55).then(() =>
119 {
120 test.deepEqual(requests, [
121 [0 + initialDelay, "GET", "/subscription1"],
122 [2 + initialDelay, "GET", "/subscription2"],
123 [24 + initialDelay, "GET", "/subscription1"],
124 [26 + initialDelay, "GET", "/subscription2"],
125 [48 + initialDelay, "GET", "/subscription1"],
126 [50 + initialDelay, "GET", "/subscription2"]
127 ], "Requests after 55 hours");
128 }).catch(unexpectedError.bind(test)).then(() => test.done());
129 };
130
131 exports.testSubscriptionHeaders = {};
132
133 for (let currentTest of [
134 {header: "[Adblock]", downloadStatus: "synchronize_ok", requiredVersion: ""},
135 {header: "[Adblock Plus]", downloadStatus: "synchronize_ok", requiredVersion: ""},
136 {header: "(something)[Adblock]", downloadStatus: "synchronize_ok", requiredVer sion: ""},
137 {header: "[Adblock Plus 0.0.1]", downloadStatus: "synchronize_ok", requiredVer sion: "0.0.1"},
138 {header: "[Adblock Plus 99.9]", downloadStatus: "synchronize_ok", requiredVers ion: "99.9"},
139 {header: "[Foo]", downloadStatus: "synchronize_invalid_data", requiredVersion: ""}
140 ])
141 {
142 exports.testSubscriptionHeaders[currentTest.header] = function(test)
143 {
144 let subscription = Subscription.fromURL("http://example.com/subscription");
145 FilterStorage.addSubscription(subscription);
146
147 this.registerHandler("/subscription", metadata =>
148 {
149 return [Cr.NS_OK, 200, currentTest.header + "\n!Expires: 8 hours\nfoo\n!ba r\n\n@@bas\n#bam"];
150 });
151
152 this.runScheduledTasks(2).then(() =>
153 {
154 test.equal(subscription.downloadStatus, currentTest.downloadStatus, "Downl oad status");
155 test.equal(subscription.requiredVersion, currentTest.requiredVersion, "Req uired version");
156
157 if (currentTest.downloadStatus == "synchronize_ok")
158 {
159 testFiltersEqual(test, subscription, [
160 Filter.fromText("foo"),
161 Filter.fromText("!bar"),
162 Filter.fromText("@@bas"),
163 Filter.fromText("#bam")
164 ], "Resulting subscription filters");
165 }
166 else
167 {
168 testFiltersEqual(test, subscription, [],
169 "Resulting subscription filters");
170 }
171 }).catch(unexpectedError.bind(test)).then(() => test.done());
172 };
173 }
174
175 exports.testsDisabledUpdates = function(test)
176 {
177 Prefs.subscriptions_autoupdate = false;
178
179 let subscription = Subscription.fromURL("http://example.com/subscription");
180 FilterStorage.addSubscription(subscription);
181
182 let requests = 0;
183 this.registerHandler("/subscription", metadata =>
184 {
185 requests++;
186 throw new Error("Unexpected request");
187 });
188
189 this.runScheduledTasks(50).then(() =>
190 {
191 test.equal(requests, 0, "Request count");
192 }).catch(unexpectedError.bind(test)).then(() => test.done());
193 };
194
195 exports.testExpirationTime = {};
196
197 for (let currentTest of [
198 {
199 expiration: "default",
200 randomResult: 0.5,
201 requests: [0 + initialDelay, 5 * 24 + initialDelay]
202 },
203 {
204 expiration: "1 hours", // Minimal expiration interval
205 randomResult: 0.5,
206 requests: [0 + initialDelay, 1 + initialDelay, 2 + initialDelay, 3 + initial Delay]
207 },
208 {
209 expiration: "26 hours",
210 randomResult: 0.5,
211 requests: [0 + initialDelay, 26 + initialDelay]
212 },
213 {
214 expiration: "2 days",
215 randomResult: 0.5,
216 requests: [0 + initialDelay, 48 + initialDelay]
217 },
218 {
219 expiration: "20 days", // Too large, will be corrected
220 randomResult: 0.5,
221 requests: [0 + initialDelay, 14 * 24 + initialDelay]
222 },
223 {
224 expiration: "35 hours",
225 randomResult: 0, // Changes interval by factor 0.8
226 requests: [0 + initialDelay, 28 + initialDelay]
227 },
228 {
229 expiration: "35 hours",
230 randomResult: 1, // Changes interval by factor 1.2
231 requests: [0 + initialDelay, 42 + initialDelay]
232 },
233 {
234 expiration: "35 hours",
235 randomResult: 0.25, // Changes interval by factor 0.9
236 requests: [0 + initialDelay, 32 + initialDelay]
237 },
238 {
239 expiration: "40 hours",
240 randomResult: 0.5,
241 skipAfter: 5 + initialDelay,
242 skip: 10, // Short break should not increase soft expiration
243 requests: [0 + initialDelay, 40 + initialDelay]
244 },
245 {
246 expiration: "40 hours",
247 randomResult: 0.5,
248 skipAfter: 5 + initialDelay,
249 skip: 30, // Long break should increase soft expiration
250 requests: [0 + initialDelay, 70 + initialDelay]
251 },
252 {
253 expiration: "40 hours",
254 randomResult: 0.5,
255 skipAfter: 5 + initialDelay,
256 skip: 80, // Hitting hard expiration, immediate download
257 requests: [0 + initialDelay, 85 + initialDelay]
258 }
259 ])
260 {
261 let testId = `"${currentTest.expiration}"`;
262 if (currentTest.randomResult != 0.5)
263 testId += " with Math.random() returning " + currentTest.randomResult;
264 if (currentTest.skip)
265 testId += " skipping " + currentTest.skip + " hours after " + currentTest.sk ipAfter + " hours";
266 exports.testExpirationTime[testId] = function(test)
267 {
268 let subscription = Subscription.fromURL("http://example.com/subscription");
269 FilterStorage.addSubscription(subscription);
270
271 let requests = [];
272 this.registerHandler("/subscription", metadata =>
273 {
274 requests.push(this.getTimeOffset());
275 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Expires: " + currentTest.expirati on + "\nbar"];
276 });
277
278 this.randomResult = currentTest.randomResult;
279
280 let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1;
281 this.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.skip).th en(() =>
282 {
283 test.deepEqual(requests, currentTest.requests, "Requests");
284 }).catch(unexpectedError.bind(test)).then(() => test.done());
285 };
286 }
287
288 exports.testSpecialComments = {};
289
290 for (let [comment, check] of [
291 ["! Homepage: http://example.com/", (test, subscription) =>
292 {
293 test.equal(subscription.homepage, "http://example.com/", "Valid homepage com ment");
294 }],
295 ["! Homepage: ssh://example.com/", (test, subscription) =>
296 {
297 test.equal(subscription.homepage, "", "Invalid homepage comment");
298 }],
299 ["! Title: foo", (test, subscription) =>
300 {
301 test.equal(subscription.title, "foo", "Title comment");
302 test.equal(subscription.fixedTitle, true, "Fixed title");
303 }],
304 ["! Version: 1234", (test, subscription) =>
305 {
306 test.equal(subscription.version, 1234, "Version comment");
307 }]
308 ])
309 {
310 exports.testSpecialComments[comment] = function(test)
311 {
312 let subscription = Subscription.fromURL("http://example.com/subscription");
313 FilterStorage.addSubscription(subscription);
314
315 this.registerHandler("/subscription", metadata =>
316 {
317 return [Cr.NS_OK, 200, "[Adblock]\n" + comment + "\nfoo\nbar"];
318 });
319
320 this.runScheduledTasks(2).then(() =>
321 {
322 check(test, subscription);
323 testFiltersEqual(test, subscription, [Filter.fromText("foo"), Filter.fromT ext("bar")], "Special comment not added to filters");
324 }).catch(unexpectedError.bind(test)).then(() => test.done());
325 };
326 }
327
328 exports.testRedirects = function(test)
329 {
330 let subscription = Subscription.fromURL("http://example.com/subscription");
331 FilterStorage.addSubscription(subscription);
332
333 this.registerHandler("/subscription", metadata =>
334 {
335 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/redire cted\nbar"];
336 });
337
338 let requests;
339
340 this.runScheduledTasks(30).then(() =>
341 {
342 testSubscriptionEqual(test, FilterStorage.subscriptionAt(0), subscription, " Invalid redirect ignored");
343 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Con nection error recorded");
344 test.equal(subscription.errors, 2, "Number of download errors");
345
346 requests = [];
347
348 this.registerHandler("/redirected", metadata =>
349 {
350 requests.push(this.getTimeOffset());
351 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n! Expires: 8 hours\nbar"];
352 });
353
354 resetSubscription(subscription);
355 return this.runScheduledTasks(15);
356 }).then(() =>
357 {
358 test.equal(FilterStorage.subscriptionAt(0).url, "http://example.com/redirect ed", "Redirect followed");
359 test.deepEqual(requests, [0 + initialDelay, 8 + initialDelay], "Resulting re quests");
360
361 this.registerHandler("/redirected", metadata =>
362 {
363 return [Cr.NS_OK, 200, "[Adblock]\nfoo\n!Redirect: http://example.com/subs cription\nbar"];
364 });
365
366 subscription = Subscription.fromURL("http://example.com/subscription");
367 resetSubscription(subscription);
368 FilterStorage.removeSubscription(FilterStorage.subscriptionAt(0));
369 FilterStorage.addSubscription(subscription);
370
371 return this.runScheduledTasks(2);
372 }).then(() =>
373 {
374 testSubscriptionEqual(test, FilterStorage.subscriptionAt(0), subscription, " Redirect not followed on redirect loop");
375 test.equal(subscription.downloadStatus, "synchronize_connection_error", "Dow nload status after redirect loop");
376 }).catch(unexpectedError.bind(test)).then(() => test.done());
377 };
378
379 exports.testFallback = function(test)
380 {
381 Prefs.subscriptions_fallbackerrors = 3;
382 Prefs.subscriptions_fallbackurl = "http://example.com/fallback?%SUBSCRIPTION%& %CHANNELSTATUS%&%RESPONSESTATUS%";
383
384 let subscription = Subscription.fromURL("http://example.com/subscription");
385 FilterStorage.addSubscription(subscription);
386
387 // No valid response from fallback
388
389 let requests = [];
390 let fallbackParams;
391 let redirectedRequests;
392 this.registerHandler("/subscription", metadata =>
393 {
394 requests.push(this.getTimeOffset());
395 return [Cr.NS_OK, 404, ""];
396 });
397
398 this.runScheduledTasks(100).then(() =>
399 {
400 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay, 72 + initialDelay, 96 + initialDelay], "Continue trying if the fallback do esn't respond");
401
402 // Fallback giving "Gone" response
403
404 resetSubscription(subscription);
405 requests = [];
406 fallbackParams = null;
407 this.registerHandler("/fallback", metadata =>
408 {
409 fallbackParams = decodeURIComponent(metadata.queryString);
410 return [Cr.NS_OK, 200, "410 Gone"];
411 });
412
413 return this.runScheduledTasks(100);
414 }).then(() =>
415 {
416 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay], "Stop trying if the fallback responds with Gone");
417 test.equal(fallbackParams, "http://example.com/subscription&0&404", "Fallbac k arguments");
418
419 // Fallback redirecting to a missing file
420
421 subscription = Subscription.fromURL("http://example.com/subscription");
422 resetSubscription(subscription);
423 FilterStorage.removeSubscription(FilterStorage.subscriptionAt(0));
424 FilterStorage.addSubscription(subscription);
425 requests = [];
426
427 this.registerHandler("/fallback", metadata =>
428 {
429 return [Cr.NS_OK, 200, "301 http://example.com/redirected"];
430 });
431 return this.runScheduledTasks(100);
432 }).then(() =>
433 {
434 test.equal(FilterStorage.subscriptionAt(0).url, "http://example.com/subscrip tion", "Ignore invalid redirect from fallback");
435 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay, 72 + initialDelay, 96 + initialDelay], "Requests not affected by invalid r edirect");
436
437 // Fallback redirecting to an existing file
438
439 resetSubscription(subscription);
440 requests = [];
441 redirectedRequests = [];
442 this.registerHandler("/redirected", metadata =>
443 {
444 redirectedRequests.push(this.getTimeOffset());
445 return [Cr.NS_OK, 200, "[Adblock]\n!Expires: 1day\nfoo\nbar"];
446 });
447
448 return this.runScheduledTasks(100);
449 }).then(() =>
450 {
451 test.equal(FilterStorage.subscriptionAt(0).url, "http://example.com/redirect ed", "Valid redirect from fallback is followed");
452 test.deepEqual(requests, [0 + initialDelay, 24 + initialDelay, 48 + initialD elay], "Stop polling original URL after a valid redirect from fallback");
453 test.deepEqual(redirectedRequests, [48 + initialDelay, 72 + initialDelay, 96 + initialDelay], "Request new URL after a valid redirect from fallback");
454
455 // Redirect loop
456
457 this.registerHandler("/subscription", metadata =>
458 {
459 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion2"];
460 });
461 this.registerHandler("/subscription2", metadata =>
462 {
463 return [Cr.NS_OK, 200, "[Adblock]\n! Redirect: http://example.com/subscrip tion"];
464 });
465
466 subscription = Subscription.fromURL("http://example.com/subscription");
467 resetSubscription(subscription);
468 FilterStorage.removeSubscription(FilterStorage.subscriptionAt(0));
469 FilterStorage.addSubscription(subscription);
470
471 return this.runScheduledTasks(100);
472 }).then(() =>
473 {
474 test.equal(FilterStorage.subscriptionAt(0).url, "http://example.com/redirect ed", "Fallback can still redirect even after a redirect loop");
475 }).catch(unexpectedError.bind(test)).then(() => test.done());
476 };
477
478 exports.testStateFields = function(test)
479 {
480 let subscription = Subscription.fromURL("http://example.com/subscription");
481 FilterStorage.addSubscription(subscription);
482
483 this.registerHandler("/subscription", metadata =>
484 {
485 return [Cr.NS_OK, 200, "[Adblock]\n! Expires: 2 hours\nfoo\nbar"];
486 });
487
488 let startTime = this.currentTime;
489 this.runScheduledTasks(2).then(() =>
490 {
491 test.equal(subscription.downloadStatus, "synchronize_ok", "downloadStatus af ter successful download");
492 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + initial Delay * MILLIS_IN_HOUR, "lastDownload after successful download");
493 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD elay * MILLIS_IN_HOUR, "lastSuccess after successful download");
494 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (1 + initi alDelay) * MILLIS_IN_HOUR, "lastCheck after successful download");
495 test.equal(subscription.errors, 0, "errors after successful download");
496
497 this.registerHandler("/subscription", metadata =>
498 {
499 return [Cr.NS_ERROR_FAILURE, 0, ""];
500 });
501
502 return this.runScheduledTasks(2);
503 }).then(() =>
504 {
505 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow nloadStatus after connection error");
506 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (2 + in itialDelay) * MILLIS_IN_HOUR, "lastDownload after connection error");
507 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD elay * MILLIS_IN_HOUR, "lastSuccess after connection error");
508 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (3 + initi alDelay) * MILLIS_IN_HOUR, "lastCheck after connection error");
509 test.equal(subscription.errors, 1, "errors after connection error");
510
511 this.registerHandler("/subscription", metadata =>
512 {
513 return [Cr.NS_OK, 404, ""];
514 });
515
516 return this.runScheduledTasks(24);
517 }).then(() =>
518 {
519 test.equal(subscription.downloadStatus, "synchronize_connection_error", "dow nloadStatus after download error");
520 test.equal(subscription.lastDownload * MILLIS_IN_SECOND, startTime + (26 + i nitialDelay) * MILLIS_IN_HOUR, "lastDownload after download error");
521 test.equal(subscription.lastSuccess * MILLIS_IN_SECOND, startTime + initialD elay * MILLIS_IN_HOUR, "lastSuccess after download error");
522 test.equal(subscription.lastCheck * MILLIS_IN_SECOND, startTime + (27 + init ialDelay) * MILLIS_IN_HOUR, "lastCheck after download error");
523 test.equal(subscription.errors, 2, "errors after download error");
524 }).catch(unexpectedError.bind(test)).then(() => test.done());
525 };
LEFTRIGHT

Powered by Google App Engine
This is Rietveld