toolkit/components/url-classifier/tests/unit/test_partial.js

changeset 0
6474c204b198
     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();

mercurial