Bug 583949 - Fix leaks in Firefox Sync unit tests
authorJustin Dolske <dolske@mozilla.com>
Mon, 02 Aug 2010 22:37:13 -0700
changeset 48775 ebb224739c1a8e45a8be6e1e806d9ebeb57d18e5
parent 48774 0b8b9f147452215c5a4c59fef0c4ba1e35903b6c
child 48776 48497fbb14f883f7785fa204cdf772cb4a0892a4
child 48778 94c1106d182779a2c82000c72a1eaf65f0587629
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs583949
Bug 583949 - Fix leaks in Firefox Sync unit tests
services/sync/tests/unit/test_auth_manager.js
services/sync/tests/unit/test_records_crypto.js
services/sync/tests/unit/test_records_keys.js
services/sync/tests/unit/test_records_wbo.js
services/sync/tests/unit/test_resource.js
services/sync/tests/unit/test_service_changePassword.js
services/sync/tests/unit/test_service_checkUsername.js
services/sync/tests/unit/test_service_createAccount.js
services/sync/tests/unit/test_service_login.js
services/sync/tests/unit/test_service_passphraseUTF8.js
services/sync/tests/unit/test_service_passwordUTF8.js
services/sync/tests/unit/test_service_verifyLogin.js
services/sync/tests/unit/test_syncengine_sync.js
--- a/services/sync/tests/unit/test_auth_manager.js
+++ b/services/sync/tests/unit/test_auth_manager.js
@@ -29,16 +29,17 @@ function server_handler(metadata, respon
   }
 
   response.setStatusLine(metadata.httpVersion, statusCode, status);
   response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
   response.bodyOutputStream.write(body, body.length);
 }
 
 function run_test() {
+do_test_pending();
   logger = Log4Moz.repository.getLogger('Test');
   Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
   let server = new nsHttpServer();
   server.registerPathHandler("/foo", server_handler);
   server.registerPathHandler("/bar", server_handler);
   server.start(8080);
 
@@ -52,11 +53,11 @@ function run_test() {
     let content = new Resource("http://localhost:8080/foo").get();
     do_check_eq(content, "This path exists and is protected");
     do_check_eq(content.status, 200);
 
     content = new Resource("http://localhost:8080/bar").get();
     do_check_eq(content, "This path exists and is protected by a UTF8 password");
     do_check_eq(content.status, 200);
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
   }
 }
