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

Side by Side Diff: test/filterStorage_readwrite.js

Issue 30025555: Issue 6820 - Move tests to mocha (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Rebased. Created April 5, 2019, 4:16 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/filterStorage.js ('k') | test/matcher.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-present eyeo GmbH 3 * Copyright (C) 2006-present eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 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 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 "use strict"; 18 "use strict";
19 19
20 const assert = require("assert");
20 const {createSandbox, unexpectedError} = require("./_common"); 21 const {createSandbox, unexpectedError} = require("./_common");
21 22
22 let Filter = null; 23 let Filter = null;
23 let filterStorage = null; 24 let filterStorage = null;
24 let IO = null; 25 let IO = null;
25 let Prefs = null; 26 let Prefs = null;
26 let ExternalSubscription = null; 27 let ExternalSubscription = null;
27 let SpecialSubscription = null; 28 let SpecialSubscription = null;
28 29
29 exports.setUp = function(callback) 30 describe("Filter Storage Read/Write", () =>
30 { 31 {
31 let sandboxedRequire = createSandbox(); 32 beforeEach(() =>
32 ( 33 {
33 {Filter} = sandboxedRequire("../lib/filterClasses"), 34 let sandboxedRequire = createSandbox();
34 {filterStorage} = sandboxedRequire("../lib/filterStorage"), 35 (
35 {IO} = sandboxedRequire("./stub-modules/io"), 36 {Filter} = sandboxedRequire("../lib/filterClasses"),
36 {Prefs} = sandboxedRequire("./stub-modules/prefs"), 37 {filterStorage} = sandboxedRequire("../lib/filterStorage"),
37 {ExternalSubscription, SpecialSubscription} = sandboxedRequire("../lib/subsc riptionClasses") 38 {IO} = sandboxedRequire("./stub-modules/io"),
38 ); 39 {Prefs} = sandboxedRequire("./stub-modules/prefs"),
39 40 {ExternalSubscription, SpecialSubscription} = sandboxedRequire("../lib/sub scriptionClasses")
40 filterStorage.addFilter(Filter.fromText("foobar")); 41 );
41 callback(); 42
42 }; 43 filterStorage.addFilter(Filter.fromText("foobar"));
43 44 });
44 let testData = new Promise((resolve, reject) => 45
45 { 46 let testData = new Promise((resolve, reject) =>
46 const fs = require("fs"); 47 {
47 const path = require("path"); 48 const fs = require("fs");
48 let datapath = path.resolve(__dirname, "data", "patterns.ini"); 49 const path = require("path");
49 50 let datapath = path.resolve(__dirname, "data", "patterns.ini");
50 fs.readFile(datapath, "utf-8", (error, data) => 51
51 { 52 fs.readFile(datapath, "utf-8", (error, data) =>
52 if (error) 53 {
53 reject(error); 54 if (error)
54 else 55 reject(error);
55 resolve(data.split(/[\r\n]+/)); 56 else
57 resolve(data.split(/[\r\n]+/));
58 });
59 });
60
61 function canonize(data)
62 {
63 let curSection = null;
64 let sections = [];
65 for (let line of data)
66 {
67 if (/^\[.*\]$/.test(line))
68 {
69 if (curSection)
70 sections.push(curSection);
71
72 curSection = {header: line, data: []};
73 }
74 else if (curSection && /\S/.test(line))
75 curSection.data.push(line);
76 }
77 if (curSection)
78 sections.push(curSection);
79
80 for (let section of sections)
81 {
82 section.key = section.header + " " + section.data[0];
83 section.data.sort();
84 }
85 sections.sort((a, b) =>
86 {
87 if (a.key < b.key)
88 return -1;
89 else if (a.key > b.key)
90 return 1;
91 return 0;
92 });
93 return sections;
94 }
95
96 async function testReadWrite(withExternal, withEmptySpecial)
97 {
98 assert.ok(!filterStorage.initialized, "Uninitialized before the first load") ;
99
100 try
101 {
102 let data = await testData;
103
104 IO._setFileContents(filterStorage.sourceFile, data);
105 await filterStorage.loadFromDisk();
106
107 assert.ok(filterStorage.initialized, "Initialize after the first load");
108 assert.equal(filterStorage.fileProperties.version, filterStorage.formatVer sion, "File format version");
109
110 if (withExternal)
111 {
112 {
113 let subscription = new ExternalSubscription("~external~external subscr iption ID", "External subscription");
114 subscription.addFilter(Filter.fromText("foo"));
115 subscription.addFilter(Filter.fromText("bar"));
116 filterStorage.addSubscription(subscription);
117 }
118
119 let externalSubscriptions = [...filterStorage.subscriptions()].filter(su bscription => subscription instanceof ExternalSubscription);
120 assert.equal(externalSubscriptions.length, 1, "Number of external subscr iptions after updateExternalSubscription");
121
122 assert.equal(externalSubscriptions[0].url, "~external~external subscript ion ID", "ID of external subscription");
123 assert.equal(externalSubscriptions[0].filterCount, 2, "Number of filters in external subscription");
124 }
125
126 if (withEmptySpecial)
127 {
128 let specialSubscription =
129 SpecialSubscription.createForFilter(Filter.fromText("!foo"));
130 filterStorage.addSubscription(specialSubscription);
131
132 filterStorage.removeFilter(Filter.fromText("!foo"), specialSubscription) ;
133
134 assert.equal(specialSubscription.filterCount, 0,
135 "No filters in special subscription");
136 assert.ok(new Set(filterStorage.subscriptions()).has(specialSubscription ),
137 "Empty special subscription still in storage");
138 }
139
140 await filterStorage.saveToDisk();
141
142 let expected = await testData;
143
144 assert.deepEqual(canonize(IO._getFileContents(filterStorage.sourceFile)),
145 canonize(expected), "Read/write result");
146 }
147 catch (error)
148 {
149 unexpectedError.call(assert, error);
150 }
151 }
152
153 describe("Read and Save", () =>
154 {
155 it("to File", () =>
156 {
157 testReadWrite(false);
158 });
159
160 it("to file With External Subscription", () =>
161 {
162 testReadWrite(true);
163 });
164
165 it("to file With Empty Special", () =>
166 {
167 testReadWrite(false, true);
168 });
169 });
170
171 it("Import / Export", async() =>
172 {
173 try
174 {
175 let lines = await testData;
176
177 if (lines.length && lines[lines.length - 1] == "")
178 lines.pop();
179
180 let importer = filterStorage.importData();
181 for (let line of lines)
182 importer(line);
183 importer(null);
184
185 assert.equal(filterStorage.fileProperties.version, filterStorage.formatVer sion, "File format version");
186
187 let exported = Array.from(filterStorage.exportData());
188 assert.deepEqual(canonize(exported), canonize(lines), "Import/export resul t");
189
190 // Make sure the relationships between filters and subscriptions are set
191 // up.
192 for (let subscription of filterStorage.subscriptions())
193 {
194 for (let text of subscription.filterText())
195 {
196 let found = false;
197
198 for (let filterSubscription of Filter.fromText(text).subscriptions())
199 {
200 if (filterSubscription == subscription)
201 {
202 found = true;
203 break;
204 }
205 }
206
207 assert.ok(found, `Filter ${text} should be linked to subscription ${su bscription.url}`);
208 }
209 }
210 }
211 catch (error)
212 {
213 unexpectedError.call(assert, error);
214 }
215 });
216
217 describe("Backups", () =>
218 {
219 it("Saving Without", async() =>
220 {
221 Prefs.patternsbackups = 0;
222 Prefs.patternsbackupinterval = 24;
223
224 try
225 {
226 await filterStorage.saveToDisk();
227 await filterStorage.saveToDisk();
228
229 assert.ok(!IO._getFileContents(filterStorage.getBackupName(1)),
230 "Backup shouldn't be created");
231 }
232 catch (error)
233 {
234 unexpectedError.call(assert, error);
235 }
236 });
237
238 it("Saving With", async() =>
239 {
240 Prefs.patternsbackups = 2;
241 Prefs.patternsbackupinterval = 24;
242
243 let backupFile = filterStorage.getBackupName(1);
244 let backupFile2 = filterStorage.getBackupName(2);
245 let backupFile3 = filterStorage.getBackupName(3);
246
247 let oldModifiedTime;
248
249 try
250 {
251 await filterStorage.saveToDisk();
252
253 // Save again immediately
254 await filterStorage.saveToDisk();
255
256 assert.ok(IO._getFileContents(backupFile), "First backup created");
257
258 oldModifiedTime = IO._getModifiedTime(backupFile) - 10000;
259 IO._setModifiedTime(backupFile, oldModifiedTime);
260 await filterStorage.saveToDisk();
261
262 assert.equal(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup n ot overwritten if it is only 10 seconds old");
263
264 oldModifiedTime -= 40 * 60 * 60 * 1000;
265 IO._setModifiedTime(backupFile, oldModifiedTime);
266 await filterStorage.saveToDisk();
267
268 assert.notEqual(IO._getModifiedTime(backupFile), oldModifiedTime, "Backu p overwritten if it is 40 hours old");
269
270 assert.ok(IO._getFileContents(backupFile2), "Second backup created when first backup is overwritten");
271
272 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 20000) ;
273 oldModifiedTime = IO._getModifiedTime(backupFile2);
274 await filterStorage.saveToDisk();
275
276 assert.equal(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second backup not overwritten if first one is only 20 seconds old");
277
278 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 25 * 6 0 * 60 * 1000);
279 oldModifiedTime = IO._getModifiedTime(backupFile2);
280 await filterStorage.saveToDisk();
281
282 assert.notEqual(IO._getModifiedTime(backupFile2), oldModifiedTime, "Seco nd backup overwritten if first one is 25 hours old");
283
284 assert.ok(!IO._getFileContents(backupFile3), "Third backup not created w ith patternsbackups = 2");
285 }
286 catch (error)
287 {
288 unexpectedError.call(assert, error);
289 }
290 });
291
292 it("Restoring", async() =>
293 {
294 Prefs.patternsbackups = 2;
295 Prefs.patternsbackupinterval = 24;
296
297 try
298 {
299 await filterStorage.saveToDisk();
300
301 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Init ial filter count");
302 filterStorage.addFilter(Filter.fromText("barfoo"));
303 assert.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filt er count after adding a filter");
304 await filterStorage.saveToDisk();
305
306 await filterStorage.loadFromDisk();
307
308 assert.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filt er count after adding filter and reloading");
309 await filterStorage.restoreBackup(1);
310
311 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filt er count after restoring backup");
312 await filterStorage.loadFromDisk();
313
314 assert.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filt er count after reloading");
315 }
316 catch (error)
317 {
318 unexpectedError.call(assert, error);
319 }
320 });
56 }); 321 });
57 }); 322 });
58
59 function canonize(data)
60 {
61 let curSection = null;
62 let sections = [];
63 for (let line of data)
64 {
65 if (/^\[.*\]$/.test(line))
66 {
67 if (curSection)
68 sections.push(curSection);
69
70 curSection = {header: line, data: []};
71 }
72 else if (curSection && /\S/.test(line))
73 curSection.data.push(line);
74 }
75 if (curSection)
76 sections.push(curSection);
77
78 for (let section of sections)
79 {
80 section.key = section.header + " " + section.data[0];
81 section.data.sort();
82 }
83 sections.sort((a, b) =>
84 {
85 if (a.key < b.key)
86 return -1;
87 else if (a.key > b.key)
88 return 1;
89 return 0;
90 });
91 return sections;
92 }
93
94 async function testReadWrite(test, withExternal, withEmptySpecial)
95 {
96 test.ok(!filterStorage.initialized, "Uninitialized before the first load");
97
98 try
99 {
100 let data = await testData;
101
102 IO._setFileContents(filterStorage.sourceFile, data);
103 await filterStorage.loadFromDisk();
104
105 test.ok(filterStorage.initialized, "Initialize after the first load");
106 test.equal(filterStorage.fileProperties.version, filterStorage.formatVersion , "File format version");
107
108 if (withExternal)
109 {
110 {
111 let subscription = new ExternalSubscription("~external~external subscrip tion ID", "External subscription");
112 subscription.addFilter(Filter.fromText("foo"));
113 subscription.addFilter(Filter.fromText("bar"));
114 filterStorage.addSubscription(subscription);
115 }
116
117 let externalSubscriptions = [...filterStorage.subscriptions()].filter(subs cription => subscription instanceof ExternalSubscription);
118 test.equal(externalSubscriptions.length, 1, "Number of external subscripti ons after updateExternalSubscription");
119
120 test.equal(externalSubscriptions[0].url, "~external~external subscription ID", "ID of external subscription");
121 test.equal(externalSubscriptions[0].filterCount, 2, "Number of filters in external subscription");
122 }
123
124 if (withEmptySpecial)
125 {
126 let specialSubscription =
127 SpecialSubscription.createForFilter(Filter.fromText("!foo"));
128 filterStorage.addSubscription(specialSubscription);
129
130 filterStorage.removeFilter(Filter.fromText("!foo"), specialSubscription);
131
132 test.equal(specialSubscription.filterCount, 0,
133 "No filters in special subscription");
134 test.ok(new Set(filterStorage.subscriptions()).has(specialSubscription),
135 "Empty special subscription still in storage");
136 }
137
138 await filterStorage.saveToDisk();
139
140 let expected = await testData;
141
142 test.deepEqual(canonize(IO._getFileContents(filterStorage.sourceFile)),
143 canonize(expected), "Read/write result");
144 }
145 catch (error)
146 {
147 unexpectedError.call(test, error);
148 }
149
150 test.done();
151 }
152
153 exports.testReadAndSaveToFile = function(test)
154 {
155 testReadWrite(test, false);
156 };
157
158 exports.testReadAndSaveToFileWithExternalSubscription = function(test)
159 {
160 testReadWrite(test, true);
161 };
162
163 exports.testReadAndSaveToFileWithEmptySpecial = function(test)
164 {
165 testReadWrite(test, false, true);
166 };
167
168 exports.testImportExport = async function(test)
169 {
170 try
171 {
172 let lines = await testData;
173
174 if (lines.length && lines[lines.length - 1] == "")
175 lines.pop();
176
177 let importer = filterStorage.importData();
178 for (let line of lines)
179 importer(line);
180 importer(null);
181
182 test.equal(filterStorage.fileProperties.version, filterStorage.formatVersion , "File format version");
183
184 let exported = Array.from(filterStorage.exportData());
185 test.deepEqual(canonize(exported), canonize(lines), "Import/export result");
186
187 // Make sure the relationships between filters and subscriptions are set
188 // up.
189 for (let subscription of filterStorage.subscriptions())
190 {
191 for (let text of subscription.filterText())
192 {
193 let found = false;
194
195 for (let filterSubscription of Filter.fromText(text).subscriptions())
196 {
197 if (filterSubscription == subscription)
198 {
199 found = true;
200 break;
201 }
202 }
203
204 test.ok(found, `Filter ${text} should be linked to subscription ${subscr iption.url}`);
205 }
206 }
207 }
208 catch (error)
209 {
210 unexpectedError.call(test, error);
211 }
212
213 test.done();
214 };
215
216 exports.testSavingWithoutBackups = async function(test)
217 {
218 Prefs.patternsbackups = 0;
219 Prefs.patternsbackupinterval = 24;
220
221 try
222 {
223 await filterStorage.saveToDisk();
224 await filterStorage.saveToDisk();
225
226 test.ok(!IO._getFileContents(filterStorage.getBackupName(1)),
227 "Backup shouldn't be created");
228 }
229 catch (error)
230 {
231 unexpectedError.call(test, error);
232 }
233
234 test.done();
235 };
236
237 exports.testSavingWithBackups = async function(test)
238 {
239 Prefs.patternsbackups = 2;
240 Prefs.patternsbackupinterval = 24;
241
242 let backupFile = filterStorage.getBackupName(1);
243 let backupFile2 = filterStorage.getBackupName(2);
244 let backupFile3 = filterStorage.getBackupName(3);
245
246 let oldModifiedTime;
247
248 try
249 {
250 await filterStorage.saveToDisk();
251
252 // Save again immediately
253 await filterStorage.saveToDisk();
254
255 test.ok(IO._getFileContents(backupFile), "First backup created");
256
257 oldModifiedTime = IO._getModifiedTime(backupFile) - 10000;
258 IO._setModifiedTime(backupFile, oldModifiedTime);
259 await filterStorage.saveToDisk();
260
261 test.equal(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup not ove rwritten if it is only 10 seconds old");
262
263 oldModifiedTime -= 40 * 60 * 60 * 1000;
264 IO._setModifiedTime(backupFile, oldModifiedTime);
265 await filterStorage.saveToDisk();
266
267 test.notEqual(IO._getModifiedTime(backupFile), oldModifiedTime, "Backup over written if it is 40 hours old");
268
269 test.ok(IO._getFileContents(backupFile2), "Second backup created when first backup is overwritten");
270
271 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 20000);
272 oldModifiedTime = IO._getModifiedTime(backupFile2);
273 await filterStorage.saveToDisk();
274
275 test.equal(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second backup not overwritten if first one is only 20 seconds old");
276
277 IO._setModifiedTime(backupFile, IO._getModifiedTime(backupFile) - 25 * 60 * 60 * 1000);
278 oldModifiedTime = IO._getModifiedTime(backupFile2);
279 await filterStorage.saveToDisk();
280
281 test.notEqual(IO._getModifiedTime(backupFile2), oldModifiedTime, "Second bac kup overwritten if first one is 25 hours old");
282
283 test.ok(!IO._getFileContents(backupFile3), "Third backup not created with pa tternsbackups = 2");
284 }
285 catch (error)
286 {
287 unexpectedError.call(test, error);
288 }
289
290 test.done();
291 };
292
293 exports.testRestoringBackup = async function(test)
294 {
295 Prefs.patternsbackups = 2;
296 Prefs.patternsbackupinterval = 24;
297
298 try
299 {
300 await filterStorage.saveToDisk();
301
302 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Initial fi lter count");
303 filterStorage.addFilter(Filter.fromText("barfoo"));
304 test.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filter cou nt after adding a filter");
305 await filterStorage.saveToDisk();
306
307 await filterStorage.loadFromDisk();
308
309 test.equal([...filterStorage.subscriptions()][0].filterCount, 2, "Filter cou nt after adding filter and reloading");
310 await filterStorage.restoreBackup(1);
311
312 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filter cou nt after restoring backup");
313 await filterStorage.loadFromDisk();
314
315 test.equal([...filterStorage.subscriptions()][0].filterCount, 1, "Filter cou nt after reloading");
316 }
317 catch (error)
318 {
319 unexpectedError.call(test, error);
320 }
321
322 test.done();
323 };
OLDNEW
« no previous file with comments | « test/filterStorage.js ('k') | test/matcher.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld