1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/url-classifier/tests/unit/test_partial.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,825 @@ 1.4 + 1.5 +/** 1.6 + * DummyCompleter() lets tests easily specify the results of a partial 1.7 + * hash completion request. 1.8 + */ 1.9 +function DummyCompleter() { 1.10 + this.fragments = {}; 1.11 + this.queries = []; 1.12 + this.tableName = "test-phish-simple"; 1.13 +} 1.14 + 1.15 +DummyCompleter.prototype = 1.16 +{ 1.17 +QueryInterface: function(iid) 1.18 +{ 1.19 + if (!iid.equals(Ci.nsISupports) && 1.20 + !iid.equals(Ci.nsIUrlClassifierHashCompleter)) { 1.21 + throw Cr.NS_ERROR_NO_INTERFACE; 1.22 + } 1.23 + return this; 1.24 +}, 1.25 + 1.26 +complete: function(partialHash, cb) 1.27 +{ 1.28 + this.queries.push(partialHash); 1.29 + var fragments = this.fragments; 1.30 + var self = this; 1.31 + var doCallback = function() { 1.32 + if (self.alwaysFail) { 1.33 + cb.completionFinished(1); 1.34 + return; 1.35 + } 1.36 + var results; 1.37 + if (fragments[partialHash]) { 1.38 + for (var i = 0; i < fragments[partialHash].length; i++) { 1.39 + var chunkId = fragments[partialHash][i][0]; 1.40 + var hash = fragments[partialHash][i][1]; 1.41 + cb.completion(hash, self.tableName, chunkId); 1.42 + } 1.43 + } 1.44 + cb.completionFinished(0); 1.45 + } 1.46 + var timer = new Timer(0, doCallback); 1.47 +}, 1.48 + 1.49 +getHash: function(fragment) 1.50 +{ 1.51 + var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. 1.52 + createInstance(Ci.nsIScriptableUnicodeConverter); 1.53 + converter.charset = "UTF-8"; 1.54 + var data = converter.convertToByteArray(fragment); 1.55 + var ch = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash); 1.56 + ch.init(ch.SHA256); 1.57 + ch.update(data, data.length); 1.58 + var hash = ch.finish(false); 1.59 + return hash.slice(0, 32); 1.60 +}, 1.61 + 1.62 +addFragment: function(chunkId, fragment) 1.63 +{ 1.64 + this.addHash(chunkId, this.getHash(fragment)); 1.65 +}, 1.66 + 1.67 +// This method allows the caller to generate complete hashes that match the 1.68 +// prefix of a real fragment, but have different complete hashes. 1.69 +addConflict: function(chunkId, fragment) 1.70 +{ 1.71 + var realHash = this.getHash(fragment); 1.72 + var invalidHash = this.getHash("blah blah blah blah blah"); 1.73 + this.addHash(chunkId, realHash.slice(0, 4) + invalidHash.slice(4, 32)); 1.74 +}, 1.75 + 1.76 +addHash: function(chunkId, hash) 1.77 +{ 1.78 + var partial = hash.slice(0, 4); 1.79 + if (this.fragments[partial]) { 1.80 + this.fragments[partial].push([chunkId, hash]); 1.81 + } else { 1.82 + this.fragments[partial] = [[chunkId, hash]]; 1.83 + } 1.84 +}, 1.85 + 1.86 +compareQueries: function(fragments) 1.87 +{ 1.88 + var expectedQueries = []; 1.89 + for (var i = 0; i < fragments.length; i++) { 1.90 + expectedQueries.push(this.getHash(fragments[i]).slice(0, 4)); 1.91 + } 1.92 + do_check_eq(this.queries.length, expectedQueries.length); 1.93 + expectedQueries.sort(); 1.94 + this.queries.sort(); 1.95 + for (var i = 0; i < this.queries.length; i++) { 1.96 + do_check_eq(this.queries[i], expectedQueries[i]); 1.97 + } 1.98 +} 1.99 +}; 1.100 + 1.101 +function setupCompleter(table, hits, conflicts) 1.102 +{ 1.103 + var completer = new DummyCompleter(); 1.104 + completer.tableName = table; 1.105 + for (var i = 0; i < hits.length; i++) { 1.106 + var chunkId = hits[i][0]; 1.107 + var fragments = hits[i][1]; 1.108 + for (var j = 0; j < fragments.length; j++) { 1.109 + completer.addFragment(chunkId, fragments[j]); 1.110 + } 1.111 + } 1.112 + for (var i = 0; i < conflicts.length; i++) { 1.113 + var chunkId = conflicts[i][0]; 1.114 + var fragments = conflicts[i][1]; 1.115 + for (var j = 0; j < fragments.length; j++) { 1.116 + completer.addConflict(chunkId, fragments[j]); 1.117 + } 1.118 + } 1.119 + 1.120 + dbservice.setHashCompleter(table, completer); 1.121 + 1.122 + return completer; 1.123 +} 1.124 + 1.125 +function installCompleter(table, fragments, conflictFragments) 1.126 +{ 1.127 + return setupCompleter(table, fragments, conflictFragments); 1.128 +} 1.129 + 1.130 +function installFailingCompleter(table) { 1.131 + var completer = setupCompleter(table, [], []); 1.132 + completer.alwaysFail = true; 1.133 + return completer; 1.134 +} 1.135 + 1.136 +// Helper assertion for checking dummy completer queries 1.137 +gAssertions.completerQueried = function(data, cb) 1.138 +{ 1.139 + var completer = data[0]; 1.140 + completer.compareQueries(data[1]); 1.141 + cb(); 1.142 +} 1.143 + 1.144 +function doTest(updates, assertions) 1.145 +{ 1.146 + doUpdateTest(updates, assertions, runNextTest, updateError); 1.147 +} 1.148 + 1.149 +// Test an add of two partial urls to a fresh database 1.150 +function testPartialAdds() { 1.151 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.152 + var update = buildPhishingUpdate( 1.153 + [ 1.154 + { "chunkNum" : 1, 1.155 + "urls" : addUrls 1.156 + }], 1.157 + 4); 1.158 + 1.159 + 1.160 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.161 + 1.162 + var assertions = { 1.163 + "tableData" : "test-phish-simple;a:1", 1.164 + "urlsExist" : addUrls, 1.165 + "completerQueried" : [completer, addUrls] 1.166 + }; 1.167 + 1.168 + 1.169 + doTest([update], assertions); 1.170 +} 1.171 + 1.172 +function testPartialAddsWithConflicts() { 1.173 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.174 + var update = buildPhishingUpdate( 1.175 + [ 1.176 + { "chunkNum" : 1, 1.177 + "urls" : addUrls 1.178 + }], 1.179 + 4); 1.180 + 1.181 + // Each result will have both a real match and a conflict 1.182 + var completer = installCompleter('test-phish-simple', 1.183 + [[1, addUrls]], 1.184 + [[1, addUrls]]); 1.185 + 1.186 + var assertions = { 1.187 + "tableData" : "test-phish-simple;a:1", 1.188 + "urlsExist" : addUrls, 1.189 + "completerQueried" : [completer, addUrls] 1.190 + }; 1.191 + 1.192 + doTest([update], assertions); 1.193 +} 1.194 + 1.195 +// Test whether the fragmenting code does not cause duplicated completions 1.196 +function testFragments() { 1.197 + var addUrls = [ "foo.com/a/b/c", "foo.net/", "foo.com/c/" ]; 1.198 + var update = buildPhishingUpdate( 1.199 + [ 1.200 + { "chunkNum" : 1, 1.201 + "urls" : addUrls 1.202 + }], 1.203 + 4); 1.204 + 1.205 + 1.206 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.207 + 1.208 + var assertions = { 1.209 + "tableData" : "test-phish-simple;a:1", 1.210 + "urlsExist" : addUrls, 1.211 + "completerQueried" : [completer, addUrls] 1.212 + }; 1.213 + 1.214 + 1.215 + doTest([update], assertions); 1.216 +} 1.217 + 1.218 +// Test http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec 1.219 +// section 6.2 example 1 1.220 +function testSpecFragments() { 1.221 + var probeUrls = [ "a.b.c/1/2.html?param=1" ]; 1.222 + 1.223 + var addUrls = [ "a.b.c/1/2.html", 1.224 + "a.b.c/", 1.225 + "a.b.c/1/", 1.226 + "b.c/1/2.html?param=1", 1.227 + "b.c/1/2.html", 1.228 + "b.c/", 1.229 + "b.c/1/", 1.230 + "a.b.c/1/2.html?param=1" ]; 1.231 + 1.232 + var update = buildPhishingUpdate( 1.233 + [ 1.234 + { "chunkNum" : 1, 1.235 + "urls" : addUrls 1.236 + }], 1.237 + 4); 1.238 + 1.239 + 1.240 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.241 + 1.242 + var assertions = { 1.243 + "tableData" : "test-phish-simple;a:1", 1.244 + "urlsExist" : probeUrls, 1.245 + "completerQueried" : [completer, addUrls] 1.246 + }; 1.247 + 1.248 + doTest([update], assertions); 1.249 + 1.250 +} 1.251 + 1.252 +// Test http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec 1.253 +// section 6.2 example 2 1.254 +function testMoreSpecFragments() { 1.255 + var probeUrls = [ "a.b.c.d.e.f.g/1.html" ]; 1.256 + 1.257 + var addUrls = [ "a.b.c.d.e.f.g/1.html", 1.258 + "a.b.c.d.e.f.g/", 1.259 + "c.d.e.f.g/1.html", 1.260 + "c.d.e.f.g/", 1.261 + "d.e.f.g/1.html", 1.262 + "d.e.f.g/", 1.263 + "e.f.g/1.html", 1.264 + "e.f.g/", 1.265 + "f.g/1.html", 1.266 + "f.g/" ]; 1.267 + 1.268 + var update = buildPhishingUpdate( 1.269 + [ 1.270 + { "chunkNum" : 1, 1.271 + "urls" : addUrls 1.272 + }], 1.273 + 4); 1.274 + 1.275 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.276 + 1.277 + var assertions = { 1.278 + "tableData" : "test-phish-simple;a:1", 1.279 + "urlsExist" : probeUrls, 1.280 + "completerQueried" : [completer, addUrls] 1.281 + }; 1.282 + 1.283 + doTest([update], assertions); 1.284 + 1.285 +} 1.286 + 1.287 +function testFalsePositives() { 1.288 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.289 + var update = buildPhishingUpdate( 1.290 + [ 1.291 + { "chunkNum" : 1, 1.292 + "urls" : addUrls 1.293 + }], 1.294 + 4); 1.295 + 1.296 + // Each result will have no matching complete hashes and a non-matching 1.297 + // conflict 1.298 + var completer = installCompleter('test-phish-simple', [], [[1, addUrls]]); 1.299 + 1.300 + var assertions = { 1.301 + "tableData" : "test-phish-simple;a:1", 1.302 + "urlsDontExist" : addUrls, 1.303 + "completerQueried" : [completer, addUrls] 1.304 + }; 1.305 + 1.306 + doTest([update], assertions); 1.307 +} 1.308 + 1.309 +function testEmptyCompleter() { 1.310 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.311 + var update = buildPhishingUpdate( 1.312 + [ 1.313 + { "chunkNum" : 1, 1.314 + "urls" : addUrls 1.315 + }], 1.316 + 4); 1.317 + 1.318 + // Completer will never return full hashes 1.319 + var completer = installCompleter('test-phish-simple', [], []); 1.320 + 1.321 + var assertions = { 1.322 + "tableData" : "test-phish-simple;a:1", 1.323 + "urlsDontExist" : addUrls, 1.324 + "completerQueried" : [completer, addUrls] 1.325 + }; 1.326 + 1.327 + doTest([update], assertions); 1.328 +} 1.329 + 1.330 +function testCompleterFailure() { 1.331 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.332 + var update = buildPhishingUpdate( 1.333 + [ 1.334 + { "chunkNum" : 1, 1.335 + "urls" : addUrls 1.336 + }], 1.337 + 4); 1.338 + 1.339 + // Completer will never return full hashes 1.340 + var completer = installFailingCompleter('test-phish-simple'); 1.341 + 1.342 + var assertions = { 1.343 + "tableData" : "test-phish-simple;a:1", 1.344 + "urlsDontExist" : addUrls, 1.345 + "completerQueried" : [completer, addUrls] 1.346 + }; 1.347 + 1.348 + doTest([update], assertions); 1.349 +} 1.350 + 1.351 +function testMixedSizesSameDomain() { 1.352 + var add1Urls = [ "foo.com/a" ]; 1.353 + var add2Urls = [ "foo.com/b" ]; 1.354 + 1.355 + var update1 = buildPhishingUpdate( 1.356 + [ 1.357 + { "chunkNum" : 1, 1.358 + "urls" : add1Urls }], 1.359 + 4); 1.360 + var update2 = buildPhishingUpdate( 1.361 + [ 1.362 + { "chunkNum" : 2, 1.363 + "urls" : add2Urls }], 1.364 + 32); 1.365 + 1.366 + // We should only need to complete the partial hashes 1.367 + var completer = installCompleter('test-phish-simple', [[1, add1Urls]], []); 1.368 + 1.369 + var assertions = { 1.370 + "tableData" : "test-phish-simple;a:1-2", 1.371 + // both urls should match... 1.372 + "urlsExist" : add1Urls.concat(add2Urls), 1.373 + // ... but the completer should only be queried for the partial entry 1.374 + "completerQueried" : [completer, add1Urls] 1.375 + }; 1.376 + 1.377 + doTest([update1, update2], assertions); 1.378 +} 1.379 + 1.380 +function testMixedSizesDifferentDomains() { 1.381 + var add1Urls = [ "foo.com/a" ]; 1.382 + var add2Urls = [ "bar.com/b" ]; 1.383 + 1.384 + var update1 = buildPhishingUpdate( 1.385 + [ 1.386 + { "chunkNum" : 1, 1.387 + "urls" : add1Urls }], 1.388 + 4); 1.389 + var update2 = buildPhishingUpdate( 1.390 + [ 1.391 + { "chunkNum" : 2, 1.392 + "urls" : add2Urls }], 1.393 + 32); 1.394 + 1.395 + // We should only need to complete the partial hashes 1.396 + var completer = installCompleter('test-phish-simple', [[1, add1Urls]], []); 1.397 + 1.398 + var assertions = { 1.399 + "tableData" : "test-phish-simple;a:1-2", 1.400 + // both urls should match... 1.401 + "urlsExist" : add1Urls.concat(add2Urls), 1.402 + // ... but the completer should only be queried for the partial entry 1.403 + "completerQueried" : [completer, add1Urls] 1.404 + }; 1.405 + 1.406 + doTest([update1, update2], assertions); 1.407 +} 1.408 + 1.409 +function testInvalidHashSize() 1.410 +{ 1.411 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.412 + var update = buildPhishingUpdate( 1.413 + [ 1.414 + { "chunkNum" : 1, 1.415 + "urls" : addUrls 1.416 + }], 1.417 + 12); // only 4 and 32 are legal hash sizes 1.418 + 1.419 + var addUrls2 = [ "zaz.com/a", "xyz.com/b" ]; 1.420 + var update2 = buildPhishingUpdate( 1.421 + [ 1.422 + { "chunkNum" : 2, 1.423 + "urls" : addUrls2 1.424 + }], 1.425 + 4); 1.426 + 1.427 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.428 + 1.429 + var assertions = { 1.430 + "tableData" : "test-phish-simple;a:2", 1.431 + "urlsDontExist" : addUrls 1.432 + }; 1.433 + 1.434 + // A successful update will trigger an error 1.435 + doUpdateTest([update2, update], assertions, updateError, runNextTest); 1.436 +} 1.437 + 1.438 +function testWrongTable() 1.439 +{ 1.440 + var addUrls = [ "foo.com/a" ]; 1.441 + var update = buildPhishingUpdate( 1.442 + [ 1.443 + { "chunkNum" : 1, 1.444 + "urls" : addUrls 1.445 + }], 1.446 + 4); 1.447 + var completer = installCompleter('test-malware-simple', // wrong table 1.448 + [[1, addUrls]], []); 1.449 + 1.450 + // The above installCompleter installs the completer for test-malware-simple, 1.451 + // we want it to be used for test-phish-simple too. 1.452 + dbservice.setHashCompleter("test-phish-simple", completer); 1.453 + 1.454 + 1.455 + var assertions = { 1.456 + "tableData" : "test-phish-simple;a:1", 1.457 + // The urls were added as phishing urls, but the completer is claiming 1.458 + // that they are malware urls, and we trust the completer in this case. 1.459 + // The result will be discarded, so we can only check for non-existence. 1.460 + "urlsDontExist" : addUrls, 1.461 + // Make sure the completer was actually queried. 1.462 + "completerQueried" : [completer, addUrls] 1.463 + }; 1.464 + 1.465 + doUpdateTest([update], assertions, 1.466 + function() { 1.467 + // Give the dbservice a chance to (not) cache the result. 1.468 + var timer = new Timer(3000, function() { 1.469 + // The miss earlier will have caused a miss to be cached. 1.470 + // Resetting the completer does not count as an update, 1.471 + // so we will not be probed again. 1.472 + var newCompleter = installCompleter('test-malware-simple', [[1, addUrls]], []); dbservice.setHashCompleter("test-phish-simple", 1.473 + newCompleter); 1.474 + 1.475 + var assertions = { 1.476 + "urlsDontExist" : addUrls 1.477 + }; 1.478 + checkAssertions(assertions, runNextTest); 1.479 + }); 1.480 + }, updateError); 1.481 +} 1.482 + 1.483 +function setupCachedResults(addUrls, part2) 1.484 +{ 1.485 + var update = buildPhishingUpdate( 1.486 + [ 1.487 + { "chunkNum" : 1, 1.488 + "urls" : addUrls 1.489 + }], 1.490 + 4); 1.491 + 1.492 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.493 + 1.494 + var assertions = { 1.495 + "tableData" : "test-phish-simple;a:1", 1.496 + // Request the add url. This should cause the completion to be cached. 1.497 + "urlsExist" : addUrls, 1.498 + // Make sure the completer was actually queried. 1.499 + "completerQueried" : [completer, addUrls] 1.500 + }; 1.501 + 1.502 + doUpdateTest([update], assertions, 1.503 + function() { 1.504 + // Give the dbservice a chance to cache the result. 1.505 + var timer = new Timer(3000, part2); 1.506 + }, updateError); 1.507 +} 1.508 + 1.509 +function testCachedResults() 1.510 +{ 1.511 + setupCachedResults(["foo.com/a"], function(add) { 1.512 + // This is called after setupCachedResults(). Verify that 1.513 + // checking the url again does not cause a completer request. 1.514 + 1.515 + // install a new completer, this one should never be queried. 1.516 + var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); 1.517 + 1.518 + var assertions = { 1.519 + "urlsExist" : ["foo.com/a"], 1.520 + "completerQueried" : [newCompleter, []] 1.521 + }; 1.522 + checkAssertions(assertions, runNextTest); 1.523 + }); 1.524 +} 1.525 + 1.526 +function testCachedResultsWithSub() { 1.527 + setupCachedResults(["foo.com/a"], function() { 1.528 + // install a new completer, this one should never be queried. 1.529 + var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); 1.530 + 1.531 + var removeUpdate = buildPhishingUpdate( 1.532 + [ { "chunkNum" : 2, 1.533 + "chunkType" : "s", 1.534 + "urls": ["1:foo.com/a"] }], 1.535 + 4); 1.536 + 1.537 + var assertions = { 1.538 + "urlsDontExist" : ["foo.com/a"], 1.539 + "completerQueried" : [newCompleter, []] 1.540 + } 1.541 + 1.542 + doTest([removeUpdate], assertions); 1.543 + }); 1.544 +} 1.545 + 1.546 +function testCachedResultsWithExpire() { 1.547 + setupCachedResults(["foo.com/a"], function() { 1.548 + // install a new completer, this one should never be queried. 1.549 + var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); 1.550 + 1.551 + var expireUpdate = 1.552 + "n:1000\n" + 1.553 + "i:test-phish-simple\n" + 1.554 + "ad:1\n"; 1.555 + 1.556 + var assertions = { 1.557 + "urlsDontExist" : ["foo.com/a"], 1.558 + "completerQueried" : [newCompleter, []] 1.559 + } 1.560 + doTest([expireUpdate], assertions); 1.561 + }); 1.562 +} 1.563 + 1.564 +function testCachedResultsUpdate() 1.565 +{ 1.566 + var existUrls = ["foo.com/a"]; 1.567 + setupCachedResults(existUrls, function() { 1.568 + // This is called after setupCachedResults(). Verify that 1.569 + // checking the url again does not cause a completer request. 1.570 + 1.571 + // install a new completer, this one should never be queried. 1.572 + var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); 1.573 + 1.574 + var assertions = { 1.575 + "urlsExist" : existUrls, 1.576 + "completerQueried" : [newCompleter, []] 1.577 + }; 1.578 + 1.579 + var addUrls = ["foobar.org/a"]; 1.580 + 1.581 + var update2 = buildPhishingUpdate( 1.582 + [ 1.583 + { "chunkNum" : 2, 1.584 + "urls" : addUrls 1.585 + }], 1.586 + 4); 1.587 + 1.588 + checkAssertions(assertions, function () { 1.589 + // Apply the update. The cached completes should be gone. 1.590 + doStreamUpdate(update2, function() { 1.591 + // Now the completer gets queried again. 1.592 + var newCompleter2 = installCompleter('test-phish-simple', [[1, existUrls]], []); 1.593 + var assertions2 = { 1.594 + "tableData" : "test-phish-simple;a:1-2", 1.595 + "urlsExist" : existUrls, 1.596 + "completerQueried" : [newCompleter2, existUrls] 1.597 + }; 1.598 + checkAssertions(assertions2, runNextTest); 1.599 + }, updateError); 1.600 + }); 1.601 + }); 1.602 +} 1.603 + 1.604 +function testCachedResultsFailure() 1.605 +{ 1.606 + var existUrls = ["foo.com/a"]; 1.607 + setupCachedResults(existUrls, function() { 1.608 + // This is called after setupCachedResults(). Verify that 1.609 + // checking the url again does not cause a completer request. 1.610 + 1.611 + // install a new completer, this one should never be queried. 1.612 + var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); 1.613 + 1.614 + var assertions = { 1.615 + "urlsExist" : existUrls, 1.616 + "completerQueried" : [newCompleter, []] 1.617 + }; 1.618 + 1.619 + var addUrls = ["foobar.org/a"]; 1.620 + 1.621 + var update2 = buildPhishingUpdate( 1.622 + [ 1.623 + { "chunkNum" : 2, 1.624 + "urls" : addUrls 1.625 + }], 1.626 + 4); 1.627 + 1.628 + checkAssertions(assertions, function() { 1.629 + // Apply the update. The cached completes should be gone. 1.630 + doErrorUpdate("test-phish-simple,test-malware-simple", function() { 1.631 + // Now the completer gets queried again. 1.632 + var newCompleter2 = installCompleter('test-phish-simple', [[1, existUrls]], []); 1.633 + var assertions2 = { 1.634 + "tableData" : "test-phish-simple;a:1", 1.635 + "urlsExist" : existUrls, 1.636 + "completerQueried" : [newCompleter2, existUrls] 1.637 + }; 1.638 + checkAssertions(assertions2, runNextTest); 1.639 + }, updateError); 1.640 + }); 1.641 + }); 1.642 +} 1.643 + 1.644 +function testErrorList() 1.645 +{ 1.646 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.647 + var update = buildPhishingUpdate( 1.648 + [ 1.649 + { "chunkNum" : 1, 1.650 + "urls" : addUrls 1.651 + }], 1.652 + 4); 1.653 + // The update failure should will kill the completes, so the above 1.654 + // must be a prefix to get any hit at all past the update failure. 1.655 + 1.656 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.657 + 1.658 + var assertions = { 1.659 + "tableData" : "test-phish-simple;a:1", 1.660 + "urlsExist" : addUrls, 1.661 + // These are complete urls, and will only be completed if the 1.662 + // list is stale. 1.663 + "completerQueried" : [completer, addUrls] 1.664 + }; 1.665 + 1.666 + // Apply the update. 1.667 + doStreamUpdate(update, function() { 1.668 + // Now the test-phish-simple and test-malware-simple tables are marked 1.669 + // as fresh. Fake an update failure to mark them stale. 1.670 + doErrorUpdate("test-phish-simple,test-malware-simple", function() { 1.671 + // Now the lists should be marked stale. Check assertions. 1.672 + checkAssertions(assertions, runNextTest); 1.673 + }, updateError); 1.674 + }, updateError); 1.675 +} 1.676 + 1.677 + 1.678 +function testStaleList() 1.679 +{ 1.680 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.681 + var update = buildPhishingUpdate( 1.682 + [ 1.683 + { "chunkNum" : 1, 1.684 + "urls" : addUrls 1.685 + }], 1.686 + 32); 1.687 + 1.688 + var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); 1.689 + 1.690 + var assertions = { 1.691 + "tableData" : "test-phish-simple;a:1", 1.692 + "urlsExist" : addUrls, 1.693 + // These are complete urls, and will only be completed if the 1.694 + // list is stale. 1.695 + "completerQueried" : [completer, addUrls] 1.696 + }; 1.697 + 1.698 + // Consider a match stale after one second. 1.699 + prefBranch.setIntPref("urlclassifier.max-complete-age", 1); 1.700 + 1.701 + // Apply the update. 1.702 + doStreamUpdate(update, function() { 1.703 + // Now the test-phish-simple and test-malware-simple tables are marked 1.704 + // as fresh. Wait three seconds to make sure the list is marked stale. 1.705 + new Timer(3000, function() { 1.706 + // Now the lists should be marked stale. Check assertions. 1.707 + checkAssertions(assertions, function() { 1.708 + prefBranch.setIntPref("urlclassifier.max-complete-age", 2700); 1.709 + runNextTest(); 1.710 + }); 1.711 + }, updateError); 1.712 + }, updateError); 1.713 +} 1.714 + 1.715 +// Same as testStaleList, but verifies that an empty response still 1.716 +// unconfirms the entry. 1.717 +function testStaleListEmpty() 1.718 +{ 1.719 + var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; 1.720 + var update = buildPhishingUpdate( 1.721 + [ 1.722 + { "chunkNum" : 1, 1.723 + "urls" : addUrls 1.724 + }], 1.725 + 32); 1.726 + 1.727 + var completer = installCompleter('test-phish-simple', [], []); 1.728 + 1.729 + var assertions = { 1.730 + "tableData" : "test-phish-simple;a:1", 1.731 + // None of these should match, because they won't be completed 1.732 + "urlsDontExist" : addUrls, 1.733 + // These are complete urls, and will only be completed if the 1.734 + // list is stale. 1.735 + "completerQueried" : [completer, addUrls] 1.736 + }; 1.737 + 1.738 + // Consider a match stale after one second. 1.739 + prefBranch.setIntPref("urlclassifier.max-complete-age", 1); 1.740 + 1.741 + // Apply the update. 1.742 + doStreamUpdate(update, function() { 1.743 + // Now the test-phish-simple and test-malware-simple tables are marked 1.744 + // as fresh. Wait three seconds to make sure the list is marked stale. 1.745 + new Timer(3000, function() { 1.746 + // Now the lists should be marked stale. Check assertions. 1.747 + checkAssertions(assertions, function() { 1.748 + prefBranch.setIntPref("urlclassifier.max-complete-age", 2700); 1.749 + runNextTest(); 1.750 + }); 1.751 + }, updateError); 1.752 + }, updateError); 1.753 +} 1.754 + 1.755 + 1.756 +// Verify that different lists (test-phish-simple, 1.757 +// test-malware-simple) maintain their freshness separately. 1.758 +function testErrorListIndependent() 1.759 +{ 1.760 + var phishUrls = [ "phish.com/a" ]; 1.761 + var malwareUrls = [ "attack.com/a" ]; 1.762 + var update = buildPhishingUpdate( 1.763 + [ 1.764 + { "chunkNum" : 1, 1.765 + "urls" : phishUrls 1.766 + }], 1.767 + 4); 1.768 + // These have to persist past the update failure, so they must be prefixes, 1.769 + // not completes. 1.770 + 1.771 + update += buildMalwareUpdate( 1.772 + [ 1.773 + { "chunkNum" : 2, 1.774 + "urls" : malwareUrls 1.775 + }], 1.776 + 32); 1.777 + 1.778 + var completer = installCompleter('test-phish-simple', [[1, phishUrls]], []); 1.779 + 1.780 + var assertions = { 1.781 + "tableData" : "test-malware-simple;a:2\ntest-phish-simple;a:1", 1.782 + "urlsExist" : phishUrls, 1.783 + "malwareUrlsExist" : malwareUrls, 1.784 + // Only this phishing urls should be completed, because only the phishing 1.785 + // urls will be stale. 1.786 + "completerQueried" : [completer, phishUrls] 1.787 + }; 1.788 + 1.789 + // Apply the update. 1.790 + doStreamUpdate(update, function() { 1.791 + // Now the test-phish-simple and test-malware-simple tables are 1.792 + // marked as fresh. Fake an update failure to mark *just* 1.793 + // phishing data as stale. 1.794 + doErrorUpdate("test-phish-simple", function() { 1.795 + // Now the lists should be marked stale. Check assertions. 1.796 + checkAssertions(assertions, runNextTest); 1.797 + }, updateError); 1.798 + }, updateError); 1.799 +} 1.800 + 1.801 +function run_test() 1.802 +{ 1.803 + runTests([ 1.804 + testPartialAdds, 1.805 + testPartialAddsWithConflicts, 1.806 + testFragments, 1.807 + testSpecFragments, 1.808 + testMoreSpecFragments, 1.809 + testFalsePositives, 1.810 + testEmptyCompleter, 1.811 + testCompleterFailure, 1.812 + testMixedSizesSameDomain, 1.813 + testMixedSizesDifferentDomains, 1.814 + testInvalidHashSize, 1.815 + testWrongTable, 1.816 + testCachedResults, 1.817 + testCachedResultsWithSub, 1.818 + testCachedResultsWithExpire, 1.819 + testCachedResultsUpdate, 1.820 + testCachedResultsFailure, 1.821 + testStaleList, 1.822 + testStaleListEmpty, 1.823 + testErrorList, 1.824 + testErrorListIndependent 1.825 + ]); 1.826 +} 1.827 + 1.828 +do_test_pending();