--- a/services/sync/tests/unit/test_records_crypto.js
+++ b/services/sync/tests/unit/test_records_crypto.js
@@ -32,16 +32,17 @@ function crypto_meta_handler(metadata, r
   let obj = {id: "ignore-me-4",
              modified: cryptoMeta.modified,
              payload: JSON.stringify(cryptoMeta.payload)};
   return httpd_basic_auth_handler(JSON.stringify(obj), metadata, response);
 }
 
 function run_test() {
   let server;
+  do_test_pending();
 
   try {
     let log = Log4Moz.repository.getLogger("Test");
     Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
     log.info("Setting up server and authenticator");
 
     server = httpd_setup({"/pubkey": pubkey_handler,
@@ -114,10 +115,12 @@ function run_test() {
     }
     catch(ex) {
       error = ex;
     }
     do_check_eq(error, "Record SHA256 HMAC mismatch: foo");
 
     log.info("Done!");
   }
-  finally { server.stop(function() {}); }
+  finally {
+    server.stop(do_test_finished);
+  }
 }
--- a/services/sync/tests/unit/test_records_keys.js
+++ b/services/sync/tests/unit/test_records_keys.js
@@ -18,45 +18,37 @@ function privkey_handler(metadata, respo
              modified: "2454725.98283",
              payload: JSON.stringify({type: "privkey",
                                    publicKeyUri: "http://localhost:8080/pubkey",
                                    keyData: "asdfasdfasf..."})};
   return httpd_basic_auth_handler(JSON.stringify(obj), metadata, response);
 }
 
 function test_get() {
-  let server;
+  let log = Log4Moz.repository.getLogger("Test");
+  Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
-  try {
-    let log = Log4Moz.repository.getLogger("Test");
-    Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
+  log.info("Setting up authenticator");
 
-    log.info("Setting up server and authenticator");
+  let auth = new BasicAuthenticator(new Identity("secret", "guest", "guest"));
+  Auth.defaultAuthenticator = auth;
 
-    server = httpd_setup({"/pubkey": pubkey_handler,
-                          "/privkey": privkey_handler});
-
-    let auth = new BasicAuthenticator(new Identity("secret", "guest", "guest"));
-    Auth.defaultAuthenticator = auth;
+  log.info("Getting a public key");
 
-    log.info("Getting a public key");
+  let pubkey = PubKeys.get("http://localhost:8080/pubkey");
+  do_check_eq(pubkey.data.payload.type, "pubkey");
+  do_check_eq(PubKeys.response.status, 200);
 
-    let pubkey = PubKeys.get("http://localhost:8080/pubkey");
-    do_check_eq(pubkey.data.payload.type, "pubkey");
-    do_check_eq(PubKeys.response.status, 200);
-
-    log.info("Getting matching private key");
+  log.info("Getting matching private key");
 
-    let privkey = PrivKeys.get(pubkey.privateKeyUri);
-    do_check_eq(privkey.data.payload.type, "privkey");
-    do_check_eq(PrivKeys.response.status, 200);
+  let privkey = PrivKeys.get(pubkey.privateKeyUri);
+  do_check_eq(privkey.data.payload.type, "privkey");
+  do_check_eq(PrivKeys.response.status, 200);
 
-    log.info("Done!");
-  }
-  finally { server.stop(function() {}); }
+  log.info("Done!");
 }
 
 
 function test_createKeypair() {
   let passphrase = "moneyislike$\u20ac\u00a5\u5143";
   let id = ID.set('foo', new Identity('foo', 'luser'));
   id.password = passphrase;
 
@@ -77,11 +69,20 @@ function test_createKeypair() {
   _("UTF8 encoded passphrase was used.");
   do_check_true(Svc.Crypto.verifyPassphrase(result.privkey.keyData,
                                             Utils.encodeUTF8(passphrase),
                                             result.privkey.salt,
                                             result.privkey.payload.iv));
 }
 
 function run_test() {
-  test_get();
-  test_createKeypair();
+  do_test_pending();
+  let server;
+  try {
+    server = httpd_setup({"/pubkey": pubkey_handler,
+                          "/privkey": privkey_handler});
+
+    test_get();
+    test_createKeypair();
+  } finally {
+    server.stop(do_test_finished);
+  }
 }
--- a/services/sync/tests/unit/test_records_wbo.js
+++ b/services/sync/tests/unit/test_records_wbo.js
@@ -26,16 +26,17 @@ function coll_handler(metadata, response
   let obj = [{id: "record2",
               modified: 2454725.98284,
               payload: JSON.stringify({cheese: "gruyere"})}];
   return httpd_basic_auth_handler(JSON.stringify(obj), metadata, response);
 }
 
 function run_test() {
   let server;
+  do_test_pending();
 
   try {
     let log = Log4Moz.repository.getLogger('Test');
     Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
     log.info("Setting up server and authenticator");
 
     server = httpd_setup({"/record": record_handler,
@@ -69,10 +70,10 @@ function run_test() {
     do_check_eq(rec2.modified, 2454725.98284);
     do_check_eq(typeof(rec2.payload), "object");
     do_check_eq(rec2.payload.cheese, "gruyere");
     do_check_eq(Records.response.status, 200);
 
     log.info("Done!");
   }
   catch (e) { do_throw(e); }
-  finally { server.stop(function() {}); }
+  finally { server.stop(do_test_finished); }
 }
--- a/services/sync/tests/unit/test_resource.js
+++ b/services/sync/tests/unit/test_resource.js
@@ -121,16 +121,18 @@ function server_headers(metadata, respon
   }
   let body = JSON.stringify(headers);
   response.setStatusLine(metadata.httpVersion, 200, "OK");
   response.bodyOutputStream.write(body, body.length);
 }
 
 
 function run_test() {
+  do_test_pending();
+
   logger = Log4Moz.repository.getLogger('Test');
   Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
   let server = new nsHttpServer();
   server.registerPathHandler("/open", server_open);
   server.registerPathHandler("/protected", server_protected);
   server.registerPathHandler("/404", server_404);
   server.registerPathHandler("/upload", server_upload);
@@ -371,10 +373,10 @@ function run_test() {
   did401 = false;
   let res13 = new Resource("http://localhost:8080/protected");
   content = res13.get();
   do_check_true(did401);
   do_check_eq(content, "This path exists and is protected - failed")
   do_check_eq(content.status, 401);
   do_check_false(content.success);
 
-  server.stop(function() {});
+  server.stop(do_test_finished);
 }
--- a/services/sync/tests/unit/test_service_changePassword.js
+++ b/services/sync/tests/unit/test_service_changePassword.js
@@ -25,16 +25,17 @@ function run_test() {
     do_check_false(res);
     do_check_eq(Weave.Service.password, "ilovejane");
 
     _("Let's fire up the server and actually change the password.");
     server  = httpd_setup({
       "/user/1.0/johndoe/password": send(200, "OK", ""),
       "/user/1.0/janedoe/password": send(401, "Unauthorized", "Forbidden!")
     });
+    do_test_pending();
 
     res = Weave.Service.changePassword("ILoveJane83");
     do_check_true(res);
     do_check_eq(Weave.Service.password, "ILoveJane83");
     do_check_eq(requestBody, "ILoveJane83");
 
     _("Make sure the password has been persisted in the login manager.");
     let logins = Weave.Svc.Login.findLogins({}, PWDMGR_HOST, null,
@@ -54,12 +55,12 @@ function run_test() {
     res = Weave.Service.changePassword("ILoveJohn86");
     do_check_false(res);
     do_check_eq(Weave.Service.password, "ilovejohn");
 
   } finally {
     Weave.Svc.Prefs.resetBranch("");
     Weave.Svc.Login.removeAllLogins();
     if (server) {
-      server.stop(function() {});
+      server.stop(do_test_finished);
     }
   }
 }
--- a/services/sync/tests/unit/test_service_checkUsername.js
+++ b/services/sync/tests/unit/test_service_checkUsername.js
@@ -3,16 +3,17 @@ Cu.import("resource://services-sync/serv
 function send(statusCode, status, body) {
   return function(request, response) {
     response.setStatusLine(request.httpVersion, statusCode, status);
     response.bodyOutputStream.write(body, body.length);
   };
 }
 
 function run_test() {
+  do_test_pending();
   let server = httpd_setup({
     "/user/1.0/johndoe": send(200, "OK", "1"),
     "/user/1.0/janedoe": send(200, "OK", "0")
   });
   try {
     Weave.Service.serverURL = "http://localhost:8080/";
 
     _("A 404 will be recorded as 'generic-server-error'");
@@ -21,11 +22,11 @@ function run_test() {
     _("Username that's not available.");
     do_check_eq(Weave.Service.checkUsername("johndoe"), "notAvailable");
 
     _("Username that's available.");
     do_check_eq(Weave.Service.checkUsername("janedoe"), "available");
 
   } finally {
     Weave.Svc.Prefs.resetBranch("");
-    server.stop(function() {});
+    server.stop(do_test_finished);
   }
 }
--- a/services/sync/tests/unit/test_service_createAccount.js
+++ b/services/sync/tests/unit/test_service_createAccount.js
@@ -11,16 +11,17 @@ function run_test() {
         secretHeader = request.getHeader("X-Weave-Secret");
       }
 
       response.setStatusLine(request.httpVersion, statusCode, status);
       response.bodyOutputStream.write(body, body.length);
     };
   }
 
+  do_test_pending();
   let server = httpd_setup({
     "/user/1.0/johndoe": send(200, "OK", "0"),
     "/user/1.0/janedoe": send(400, "Bad Request", "2"),
     "/user/1.0/jimdoe": send(500, "Server Error", "Server Error")
   });
   try {
     Weave.Service.serverURL = "http://localhost:8080/";
 
@@ -55,11 +56,11 @@ function run_test() {
     _("Admin secret preference is passed as HTTP header token.");
     Weave.Svc.Prefs.set("admin-secret", "my-server-secret");
     res = Weave.Service.createAccount("johndoe", "mysecretpw", "john@doe",
                                       "challenge", "response");
     do_check_eq(secretHeader, "my-server-secret");
 
   } finally {
     Weave.Svc.Prefs.resetBranch("");
-    server.stop(function() {});
+    server.stop(do_test_finished);
   }
 }
--- a/services/sync/tests/unit/test_service_login.js
+++ b/services/sync/tests/unit/test_service_login.js
@@ -19,16 +19,17 @@ function login_handler(request, response
   }
   response.bodyOutputStream.write(body, body.length);
 }
 
 function run_test() {
   let logger = Log4Moz.repository.rootLogger;
   Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
+  do_test_pending();
   let server = httpd_setup({
     "/1.0/johndoe/info/collections": login_handler,
     "/1.0/janedoe/info/collections": login_handler
   });
 
   try {
     Weave.Service.serverURL = "http://localhost:8080/";
     Weave.Service.clusterURL = "http://localhost:8080/";
@@ -84,11 +85,11 @@ function run_test() {
 
     _("Logging out again won't do any harm.");
     Weave.Service.logout();
     do_check_false(Weave.Service.isLoggedIn);
     do_check_false(Svc.Prefs.get("autoconnect"));
 
   } finally {
     Svc.Prefs.resetBranch("");
-    server.stop(function() {});
+    server.stop(do_test_finished);
   }
 }
--- a/services/sync/tests/unit/test_service_passphraseUTF8.js
+++ b/services/sync/tests/unit/test_service_passphraseUTF8.js
@@ -67,16 +67,17 @@ function run_test() {
   // Set up the server
   let server_privkey = new ServerWBO('privkey');
   let server_steam_key = new ServerWBO('steam', symkey);
   let server_petrol_key = new ServerWBO('petrol', petrol_symkey);
   let server_petrol_coll = new ServerCollection({
     'obj': new ServerWBO('obj', {somedata: "that's going", toget: "wiped"})
   });
 
+  do_test_pending();
   let server = httpd_setup({
     // Need these to make Weave.Service.wipeRemote() etc. happy
     "/1.0/foo/storage/meta/global": new ServerWBO('global', {}).handler(),
     "/1.0/foo/storage/crypto/clients": new ServerWBO('clients', {}).handler(),
     "/1.0/foo/storage/clients": new ServerCollection().handler(),
 
     // Records to reupload
     "/1.0/foo/storage/keys/privkey": server_privkey.handler(),
@@ -137,12 +138,13 @@ function run_test() {
     _("The 'petrol' bulk key had an incorrect HMAC to begin with, so it and all the data from that engine has been wiped.");
     do_check_eq(server_petrol_key.payload, undefined);
     do_check_eq(server_petrol_coll.wbos.obj.payload, undefined);
 
     _("The _needUpdatedKeys flag is no longer set.");
     do_check_false(Weave.Service._needUpdatedKeys);
 
   } finally {
-    server.stop(function() {});
+    if (server)
+      server.stop(do_test_finished);
     Weave.Svc.Prefs.resetBranch("");
   }
 }
--- a/services/sync/tests/unit/test_service_passwordUTF8.js
+++ b/services/sync/tests/unit/test_service_passwordUTF8.js
@@ -47,16 +47,17 @@ function change_password(request, respon
     body = status = "Unauthorized";
   }
   response.setStatusLine(request.httpVersion, statusCode, status);
   response.setHeader("WWW-Authenticate", 'Basic realm="secret"', false);
   response.bodyOutputStream.write(body, body.length);
 }
 
 function run_test() {
+  do_test_pending();
   let server = httpd_setup({
     "/1.0/johndoe/info/collections": info_collections,
     "/user/1.0/johndoe/password": change_password
   });
 
   Weave.Service.username = "johndoe";
   Weave.Service.password = JAPANESE;
   Weave.Service.passphrase = "Must exist, but contents irrelevant.";
@@ -74,12 +75,12 @@ function run_test() {
     do_check_eq(server_password, Utils.encodeUTF8(JAPANESE));
 
     _("Can't use a password that has the same low bytes as ours.");
     Weave.Service.password = APPLES;
     do_check_false(Weave.Service.verifyLogin());
     do_check_eq(server_password, Utils.encodeUTF8(JAPANESE));
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Weave.Svc.Prefs.resetBranch("");
   }
 }
--- a/services/sync/tests/unit/test_service_verifyLogin.js
+++ b/services/sync/tests/unit/test_service_verifyLogin.js
@@ -17,16 +17,17 @@ function login_handler(request, response
   }
   response.bodyOutputStream.write(body, body.length);
 }
 
 function run_test() {
   let logger = Log4Moz.repository.rootLogger;
   Log4Moz.repository.rootLogger.addAppender(new Log4Moz.DumpAppender());
 
+  do_test_pending();
   let server = httpd_setup({
     "/1.0/johndoe/info/collections": login_handler
   });
 
   try {
     Weave.Service.serverURL = "http://localhost:8080/";
     Weave.Service.clusterURL = "http://localhost:8080/";
 
@@ -49,11 +50,11 @@ function run_test() {
     Weave.Service.passphrase = "foo";
     Weave.Service.login();
     do_check_eq(Status.service, STATUS_OK);
     do_check_eq(Status.login, LOGIN_SUCCEEDED);
     do_check_true(Weave.Service.isLoggedIn);
 
   } finally {
     Svc.Prefs.resetBranch("");
-    server.stop(function() {});
+    server.stop(do_test_finished);
   }
 }
--- a/services/sync/tests/unit/test_syncengine_sync.js
+++ b/services/sync/tests/unit/test_syncengine_sync.js
@@ -182,16 +182,17 @@ function test_syncStartup_emptyOrOutdate
   collection.wbos.scotsman = new ServerWBO(
       'scotsman', encryptPayload({id: 'scotsman',
                                   denomination: "Flying Scotsman"}));
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
 
   let engine = makeSteamEngine();
   engine._store.items = {rekolok: "Rekonstruktionslokomotive"};
   try {
 
     // Confirm initial environment
     do_check_eq(crypto_steam.payload, undefined);
@@ -217,17 +218,17 @@ function test_syncStartup_emptyOrOutdate
     // Bulk key was uploaded
     do_check_true(!!crypto_steam.payload);
     do_check_true(!!crypto_steam.data.keyring);
 
     // WBO IDs are added to tracker (they're all marked for uploading)
     do_check_eq(engine._tracker.changedIDs["rekolok"], 0);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 function test_syncStartup_metaGet404() {
@@ -253,16 +254,17 @@ function test_syncStartup_metaGet404() {
   collection.wbos.scotsman = new ServerWBO(
       "scotsman", encryptPayload({id: "scotsman",
                                   denomination: "Flying Scotsman"}));
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
 
   try {
 
     _("Confirm initial environment");
     do_check_false(!!crypto_steam.payload);
     do_check_true(!!collection.wbos.flying.payload);
     do_check_true(!!collection.wbos.scotsman.payload);
@@ -276,17 +278,17 @@ function test_syncStartup_metaGet404() {
     do_check_eq(collection.wbos.scotsman.payload, undefined);
 
     _("New bulk key was uploaded");
     let key = crypto_steam.data.keyring["http://localhost:8080/1.0/foo/storage/keys/pubkey"];
     do_check_eq(key.wrapped, "fake-symmetric-key-0");
     do_check_eq(key.hmac, "fake-symmetric-key-0                                            ");
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 function test_syncStartup_failedMetaGet() {
@@ -295,78 +297,81 @@ function test_syncStartup_failedMetaGet(
   Svc.Prefs.set("clusterURL", "http://localhost:8080/");
   Svc.Prefs.set("username", "foo");
   let server = httpd_setup({
     "/1.0/foo/storage/crypto/steam": function(request, response) {
       response.setStatusLine(request.httpVersion, 405, "Method Not Allowed");
       response.bodyOutputStream.write("Fail!", 5);
     }
   });
+  do_test_pending();
 
   let engine = makeSteamEngine();
   try {
 
     _("Getting the cryptometa will fail and should set the appropriate failure");
     let error;
     try {
       engine._syncStartup();
     } catch (ex) {
       error = ex;
     }
     do_check_eq(error.failureCode, ENGINE_METARECORD_DOWNLOAD_FAIL);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 function test_syncStartup_serverHasNewerVersion() {
   _("SyncEngine._syncStartup ");
 
   Svc.Prefs.set("clusterURL", "http://localhost:8080/");
   Svc.Prefs.set("username", "foo");
   let global = new ServerWBO('global', {engines: {steam: {version: 23456}}});
   let server = httpd_setup({
       "/1.0/foo/storage/meta/global": global.handler()
   });
+  do_test_pending();
 
   let engine = makeSteamEngine();
   try {
 
     // The server has a newer version of the data and our engine can
     // handle.  That should give us an exception.
     let error;
     try {
       engine._syncStartup();
     } catch (ex) {
       error = ex;
     }
     do_check_eq(error.failureCode, VERSION_OUT_OF_DATE);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
 function test_syncStartup_syncIDMismatchResetsClient() {
   _("SyncEngine._syncStartup resets sync if syncIDs don't match");
 
   Svc.Prefs.set("clusterURL", "http://localhost:8080/");
   Svc.Prefs.set("username", "foo");
   let crypto_steam = new ServerWBO('steam');
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler()
   });
+  do_test_pending();
 
   // global record with a different syncID than our engine has
   let engine = makeSteamEngine();
   let global = new ServerWBO('global',
                              {engines: {steam: {version: engine.version,
                                                 syncID: 'foobar'}}});
   server.registerPathHandler("/1.0/foo/storage/meta/global", global.handler());
 
@@ -384,17 +389,17 @@ function test_syncStartup_syncIDMismatch
 
     // The engine has assumed the server's syncID 
     do_check_eq(engine.syncID, 'foobar');
 
     // Sync was reset
     do_check_eq(engine.lastSync, 0);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -429,16 +434,17 @@ function test_syncStartup_badKeyWipesSer
   collection.wbos.scotsman = new ServerWBO(
       'scotsman', encryptPayload({id: 'scotsman',
                                   denomination: "Flying Scotsman"}));
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
 
   try {
 
     // Confirm initial environment
     let key = crypto_steam.data.keyring["http://localhost:8080/1.0/foo/storage/keys/pubkey"];
     do_check_eq(key.wrapped, "fake-symmetric-key-0");
     do_check_eq(key.hmac, "this-hmac-is-incorrect");
@@ -454,17 +460,17 @@ function test_syncStartup_badKeyWipesSer
     do_check_eq(collection.wbos.scotsman.payload, undefined);
 
     // New bulk key was uploaded
     key = crypto_steam.data.keyring["http://localhost:8080/1.0/foo/storage/keys/pubkey"];
     do_check_eq(key.wrapped, "fake-symmetric-key-1");
     do_check_eq(key.hmac, "fake-symmetric-key-1                                            ");
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -475,28 +481,29 @@ function test_processIncoming_emptyServe
   Svc.Prefs.set("username", "foo");
   let crypto_steam = new ServerWBO('steam');
   let collection = new ServerCollection();
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
 
   let engine = makeSteamEngine();
   try {
 
     // Merely ensure that this code path is run without any errors
     engine._processIncoming();
     do_check_eq(engine.lastSync, 0);
     do_check_eq(engine.toFetch.length, 0);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -517,16 +524,17 @@ function test_processIncoming_createFrom
                                   denomination: "Flying Scotsman"}));
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler(),
       "/1.0/foo/storage/steam/flying": collection.wbos.flying.handler(),
       "/1.0/foo/storage/steam/scotsman": collection.wbos.scotsman.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
   createAndUploadSymKey("http://localhost:8080/1.0/foo/storage/crypto/steam");
 
   let engine = makeSteamEngine();
   try {
 
     // Confirm initial environment
     do_check_eq(engine.lastSync, 0);
@@ -540,17 +548,17 @@ function test_processIncoming_createFrom
     do_check_true(engine.lastSync > 0);
     do_check_true(engine.lastModified > 0);
 
     // Local records have been created from the server data.
     do_check_eq(engine._store.items.flying, "LNER Class A3 4472");
     do_check_eq(engine._store.items.scotsman, "Flying Scotsman");
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -606,16 +614,17 @@ function test_processIncoming_reconcile(
       'nukeme', encryptPayload({id: 'nukeme',
                                 denomination: "Nuke me!",
                                 deleted: true}));
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
   createAndUploadSymKey("http://localhost:8080/1.0/foo/storage/crypto/steam");
 
   let engine = makeSteamEngine();
   engine._store.items = {newerserver: "New data, but not as new as server!",
                          olderidentical: "Older but identical",
                          updateclient: "Got data?",
                          original: "Original Entry",
@@ -662,17 +671,17 @@ function test_processIncoming_reconcile(
     do_check_eq(engine._store.items.long_original, undefined);
     do_check_eq(engine._store.items.dupe, "Long Original Entry");
     do_check_neq(engine._delete.ids.indexOf('duplication'), -1);
 
     // The 'nukeme' record marked as deleted is removed.
     do_check_eq(engine._store.items.nukeme, undefined);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -694,16 +703,17 @@ function test_processIncoming_fetchNum()
     wbo.modified = Date.now()/1000 - 60*(i+10);
     collection.wbos[id] = wbo;
   }
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
   createAndUploadSymKey("http://localhost:8080/1.0/foo/storage/crypto/steam");
 
   let engine = makeSteamEngine();
 
   try {
 
     // On a mobile client, the first sync will only get the first 50
@@ -768,17 +778,17 @@ function test_processIncoming_fetchNum()
     // everything up to the last record.
     while(engine.toFetch.length) {
       engine._processIncoming();
     }
     do_check_eq([id for (id in engine._store.items)].length, 234 + 5);
     do_check_true('record-no-233' in engine._store.items);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -793,16 +803,17 @@ function test_uploadOutgoing_toEmptyServ
   collection.wbos.scotsman = new ServerWBO('scotsman');
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler(),
       "/1.0/foo/storage/steam/flying": collection.wbos.flying.handler(),
       "/1.0/foo/storage/steam/scotsman": collection.wbos.scotsman.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
   createAndUploadSymKey("http://localhost:8080/1.0/foo/storage/crypto/steam");
 
   let engine = makeSteamEngine();
   engine._store.items = {flying: "LNER Class A3 4472",
                          scotsman: "Flying Scotsman"};
   // Mark one of these records as changed 
   engine._tracker.addChangedID('scotsman', 0);
@@ -823,17 +834,17 @@ function test_uploadOutgoing_toEmptyServ
     do_check_eq(JSON.parse(collection.wbos.scotsman.data.ciphertext).id,
                 'scotsman');
     do_check_eq(engine._tracker.changedIDs['scotsman'], undefined);
 
     // The 'flying' record wasn't marked so it wasn't uploaded
     do_check_eq(collection.wbos.flying.payload, undefined);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -921,16 +932,17 @@ function test_uploadOutgoing_MAX_UPLOAD_
     engine._tracker.addChangedID(id, 0);
     collection.wbos[id] = new ServerWBO(id);
   }
 
   let server = sync_httpd_setup({
       "/1.0/foo/storage/crypto/steam": crypto_steam.handler(),
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
   createAndUploadKeypair();
   createAndUploadSymKey("http://localhost:8080/1.0/foo/storage/crypto/steam");
 
   try {
 
     // Confirm initial environment
     do_check_eq(noOfUploads, 0);
 
@@ -940,17 +952,17 @@ function test_uploadOutgoing_MAX_UPLOAD_
     for (i = 0; i < 234; i++) {
       do_check_true(!!collection.wbos['record-no-'+i].payload);
     }
 
     // Ensure that the uploads were performed in batches of MAX_UPLOAD_RECORDS
     do_check_eq(noOfUploads, Math.ceil(234/MAX_UPLOAD_RECORDS));
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     CryptoMetas.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
@@ -980,33 +992,34 @@ function test_syncFinish_deleteByIds() {
                                   denomination: "Flying Scotsman"}));
   collection.wbos.rekolok = new ServerWBO(
       'rekolok', encryptPayload({id: 'rekolok',
                                 denomination: "Rekonstruktionslokomotive"}));
 
   let server = httpd_setup({
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
 
   let engine = makeSteamEngine();
   try {
     engine._delete = {ids: ['flying', 'rekolok']};
     engine._syncFinish();
 
     // The 'flying' and 'rekolok' records were deleted while the
     // 'scotsman' one wasn't.
     do_check_eq(collection.wbos.flying.payload, undefined);
     do_check_true(!!collection.wbos.scotsman.payload);
     do_check_eq(collection.wbos.rekolok.payload, undefined);
 
     // The deletion todo list has been reset.
     do_check_eq(engine._delete.ids, undefined);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 
 function test_syncFinish_deleteLotsInBatches() {
@@ -1033,16 +1046,17 @@ function test_syncFinish_deleteLotsInBat
     let wbo = new ServerWBO(id, payload);
     wbo.modified = now / 1000 - 60 * (i + 110);
     collection.wbos[id] = wbo;
   }
 
   let server = httpd_setup({
       "/1.0/foo/storage/steam": collection.handler()
   });
+  do_test_pending();
 
   let engine = makeSteamEngine();
   try {
 
     // Confirm initial environment
     do_check_eq(noOfUploads, 0);
 
     // Declare what we want to have deleted: all records no. 100 and
@@ -1069,17 +1083,17 @@ function test_syncFinish_deleteLotsInBat
 
     // The deletion was done in batches
     do_check_eq(noOfUploads, 2 + 1);
 
     // The deletion todo list has been reset.
     do_check_eq(engine._delete.ids, undefined);
 
   } finally {
-    server.stop(function() {});
+    server.stop(do_test_finished);
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     syncTesting = new SyncTestingInfrastructure(makeSteamEngine);
   }
 }
 
 function run_test() {
   test_syncStartup_emptyOrOutdatedGlobalsResetsSync();