Bug 1353458 - Make test_cert_blocklist more flexible about order of lines in revocations.txt. r?keeler draft
authorL. David Baron <dbaron@dbaron.org>
Wed, 03 May 2017 17:51:05 -0700
changeset 572368 72f99eeaa5be8dd5557262ea83a1ed767267d9f6
parent 570708 2fe636103d7167f3a5d57f61bd19fddcc878ca3c
child 626997 3326c457defb86ca620d0a84bcf7c1491be967a4
push id57046
push userdbaron@mozilla.com
push dateThu, 04 May 2017 00:53:23 +0000
reviewerskeeler
bugs1353458
milestone55.0a1
Bug 1353458 - Make test_cert_blocklist more flexible about order of lines in revocations.txt. r?keeler This allows patches to land that will change the hashtable enumeration order, which in turn changes the ordering of the lines in revocations.txt. MozReview-Commit-ID: Fyuahnpky6g
security/manager/ssl/tests/unit/test_cert_blocklist.js
--- a/security/manager/ssl/tests/unit/test_cert_blocklist.js
+++ b/security/manager/ssl/tests/unit/test_cert_blocklist.js
@@ -184,54 +184,99 @@ function fetch_blocklist(blocklistPath) 
   Services.obs.addObserver(certblockObserver, "blocklist-updated");
   Services.prefs.setCharPref("extensions.blocklist.url",
                               `http://localhost:${port}/${blocklistPath}`);
   let blocklist = Cc["@mozilla.org/extensions/blocklist;1"]
                     .getService(Ci.nsITimerCallback);
   blocklist.notify(null);
 }
 
-function check_revocations_txt_contents(expected) {
+function* generate_revocations_txt_lines() {
   let profile = do_get_profile();
   let revocations = profile.clone();
   revocations.append("revocations.txt");
   ok(revocations.exists(), "the revocations file should exist");
   let inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
                       .createInstance(Ci.nsIFileInputStream);
   inputStream.init(revocations, -1, -1, 0);
   inputStream.QueryInterface(Ci.nsILineInputStream);
-  let contents = "";
   let hasmore = false;
   do {
     let line = {};
     hasmore = inputStream.readLine(line);
-    contents += (contents.length == 0 ? "" : "\n") + line.value;
+    yield line.value;
   } while (hasmore);
-  equal(contents, expected, "revocations.txt should be as expected");
+}
+
+// Check that revocations.txt contains, in any order, the lines
+// ("top-level lines") that are the keys in |expected|, each followed
+// immediately by the lines ("sublines") in expected[topLevelLine]
+// (again, in any order).
+function check_revocations_txt_contents(expected) {
+  let lineGenerator = generate_revocations_txt_lines();
+  let firstLine = lineGenerator.next();
+  equal(firstLine.done, false,
+        "first line of revocations.txt should be present");
+  equal(firstLine.value, "# Auto generated contents. Do not edit.",
+        "first line of revocations.txt");
+  let line = lineGenerator.next();
+  let topLevelFound = {};
+  while (true) {
+    if (line.done) {
+      break;
+    }
+
+    ok(line.value in expected,
+       `${line.value} should be an expected top-level line in revocations.txt`);
+    ok(!(line.value in topLevelFound),
+       `should not have seen ${line.value} before in revocations.txt`);
+    topLevelFound[line.value] = true;
+    let topLevelLine = line.value;
+
+    let sublines = expected[line.value];
+    let subFound = {};
+    while (true) {
+      line = lineGenerator.next();
+      if (line.done || !(line.value in sublines)) {
+        break;
+      }
+      ok(!(line.value in subFound),
+         `should not have seen ${line.value} before in revocations.txt`);
+      subFound[line.value] = true;
+    }
+    for (let subline in sublines) {
+      ok(subFound[subline],
+         `should have found ${subline} below ${topLevelLine} in revocations.txt`);
+    }
+  }
+  for (let topLevelLine in expected) {
+    ok(topLevelFound[topLevelLine],
+       `should have found ${topLevelLine} in revocations.txt`);
+  }
 }
 
 function run_test() {
   // import the certificates we need
   load_cert("test-ca", "CTu,CTu,CTu");
   load_cert("test-int", ",,");
   load_cert("other-test-ca", "CTu,CTu,CTu");
 
   let certList = Cc["@mozilla.org/security/certblocklist;1"]
                   .getService(Ci.nsICertBlocklist);
 
-  let expected = "# Auto generated contents. Do not edit.\n" +
-                 "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5\n" +
-                 "\tVCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=\n" +
-                 "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=\n" +
-                 " BVio/iQ21GCi2iUven8oJ/gae74=\n" +
-                 "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=\n" +
-                 " exJUIJpq50jgqOwQluhVrAzTF74=\n" +
-                 "YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy\n" +
-                 " YW5vdGhlciBzZXJpYWwu\n" +
-                 " c2VyaWFsMi4=";
+  let expected = { "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5":
+                     { "\tVCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=": true },
+                   "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=":
+                     { " BVio/iQ21GCi2iUven8oJ/gae74=": true },
+                   "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=":
+                     { " exJUIJpq50jgqOwQluhVrAzTF74=": true },
+                   "YW5vdGhlciBpbWFnaW5hcnkgaXNzdWVy":
+                     { " YW5vdGhlciBzZXJpYWwu": true,
+                       " c2VyaWFsMi4=": true }
+                 };
 
   // This test assumes OneCRL updates via AMO
   Services.prefs.setBoolPref(PREF_BLOCKLIST_UPDATE_ENABLED, false);
   Services.prefs.setBoolPref(PREF_ONECRL_VIA_AMO, true);
 
   add_test(function () {
     // check some existing items in revocations.txt are blocked. Since the
     // CertBlocklistItems don't know about the data they contain, we can use