Bug 1335752 - Disable persistence and clean up after `RotaryEngine` in tests. r=markh draft
authorKit Cambridge <kit@yakshaving.ninja>
Mon, 13 Feb 2017 13:48:08 -0800
changeset 488771 c01eed08e72fd4ff654b3afed0472cb5185aec4e
parent 488323 804897e8a18e740483fa96e980ee63a76fa2616a
child 546826 6d8fc3a3873c09edd6d96fed461681621340df63
push id46631
push userbmo:kit@mozilla.com
push dateThu, 23 Feb 2017 18:08:23 +0000
reviewersmarkh
bugs1335752
milestone54.0a1
Bug 1335752 - Disable persistence and clean up after `RotaryEngine` in tests. r=markh MozReview-Commit-ID: 8feE9O6Dv3W
services/sync/modules-testing/rotaryengine.js
services/sync/modules/engines.js
services/sync/tests/unit/head_helpers.js
services/sync/tests/unit/test_engine.js
services/sync/tests/unit/test_engine_abort.js
services/sync/tests/unit/test_enginemanager.js
services/sync/tests/unit/test_fxa_node_reassignment.js
services/sync/tests/unit/test_hmac_error.js
services/sync/tests/unit/test_node_reassignment.js
services/sync/tests/unit/test_score_triggers.js
services/sync/tests/unit/test_syncengine_sync.js
services/sync/tests/unit/test_telemetry.js
--- a/services/sync/modules-testing/rotaryengine.js
+++ b/services/sync/modules-testing/rotaryengine.js
@@ -87,17 +87,18 @@ RotaryStore.prototype = {
     this.items = {};
   }
 };
 
 this.RotaryTracker = function RotaryTracker(name, engine) {
   Tracker.call(this, name, engine);
 }
 RotaryTracker.prototype = {
-  __proto__: Tracker.prototype
+  __proto__: Tracker.prototype,
+  persistChangedIDs: false,
 };
 
 
 this.RotaryEngine = function RotaryEngine(service) {
   SyncEngine.call(this, "Rotary", service);
   // Ensure that the engine starts with a clean slate.
   this.toFetch        = [];
   this.previousFailed = [];
--- a/services/sync/modules/engines.js
+++ b/services/sync/modules/engines.js
@@ -624,23 +624,25 @@ EngineManager.prototype = {
   unregister(val) {
     let name = val;
     if (val instanceof Engine) {
       name = val.name;
     }
     if (name in this._engines) {
       let engine = this._engines[name];
       delete this._engines[name];
-      engine.finalize();
+      Async.promiseSpinningly(engine.finalize());
     }
   },
 
   clear() {
     for (let name in this._engines) {
+      let engine = this._engines[name];
       delete this._engines[name];
+      Async.promiseSpinningly(engine.finalize());
     }
   },
 };
 
 this.Engine = function Engine(name, service) {
   if (!service) {
     throw new Error("Engine must be associated with a Service instance.");
   }
@@ -740,18 +742,18 @@ Engine.prototype = {
    * If one exists, initialize and return a validator for this engine (which
    * must have a `validate(engine)` method that returns a promise to an object
    * with a getSummary method). Otherwise return null.
    */
   getValidator() {
     return null;
   },
 
-  finalize() {
-    Async.promiseSpinningly(this._tracker.finalize());
+  async finalize() {
+    await this._tracker.finalize();
   },
 };
 
 this.SyncEngine = function SyncEngine(name, service) {
   Engine.call(this, name || "SyncEngine", service);
 
   this.loadToFetch();
   this.loadPreviousFailed();
--- a/services/sync/tests/unit/head_helpers.js
+++ b/services/sync/tests/unit/head_helpers.js
@@ -478,8 +478,18 @@ function promiseNextTick() {
   });
 }
 // Avoid an issue where `client.name2` containing unicode characters causes
 // a number of tests to fail, due to them assuming that we do not need to utf-8
 // encode or decode data sent through the mocked server (see bug 1268912).
 Utils.getDefaultDeviceName = function() {
   return "Test device name";
 };
+
+function registerRotaryEngine() {
+  Service.engineManager.clear();
+
+  Service.engineManager.register(RotaryEngine);
+  let engine = Service.engineManager.get("rotary");
+  engine.enabled = true;
+
+  return { engine, tracker: engine._tracker };
+}
--- a/services/sync/tests/unit/test_engine.js
+++ b/services/sync/tests/unit/test_engine.js
@@ -66,17 +66,17 @@ Observers.add("weave:engine:sync:start",
 Observers.add("weave:engine:sync:finish", engineObserver);
 
 async function cleanup(engine) {
   Svc.Prefs.resetBranch("");
   engine.wasReset = false;
   engine.wasSynced = false;
   engineObserver.reset();
   engine._tracker.clearChangedIDs();
-  await engine._tracker._storage.finalize();
+  await engine.finalize();
 }
 
 add_task(async function test_members() {
   _("Engine object members");
   let engine = new SteamEngine("Steam", Service);
   do_check_eq(engine.Name, "Steam");
   do_check_eq(engine.prefName, "steam");
   do_check_true(engine._store instanceof SteamStore);
--- a/services/sync/tests/unit/test_engine_abort.js
+++ b/services/sync/tests/unit/test_engine_abort.js
@@ -57,13 +57,16 @@ add_task(async function test_processInco
     err = ex;
   }
 
   do_check_eq(err, undefined);
 
   await promiseStopServer(server);
   Svc.Prefs.resetBranch("");
   Service.recordManager.clearCache();
+
+  engine._tracker.clearChangedIDs();
+  await engine.finalize();
 });
 
 function run_test() {
   run_next_test();
 }
--- a/services/sync/tests/unit/test_enginemanager.js
+++ b/services/sync/tests/unit/test_enginemanager.js
@@ -5,25 +5,25 @@ Cu.import("resource://services-sync/engi
 Cu.import("resource://services-sync/service.js");
 
 function run_test() {
   run_next_test();
 }
 
 function PetrolEngine() {}
 PetrolEngine.prototype.name = "petrol";
-PetrolEngine.prototype.finalize = function() {};
+PetrolEngine.prototype.finalize = async function() {};
 
 function DieselEngine() {}
 DieselEngine.prototype.name = "diesel";
-DieselEngine.prototype.finalize = function() {};
+DieselEngine.prototype.finalize = async function() {};
 
 function DummyEngine() {}
 DummyEngine.prototype.name = "dummy";
-DummyEngine.prototype.finalize = function() {};
+DummyEngine.prototype.finalize = async function() {};
 
 function ActualEngine() {}
 ActualEngine.prototype = {__proto__: Engine.prototype,
                           name: "actual"};
 
 add_test(function test_basics() {
   _("We start out with a clean slate");
 
--- a/services/sync/tests/unit/test_fxa_node_reassignment.js
+++ b/services/sync/tests/unit/test_fxa_node_reassignment.js
@@ -13,29 +13,29 @@ Cu.import("resource://services-sync/cons
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/status.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/rotaryengine.js");
 Cu.import("resource://services-sync/browserid_identity.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 Cu.import("resource://gre/modules/PromiseUtils.jsm");
 
+// Disables all built-in engines. Important for avoiding errors thrown by the
+// add-ons engine.
 Service.engineManager.clear();
 
 function run_test() {
   Log.repository.getLogger("Sync.AsyncResource").level = Log.Level.Trace;
   Log.repository.getLogger("Sync.ErrorHandler").level  = Log.Level.Trace;
   Log.repository.getLogger("Sync.Resource").level      = Log.Level.Trace;
   Log.repository.getLogger("Sync.RESTRequest").level   = Log.Level.Trace;
   Log.repository.getLogger("Sync.Service").level       = Log.Level.Trace;
   Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace;
   initTestLogging();
 
-  Service.engineManager.register(RotaryEngine);
-
   // Setup the FxA identity manager and cluster manager.
   Status.__authManager = Service.identity = new BrowserIDManager();
   Service._clusterManager = Service.identity.createClusterManager(Service);
 
   // None of the failures in this file should result in a UI error.
   function onUIError() {
     do_throw("Errors should not be presented in the UI.");
   }
@@ -205,18 +205,17 @@ add_task(async function test_single_toke
 });
 
 add_task(async function test_momentary_401_engine() {
   _("Test a failure for engine URLs that's resolved by reassignment.");
   let server = await prepareServer();
   let john   = server.user("johndoe");
 
   _("Enabling the Rotary engine.");
-  let engine = Service.engineManager.get("rotary");
-  engine.enabled = true;
+  let { engine, tracker } = registerRotaryEngine();
 
   // We need the server to be correctly set up prior to experimenting. Do this
   // through a sync.
   let global = {syncID: Service.syncID,
                 storageVersion: STORAGE_VERSION,
                 rotary: {version: engine.version,
                          syncID:  engine.syncID}}
   john.createCollection("meta").insert("global", global);
@@ -248,16 +247,19 @@ add_task(async function test_momentary_4
     Svc.Obs.add("weave:service:login:start", onLoginStart);
   }
 
   await syncAndExpectNodeReassignment(server,
                                       "weave:service:sync:finish",
                                       between,
                                       "weave:service:sync:finish",
                                       Service.storageURL + "rotary");
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
 
 // This test ends up being a failing info fetch *after we're already logged in*.
 add_task(async function test_momentary_401_info_collections_loggedin() {
   _("Test a failure for info/collections after login that's resolved by reassignment.");
   let server = await prepareServer();
 
   _("First sync to prepare server contents.");
--- a/services/sync/tests/unit/test_hmac_error.js
+++ b/services/sync/tests/unit/test_hmac_error.js
@@ -16,43 +16,40 @@ var hmacErrorCount = 0;
     return hHE.call(Service);
   };
 })();
 
 function shared_setup() {
   hmacErrorCount = 0;
 
   // Make sure RotaryEngine is the only one we sync.
-  Service.engineManager._engines = {};
-  Service.engineManager.register(RotaryEngine);
-  let engine = Service.engineManager.get("rotary");
-  engine.enabled = true;
+  let { engine, tracker } = registerRotaryEngine();
   engine.lastSync = 123; // Needs to be non-zero so that tracker is queried.
   engine._store.items = {flying: "LNER Class A3 4472",
                          scotsman: "Flying Scotsman"};
-  engine._tracker.addChangedID("scotsman", 0);
+  tracker.addChangedID("scotsman", 0);
   do_check_eq(1, Service.engineManager.getEnabled().length);
 
   let engines = {rotary:  {version: engine.version,
                            syncID:  engine.syncID},
                  clients: {version: Service.clientsEngine.version,
                            syncID:  Service.clientsEngine.syncID}};
 
   // Common server objects.
   let global      = new ServerWBO("global", {engines});
   let keysWBO     = new ServerWBO("keys");
   let rotaryColl  = new ServerCollection({}, true);
   let clientsColl = new ServerCollection({}, true);
 
-  return [engine, rotaryColl, clientsColl, keysWBO, global];
+  return [engine, rotaryColl, clientsColl, keysWBO, global, tracker];
 }
 
 add_task(async function hmac_error_during_404() {
   _("Attempt to replicate the HMAC error setup.");
-  let [engine, rotaryColl, clientsColl, keysWBO, global] = shared_setup();
+  let [engine, rotaryColl, clientsColl, keysWBO, global, tracker] = shared_setup();
 
   // Hand out 404s for crypto/keys.
   let keysHandler    = keysWBO.handler();
   let key404Counter  = 0;
   let keys404Handler = function(request, response) {
     if (key404Counter > 0) {
       let body = "Not Found";
       response.setStatusLine(request.httpVersion, 404, body);
@@ -88,25 +85,27 @@ add_task(async function hmac_error_durin
     key404Counter = 1;
     _("---------------------------");
     await sync_and_validate_telem();
     _("---------------------------");
 
     // Two rotary items, one client record... no errors.
     do_check_eq(hmacErrorCount, 0)
   } finally {
+    tracker.clearChangedIDs();
+    Service.engineManager.unregister(engine);
     Svc.Prefs.resetBranch("");
     Service.recordManager.clearCache();
     await promiseStopServer(server);
   }
 });
 
 add_task(async function hmac_error_during_node_reassignment() {
   _("Attempt to replicate an HMAC error during node reassignment.");
-  let [engine, rotaryColl, clientsColl, keysWBO, global] = shared_setup();
+  let [engine, rotaryColl, clientsColl, keysWBO, global, tracker] = shared_setup();
 
   let collectionsHelper = track_collections_helper();
   let upd = collectionsHelper.with_updated_collection;
 
   // We'll provide a 401 mid-way through the sync. This function
   // simulates shifting to a node which has no data.
   function on401() {
     _("Deleting server data...");
@@ -214,19 +213,20 @@ add_task(async function hmac_error_durin
 
           onSyncFinished = function() {
             // Two rotary items, one client record... no errors.
             do_check_eq(hmacErrorCount, 0)
 
             Svc.Obs.remove("weave:service:sync:finish", obs);
             Svc.Obs.remove("weave:service:sync:error", obs);
 
+            tracker.clearChangedIDs();
+            Service.engineManager.unregister(engine);
             Svc.Prefs.resetBranch("");
             Service.recordManager.clearCache();
-            engine._tracker.clearChangedIDs();
             server.stop(resolve);
           };
 
           Service.sync();
         },
         this);
       };
     };
--- a/services/sync/tests/unit/test_node_reassignment.js
+++ b/services/sync/tests/unit/test_node_reassignment.js
@@ -9,30 +9,26 @@ Cu.import("resource://services-common/re
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/status.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/rotaryengine.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 Cu.import("resource://gre/modules/PromiseUtils.jsm");
 
-Service.engineManager.clear();
-
 function run_test() {
   Log.repository.getLogger("Sync.AsyncResource").level = Log.Level.Trace;
   Log.repository.getLogger("Sync.ErrorHandler").level  = Log.Level.Trace;
   Log.repository.getLogger("Sync.Resource").level      = Log.Level.Trace;
   Log.repository.getLogger("Sync.RESTRequest").level   = Log.Level.Trace;
   Log.repository.getLogger("Sync.Service").level       = Log.Level.Trace;
   Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace;
   initTestLogging();
   validate_all_future_pings();
 
-  Service.engineManager.register(RotaryEngine);
-
   // None of the failures in this file should result in a UI error.
   function onUIError() {
     do_throw("Errors should not be presented in the UI.");
   }
   Svc.Obs.add("weave:ui:login:error", onUIError);
   Svc.Obs.add("weave:ui:sync:error", onUIError);
 
   run_next_test();
@@ -139,18 +135,17 @@ async function syncAndExpectNodeReassign
 }
 
 add_task(async function test_momentary_401_engine() {
   _("Test a failure for engine URLs that's resolved by reassignment.");
   let server = await prepareServer();
   let john   = server.user("johndoe");
 
   _("Enabling the Rotary engine.");
-  let engine = Service.engineManager.get("rotary");
-  engine.enabled = true;
+  let { engine, tracker } = registerRotaryEngine();
 
   // We need the server to be correctly set up prior to experimenting. Do this
   // through a sync.
   let global = {syncID: Service.syncID,
                 storageVersion: STORAGE_VERSION,
                 rotary: {version: engine.version,
                          syncID:  engine.syncID}}
   john.createCollection("meta").insert("global", global);
@@ -182,16 +177,19 @@ add_task(async function test_momentary_4
     Svc.Obs.add("weave:service:login:start", onLoginStart);
   }
 
   await syncAndExpectNodeReassignment(server,
                                       "weave:service:sync:finish",
                                       between,
                                       "weave:service:sync:finish",
                                       Service.storageURL + "rotary");
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
 
 // This test ends up being a failing fetch *after we're already logged in*.
 add_task(async function test_momentary_401_info_collections() {
   _("Test a failure for info/collections that's resolved by reassignment.");
   let server = await prepareServer();
 
   _("First sync to prepare server contents.");
@@ -361,18 +359,17 @@ add_task(async function test_loop_avoida
 
 add_task(async function test_loop_avoidance_engine() {
   _("Test that a repeated 401 in an engine doesn't result in a sync loop " +
     "if node reassignment cannot resolve the failure.");
   let server = await prepareServer();
   let john   = server.user("johndoe");
 
   _("Enabling the Rotary engine.");
-  let engine = Service.engineManager.get("rotary");
-  engine.enabled = true;
+  let { engine, tracker } = registerRotaryEngine();
   let deferred = PromiseUtils.defer();
 
   let getTokenCount = 0;
   let mockTSC = { // TokenServerClient
     getTokenFromBrowserIDAssertion(uri, assertion, cb) {
       getTokenCount++;
       cb(null, {
         endpoint: server.baseURI + "1.1/johndoe/"
@@ -489,9 +486,12 @@ add_task(async function test_loop_avoida
     });
   }
 
   Svc.Obs.add(firstNotification, onFirstSync);
 
   now = Date.now();
   Service.sync();
   await deferred.promise;
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
--- a/services/sync/tests/unit/test_score_triggers.js
+++ b/services/sync/tests/unit/test_score_triggers.js
@@ -5,22 +5,16 @@ Cu.import("resource://services-sync/engi
 Cu.import("resource://services-sync/engines/clients.js");
 Cu.import("resource://services-sync/constants.js");
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/status.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/rotaryengine.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
-Service.engineManager.clear();
-Service.engineManager.register(RotaryEngine);
-var engine = Service.engineManager.get("rotary");
-var tracker = engine._tracker;
-engine.enabled = true;
-
 // Tracking info/collections.
 var collectionsHelper = track_collections_helper();
 var upd = collectionsHelper.with_updated_collection;
 
 function sync_httpd_setup() {
   let handlers = {};
 
   handlers["/1.1/johndoe/storage/meta/global"] =
@@ -39,28 +33,32 @@ function sync_httpd_setup() {
   let cl = new ServerCollection();
   handlers["/1.1/johndoe/storage/clients"] =
     upd("clients", cl.handler());
 
   return httpd_setup(handlers);
 }
 
 async function setUp(server) {
+  let engineInfo = registerRotaryEngine();
   await SyncTestingInfrastructure(server, "johndoe", "ilovejane");
+  return engineInfo;
 }
 
 function run_test() {
   initTestLogging("Trace");
 
   Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
 
   run_next_test();
 }
 
 add_test(function test_tracker_score_updated() {
+  let { engine, tracker } = registerRotaryEngine();
+
   let scoreUpdated = 0;
 
   function onScoreUpdated() {
     scoreUpdated++;
   }
 
   Svc.Obs.add("weave:engine:score:updated", onScoreUpdated());
 
@@ -69,60 +67,68 @@ add_test(function test_tracker_score_upd
 
     tracker.score += SCORE_INCREMENT_SMALL;
     do_check_eq(engine.score, SCORE_INCREMENT_SMALL);
 
     do_check_eq(scoreUpdated, 1);
   } finally {
     Svc.Obs.remove("weave:engine:score:updated", onScoreUpdated);
     tracker.resetScore();
+    tracker.clearChangedIDs();
+    Service.engineManager.unregister(engine);
     run_next_test();
   }
 });
 
 add_task(async function test_sync_triggered() {
   let server = sync_httpd_setup();
-  await setUp(server);
+  let { engine, tracker } = await setUp(server);
 
   Service.login();
 
   Service.scheduler.syncThreshold = MULTI_DEVICE_THRESHOLD;
 
 
   do_check_eq(Status.login, LOGIN_SUCCEEDED);
   tracker.score += SCORE_INCREMENT_XLARGE;
 
-  await promiseOneObserver("weave:service:sync:finish")
+  await promiseOneObserver("weave:service:sync:finish");
   await promiseStopServer(server);
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
 
 add_task(async function test_clients_engine_sync_triggered() {
   _("Ensure that client engine score changes trigger a sync.");
 
   // The clients engine is not registered like other engines. Therefore,
   // it needs special treatment throughout the code. Here, we verify the
   // global score tracker gives it that treatment. See bug 676042 for more.
 
   let server = sync_httpd_setup();
-  await setUp(server);
+  let { engine, tracker } = await setUp(server);
   Service.login();
 
   Service.scheduler.syncThreshold = MULTI_DEVICE_THRESHOLD;
   do_check_eq(Status.login, LOGIN_SUCCEEDED);
   Service.clientsEngine._tracker.score += SCORE_INCREMENT_XLARGE;
 
   await promiseOneObserver("weave:service:sync:finish");
   _("Sync due to clients engine change completed.");
   await promiseStopServer(server);
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
 
 add_task(async function test_incorrect_credentials_sync_not_triggered() {
   _("Ensure that score changes don't trigger a sync if Status.login != LOGIN_SUCCEEDED.");
   let server = sync_httpd_setup();
-  await setUp(server);
+  let { engine, tracker } = await setUp(server);
 
   // Ensure we don't actually try to sync.
   function onSyncStart() {
     do_throw("Should not get here!");
   }
   Svc.Obs.add("weave:service:sync:start", onSyncStart);
 
   // Faking incorrect credentials to prevent score update.
@@ -136,9 +142,12 @@ add_task(async function test_incorrect_c
   await promiseNextTick();
 
   Svc.Obs.remove("weave:service:sync:start", onSyncStart);
 
   do_check_eq(Status.login, LOGIN_FAILED_LOGIN_REJECTED);
 
   Service.startOver();
   await promiseStopServer(server);
+
+  tracker.clearChangedIDs();
+  Service.engineManager.unregister(engine);
 });
--- a/services/sync/tests/unit/test_syncengine_sync.js
+++ b/services/sync/tests/unit/test_syncengine_sync.js
@@ -10,30 +10,31 @@ Cu.import("resource://services-sync/serv
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/rotaryengine.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
 function makeRotaryEngine() {
   return new RotaryEngine(Service);
 }
 
-function clean(engine) {
+async function clean(engine) {
   Svc.Prefs.resetBranch("");
   Svc.Prefs.set("log.logger.engine.rotary", "Trace");
   Service.recordManager.clearCache();
   engine._tracker.clearChangedIDs();
+  await engine.finalize();
 }
 
 async function cleanAndGo(engine, server) {
-  clean(engine);
+  await clean(engine);
   await promiseStopServer(server);
 }
 
 async function promiseClean(engine, server) {
-  clean(engine);
+  await clean(engine);
   await promiseStopServer(server);
 }
 
 async function createServerAndConfigureClient() {
   let engine = new RotaryEngine(Service);
 
   let contents = {
     meta: {global: {engines: {rotary: {version: engine.version,
--- a/services/sync/tests/unit/test_telemetry.js
+++ b/services/sync/tests/unit/test_telemetry.js
@@ -55,20 +55,20 @@ SteamEngine.prototype = {
 
 function BogusEngine(service) {
   Engine.call(this, "bogus", service);
 }
 
 BogusEngine.prototype = Object.create(SteamEngine.prototype);
 
 async function cleanAndGo(engine, server) {
+  engine._tracker.clearChangedIDs();
   Svc.Prefs.resetBranch("");
   Svc.Prefs.set("log.logger.engine.rotary", "Trace");
   Service.recordManager.clearCache();
-  engine._tracker.clearChangedIDs();
   await promiseStopServer(server);
 }
 
 // Avoid addon manager complaining about not being initialized
 Service.engineManager.unregister("addons");
 
 add_task(async function test_basic() {
   let helper = track_collections_helper();
@@ -237,16 +237,17 @@ add_task(async function test_upload_fail
     ping = await sync_engine_and_validate_telem(engine, true);
     ok(!!ping);
     equal(ping.engines.length, 1);
     equal(ping.engines[0].incoming.reconciled, 1);
     deepEqual(ping.engines[0].outgoing, [{ sent: 2, failed: 2 }]);
 
   } finally {
     await cleanAndGo(engine, server);
+    await engine.finalize();
   }
 });
 
 add_task(async function test_sync_partialUpload() {
   let collection = new ServerCollection();
   let server = sync_httpd_setup({
       "/1.1/foo/storage/rotary": collection.handler()
   });
@@ -319,16 +320,17 @@ add_task(async function test_sync_partia
       newFailed: 1,
       reconciled: 232
     });
     ok(!ping.engines[0].outgoing);
     deepEqual(ping.engines[0].failureReason, uploadFailureError);
 
   } finally {
     await cleanAndGo(engine, server);
+    await engine.finalize();
   }
 });
 
 add_task(async function test_generic_engine_fail() {
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
   let server = serverForUsers({"foo": "password"}, {