michael@0: michael@0: /** michael@0: * DummyCompleter() lets tests easily specify the results of a partial michael@0: * hash completion request. michael@0: */ michael@0: function DummyCompleter() { michael@0: this.fragments = {}; michael@0: this.queries = []; michael@0: this.tableName = "test-phish-simple"; michael@0: } michael@0: michael@0: DummyCompleter.prototype = michael@0: { michael@0: QueryInterface: function(iid) michael@0: { michael@0: if (!iid.equals(Ci.nsISupports) && michael@0: !iid.equals(Ci.nsIUrlClassifierHashCompleter)) { michael@0: throw Cr.NS_ERROR_NO_INTERFACE; michael@0: } michael@0: return this; michael@0: }, michael@0: michael@0: complete: function(partialHash, cb) michael@0: { michael@0: this.queries.push(partialHash); michael@0: var fragments = this.fragments; michael@0: var self = this; michael@0: var doCallback = function() { michael@0: if (self.alwaysFail) { michael@0: cb.completionFinished(1); michael@0: return; michael@0: } michael@0: var results; michael@0: if (fragments[partialHash]) { michael@0: for (var i = 0; i < fragments[partialHash].length; i++) { michael@0: var chunkId = fragments[partialHash][i][0]; michael@0: var hash = fragments[partialHash][i][1]; michael@0: cb.completion(hash, self.tableName, chunkId); michael@0: } michael@0: } michael@0: cb.completionFinished(0); michael@0: } michael@0: var timer = new Timer(0, doCallback); michael@0: }, michael@0: michael@0: getHash: function(fragment) michael@0: { michael@0: var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. michael@0: createInstance(Ci.nsIScriptableUnicodeConverter); michael@0: converter.charset = "UTF-8"; michael@0: var data = converter.convertToByteArray(fragment); michael@0: var ch = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash); michael@0: ch.init(ch.SHA256); michael@0: ch.update(data, data.length); michael@0: var hash = ch.finish(false); michael@0: return hash.slice(0, 32); michael@0: }, michael@0: michael@0: addFragment: function(chunkId, fragment) michael@0: { michael@0: this.addHash(chunkId, this.getHash(fragment)); michael@0: }, michael@0: michael@0: // This method allows the caller to generate complete hashes that match the michael@0: // prefix of a real fragment, but have different complete hashes. michael@0: addConflict: function(chunkId, fragment) michael@0: { michael@0: var realHash = this.getHash(fragment); michael@0: var invalidHash = this.getHash("blah blah blah blah blah"); michael@0: this.addHash(chunkId, realHash.slice(0, 4) + invalidHash.slice(4, 32)); michael@0: }, michael@0: michael@0: addHash: function(chunkId, hash) michael@0: { michael@0: var partial = hash.slice(0, 4); michael@0: if (this.fragments[partial]) { michael@0: this.fragments[partial].push([chunkId, hash]); michael@0: } else { michael@0: this.fragments[partial] = [[chunkId, hash]]; michael@0: } michael@0: }, michael@0: michael@0: compareQueries: function(fragments) michael@0: { michael@0: var expectedQueries = []; michael@0: for (var i = 0; i < fragments.length; i++) { michael@0: expectedQueries.push(this.getHash(fragments[i]).slice(0, 4)); michael@0: } michael@0: do_check_eq(this.queries.length, expectedQueries.length); michael@0: expectedQueries.sort(); michael@0: this.queries.sort(); michael@0: for (var i = 0; i < this.queries.length; i++) { michael@0: do_check_eq(this.queries[i], expectedQueries[i]); michael@0: } michael@0: } michael@0: }; michael@0: michael@0: function setupCompleter(table, hits, conflicts) michael@0: { michael@0: var completer = new DummyCompleter(); michael@0: completer.tableName = table; michael@0: for (var i = 0; i < hits.length; i++) { michael@0: var chunkId = hits[i][0]; michael@0: var fragments = hits[i][1]; michael@0: for (var j = 0; j < fragments.length; j++) { michael@0: completer.addFragment(chunkId, fragments[j]); michael@0: } michael@0: } michael@0: for (var i = 0; i < conflicts.length; i++) { michael@0: var chunkId = conflicts[i][0]; michael@0: var fragments = conflicts[i][1]; michael@0: for (var j = 0; j < fragments.length; j++) { michael@0: completer.addConflict(chunkId, fragments[j]); michael@0: } michael@0: } michael@0: michael@0: dbservice.setHashCompleter(table, completer); michael@0: michael@0: return completer; michael@0: } michael@0: michael@0: function installCompleter(table, fragments, conflictFragments) michael@0: { michael@0: return setupCompleter(table, fragments, conflictFragments); michael@0: } michael@0: michael@0: function installFailingCompleter(table) { michael@0: var completer = setupCompleter(table, [], []); michael@0: completer.alwaysFail = true; michael@0: return completer; michael@0: } michael@0: michael@0: // Helper assertion for checking dummy completer queries michael@0: gAssertions.completerQueried = function(data, cb) michael@0: { michael@0: var completer = data[0]; michael@0: completer.compareQueries(data[1]); michael@0: cb(); michael@0: } michael@0: michael@0: function doTest(updates, assertions) michael@0: { michael@0: doUpdateTest(updates, assertions, runNextTest, updateError); michael@0: } michael@0: michael@0: // Test an add of two partial urls to a fresh database michael@0: function testPartialAdds() { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: function testPartialAddsWithConflicts() { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: // Each result will have both a real match and a conflict michael@0: var completer = installCompleter('test-phish-simple', michael@0: [[1, addUrls]], michael@0: [[1, addUrls]]); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: // Test whether the fragmenting code does not cause duplicated completions michael@0: function testFragments() { michael@0: var addUrls = [ "foo.com/a/b/c", "foo.net/", "foo.com/c/" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: // Test http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec michael@0: // section 6.2 example 1 michael@0: function testSpecFragments() { michael@0: var probeUrls = [ "a.b.c/1/2.html?param=1" ]; michael@0: michael@0: var addUrls = [ "a.b.c/1/2.html", michael@0: "a.b.c/", michael@0: "a.b.c/1/", michael@0: "b.c/1/2.html?param=1", michael@0: "b.c/1/2.html", michael@0: "b.c/", michael@0: "b.c/1/", michael@0: "a.b.c/1/2.html?param=1" ]; michael@0: michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : probeUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: michael@0: } michael@0: michael@0: // Test http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec michael@0: // section 6.2 example 2 michael@0: function testMoreSpecFragments() { michael@0: var probeUrls = [ "a.b.c.d.e.f.g/1.html" ]; michael@0: michael@0: var addUrls = [ "a.b.c.d.e.f.g/1.html", michael@0: "a.b.c.d.e.f.g/", michael@0: "c.d.e.f.g/1.html", michael@0: "c.d.e.f.g/", michael@0: "d.e.f.g/1.html", michael@0: "d.e.f.g/", michael@0: "e.f.g/1.html", michael@0: "e.f.g/", michael@0: "f.g/1.html", michael@0: "f.g/" ]; michael@0: michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : probeUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: michael@0: } michael@0: michael@0: function testFalsePositives() { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: // Each result will have no matching complete hashes and a non-matching michael@0: // conflict michael@0: var completer = installCompleter('test-phish-simple', [], [[1, addUrls]]); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsDontExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: function testEmptyCompleter() { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: // Completer will never return full hashes michael@0: var completer = installCompleter('test-phish-simple', [], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsDontExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: function testCompleterFailure() { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: // Completer will never return full hashes michael@0: var completer = installFailingCompleter('test-phish-simple'); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsDontExist" : addUrls, michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doTest([update], assertions); michael@0: } michael@0: michael@0: function testMixedSizesSameDomain() { michael@0: var add1Urls = [ "foo.com/a" ]; michael@0: var add2Urls = [ "foo.com/b" ]; michael@0: michael@0: var update1 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : add1Urls }], michael@0: 4); michael@0: var update2 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : add2Urls }], michael@0: 32); michael@0: michael@0: // We should only need to complete the partial hashes michael@0: var completer = installCompleter('test-phish-simple', [[1, add1Urls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1-2", michael@0: // both urls should match... michael@0: "urlsExist" : add1Urls.concat(add2Urls), michael@0: // ... but the completer should only be queried for the partial entry michael@0: "completerQueried" : [completer, add1Urls] michael@0: }; michael@0: michael@0: doTest([update1, update2], assertions); michael@0: } michael@0: michael@0: function testMixedSizesDifferentDomains() { michael@0: var add1Urls = [ "foo.com/a" ]; michael@0: var add2Urls = [ "bar.com/b" ]; michael@0: michael@0: var update1 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : add1Urls }], michael@0: 4); michael@0: var update2 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : add2Urls }], michael@0: 32); michael@0: michael@0: // We should only need to complete the partial hashes michael@0: var completer = installCompleter('test-phish-simple', [[1, add1Urls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1-2", michael@0: // both urls should match... michael@0: "urlsExist" : add1Urls.concat(add2Urls), michael@0: // ... but the completer should only be queried for the partial entry michael@0: "completerQueried" : [completer, add1Urls] michael@0: }; michael@0: michael@0: doTest([update1, update2], assertions); michael@0: } michael@0: michael@0: function testInvalidHashSize() michael@0: { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 12); // only 4 and 32 are legal hash sizes michael@0: michael@0: var addUrls2 = [ "zaz.com/a", "xyz.com/b" ]; michael@0: var update2 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : addUrls2 michael@0: }], michael@0: 4); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:2", michael@0: "urlsDontExist" : addUrls michael@0: }; michael@0: michael@0: // A successful update will trigger an error michael@0: doUpdateTest([update2, update], assertions, updateError, runNextTest); michael@0: } michael@0: michael@0: function testWrongTable() michael@0: { michael@0: var addUrls = [ "foo.com/a" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: var completer = installCompleter('test-malware-simple', // wrong table michael@0: [[1, addUrls]], []); michael@0: michael@0: // The above installCompleter installs the completer for test-malware-simple, michael@0: // we want it to be used for test-phish-simple too. michael@0: dbservice.setHashCompleter("test-phish-simple", completer); michael@0: michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: // The urls were added as phishing urls, but the completer is claiming michael@0: // that they are malware urls, and we trust the completer in this case. michael@0: // The result will be discarded, so we can only check for non-existence. michael@0: "urlsDontExist" : addUrls, michael@0: // Make sure the completer was actually queried. michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doUpdateTest([update], assertions, michael@0: function() { michael@0: // Give the dbservice a chance to (not) cache the result. michael@0: var timer = new Timer(3000, function() { michael@0: // The miss earlier will have caused a miss to be cached. michael@0: // Resetting the completer does not count as an update, michael@0: // so we will not be probed again. michael@0: var newCompleter = installCompleter('test-malware-simple', [[1, addUrls]], []); dbservice.setHashCompleter("test-phish-simple", michael@0: newCompleter); michael@0: michael@0: var assertions = { michael@0: "urlsDontExist" : addUrls michael@0: }; michael@0: checkAssertions(assertions, runNextTest); michael@0: }); michael@0: }, updateError); michael@0: } michael@0: michael@0: function setupCachedResults(addUrls, part2) michael@0: { michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: // Request the add url. This should cause the completion to be cached. michael@0: "urlsExist" : addUrls, michael@0: // Make sure the completer was actually queried. michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: doUpdateTest([update], assertions, michael@0: function() { michael@0: // Give the dbservice a chance to cache the result. michael@0: var timer = new Timer(3000, part2); michael@0: }, updateError); michael@0: } michael@0: michael@0: function testCachedResults() michael@0: { michael@0: setupCachedResults(["foo.com/a"], function(add) { michael@0: // This is called after setupCachedResults(). Verify that michael@0: // checking the url again does not cause a completer request. michael@0: michael@0: // install a new completer, this one should never be queried. michael@0: var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); michael@0: michael@0: var assertions = { michael@0: "urlsExist" : ["foo.com/a"], michael@0: "completerQueried" : [newCompleter, []] michael@0: }; michael@0: checkAssertions(assertions, runNextTest); michael@0: }); michael@0: } michael@0: michael@0: function testCachedResultsWithSub() { michael@0: setupCachedResults(["foo.com/a"], function() { michael@0: // install a new completer, this one should never be queried. michael@0: var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); michael@0: michael@0: var removeUpdate = buildPhishingUpdate( michael@0: [ { "chunkNum" : 2, michael@0: "chunkType" : "s", michael@0: "urls": ["1:foo.com/a"] }], michael@0: 4); michael@0: michael@0: var assertions = { michael@0: "urlsDontExist" : ["foo.com/a"], michael@0: "completerQueried" : [newCompleter, []] michael@0: } michael@0: michael@0: doTest([removeUpdate], assertions); michael@0: }); michael@0: } michael@0: michael@0: function testCachedResultsWithExpire() { michael@0: setupCachedResults(["foo.com/a"], function() { michael@0: // install a new completer, this one should never be queried. michael@0: var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); michael@0: michael@0: var expireUpdate = michael@0: "n:1000\n" + michael@0: "i:test-phish-simple\n" + michael@0: "ad:1\n"; michael@0: michael@0: var assertions = { michael@0: "urlsDontExist" : ["foo.com/a"], michael@0: "completerQueried" : [newCompleter, []] michael@0: } michael@0: doTest([expireUpdate], assertions); michael@0: }); michael@0: } michael@0: michael@0: function testCachedResultsUpdate() michael@0: { michael@0: var existUrls = ["foo.com/a"]; michael@0: setupCachedResults(existUrls, function() { michael@0: // This is called after setupCachedResults(). Verify that michael@0: // checking the url again does not cause a completer request. michael@0: michael@0: // install a new completer, this one should never be queried. michael@0: var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); michael@0: michael@0: var assertions = { michael@0: "urlsExist" : existUrls, michael@0: "completerQueried" : [newCompleter, []] michael@0: }; michael@0: michael@0: var addUrls = ["foobar.org/a"]; michael@0: michael@0: var update2 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: checkAssertions(assertions, function () { michael@0: // Apply the update. The cached completes should be gone. michael@0: doStreamUpdate(update2, function() { michael@0: // Now the completer gets queried again. michael@0: var newCompleter2 = installCompleter('test-phish-simple', [[1, existUrls]], []); michael@0: var assertions2 = { michael@0: "tableData" : "test-phish-simple;a:1-2", michael@0: "urlsExist" : existUrls, michael@0: "completerQueried" : [newCompleter2, existUrls] michael@0: }; michael@0: checkAssertions(assertions2, runNextTest); michael@0: }, updateError); michael@0: }); michael@0: }); michael@0: } michael@0: michael@0: function testCachedResultsFailure() michael@0: { michael@0: var existUrls = ["foo.com/a"]; michael@0: setupCachedResults(existUrls, function() { michael@0: // This is called after setupCachedResults(). Verify that michael@0: // checking the url again does not cause a completer request. michael@0: michael@0: // install a new completer, this one should never be queried. michael@0: var newCompleter = installCompleter('test-phish-simple', [[1, []]], []); michael@0: michael@0: var assertions = { michael@0: "urlsExist" : existUrls, michael@0: "completerQueried" : [newCompleter, []] michael@0: }; michael@0: michael@0: var addUrls = ["foobar.org/a"]; michael@0: michael@0: var update2 = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: michael@0: checkAssertions(assertions, function() { michael@0: // Apply the update. The cached completes should be gone. michael@0: doErrorUpdate("test-phish-simple,test-malware-simple", function() { michael@0: // Now the completer gets queried again. michael@0: var newCompleter2 = installCompleter('test-phish-simple', [[1, existUrls]], []); michael@0: var assertions2 = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : existUrls, michael@0: "completerQueried" : [newCompleter2, existUrls] michael@0: }; michael@0: checkAssertions(assertions2, runNextTest); michael@0: }, updateError); michael@0: }); michael@0: }); michael@0: } michael@0: michael@0: function testErrorList() michael@0: { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 4); michael@0: // The update failure should will kill the completes, so the above michael@0: // must be a prefix to get any hit at all past the update failure. michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : addUrls, michael@0: // These are complete urls, and will only be completed if the michael@0: // list is stale. michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: // Apply the update. michael@0: doStreamUpdate(update, function() { michael@0: // Now the test-phish-simple and test-malware-simple tables are marked michael@0: // as fresh. Fake an update failure to mark them stale. michael@0: doErrorUpdate("test-phish-simple,test-malware-simple", function() { michael@0: // Now the lists should be marked stale. Check assertions. michael@0: checkAssertions(assertions, runNextTest); michael@0: }, updateError); michael@0: }, updateError); michael@0: } michael@0: michael@0: michael@0: function testStaleList() michael@0: { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 32); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, addUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: "urlsExist" : addUrls, michael@0: // These are complete urls, and will only be completed if the michael@0: // list is stale. michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: // Consider a match stale after one second. michael@0: prefBranch.setIntPref("urlclassifier.max-complete-age", 1); michael@0: michael@0: // Apply the update. michael@0: doStreamUpdate(update, function() { michael@0: // Now the test-phish-simple and test-malware-simple tables are marked michael@0: // as fresh. Wait three seconds to make sure the list is marked stale. michael@0: new Timer(3000, function() { michael@0: // Now the lists should be marked stale. Check assertions. michael@0: checkAssertions(assertions, function() { michael@0: prefBranch.setIntPref("urlclassifier.max-complete-age", 2700); michael@0: runNextTest(); michael@0: }); michael@0: }, updateError); michael@0: }, updateError); michael@0: } michael@0: michael@0: // Same as testStaleList, but verifies that an empty response still michael@0: // unconfirms the entry. michael@0: function testStaleListEmpty() michael@0: { michael@0: var addUrls = [ "foo.com/a", "foo.com/b", "bar.com/c" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : addUrls michael@0: }], michael@0: 32); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-phish-simple;a:1", michael@0: // None of these should match, because they won't be completed michael@0: "urlsDontExist" : addUrls, michael@0: // These are complete urls, and will only be completed if the michael@0: // list is stale. michael@0: "completerQueried" : [completer, addUrls] michael@0: }; michael@0: michael@0: // Consider a match stale after one second. michael@0: prefBranch.setIntPref("urlclassifier.max-complete-age", 1); michael@0: michael@0: // Apply the update. michael@0: doStreamUpdate(update, function() { michael@0: // Now the test-phish-simple and test-malware-simple tables are marked michael@0: // as fresh. Wait three seconds to make sure the list is marked stale. michael@0: new Timer(3000, function() { michael@0: // Now the lists should be marked stale. Check assertions. michael@0: checkAssertions(assertions, function() { michael@0: prefBranch.setIntPref("urlclassifier.max-complete-age", 2700); michael@0: runNextTest(); michael@0: }); michael@0: }, updateError); michael@0: }, updateError); michael@0: } michael@0: michael@0: michael@0: // Verify that different lists (test-phish-simple, michael@0: // test-malware-simple) maintain their freshness separately. michael@0: function testErrorListIndependent() michael@0: { michael@0: var phishUrls = [ "phish.com/a" ]; michael@0: var malwareUrls = [ "attack.com/a" ]; michael@0: var update = buildPhishingUpdate( michael@0: [ michael@0: { "chunkNum" : 1, michael@0: "urls" : phishUrls michael@0: }], michael@0: 4); michael@0: // These have to persist past the update failure, so they must be prefixes, michael@0: // not completes. michael@0: michael@0: update += buildMalwareUpdate( michael@0: [ michael@0: { "chunkNum" : 2, michael@0: "urls" : malwareUrls michael@0: }], michael@0: 32); michael@0: michael@0: var completer = installCompleter('test-phish-simple', [[1, phishUrls]], []); michael@0: michael@0: var assertions = { michael@0: "tableData" : "test-malware-simple;a:2\ntest-phish-simple;a:1", michael@0: "urlsExist" : phishUrls, michael@0: "malwareUrlsExist" : malwareUrls, michael@0: // Only this phishing urls should be completed, because only the phishing michael@0: // urls will be stale. michael@0: "completerQueried" : [completer, phishUrls] michael@0: }; michael@0: michael@0: // Apply the update. michael@0: doStreamUpdate(update, function() { michael@0: // Now the test-phish-simple and test-malware-simple tables are michael@0: // marked as fresh. Fake an update failure to mark *just* michael@0: // phishing data as stale. michael@0: doErrorUpdate("test-phish-simple", function() { michael@0: // Now the lists should be marked stale. Check assertions. michael@0: checkAssertions(assertions, runNextTest); michael@0: }, updateError); michael@0: }, updateError); michael@0: } michael@0: michael@0: function run_test() michael@0: { michael@0: runTests([ michael@0: testPartialAdds, michael@0: testPartialAddsWithConflicts, michael@0: testFragments, michael@0: testSpecFragments, michael@0: testMoreSpecFragments, michael@0: testFalsePositives, michael@0: testEmptyCompleter, michael@0: testCompleterFailure, michael@0: testMixedSizesSameDomain, michael@0: testMixedSizesDifferentDomains, michael@0: testInvalidHashSize, michael@0: testWrongTable, michael@0: testCachedResults, michael@0: testCachedResultsWithSub, michael@0: testCachedResultsWithExpire, michael@0: testCachedResultsUpdate, michael@0: testCachedResultsFailure, michael@0: testStaleList, michael@0: testStaleListEmpty, michael@0: testErrorList, michael@0: testErrorListIndependent michael@0: ]); michael@0: } michael@0: michael@0: do_test_pending();