Bug 1350030 - Extract `serverForEngine` into `serverForEnginesWithKeys`. r=tcsc draft
authorKit Cambridge <kit@yakshaving.ninja>
Thu, 30 Mar 2017 18:01:19 -0700
changeset 570979 a27836cea6100fd90e15ed95b08c9f02e6c79605
parent 570886 57b37213d81150642f5139764e7044b07b9dccc3
child 626634 7e23da29b2d2373ebade3b7dad243b1f81b8fdd3
push id56646
push userbmo:kit@mozilla.com
push dateMon, 01 May 2017 20:39:10 +0000
reviewerstcsc
bugs1350030
milestone55.0a1
Bug 1350030 - Extract `serverForEngine` into `serverForEnginesWithKeys`. r=tcsc MozReview-Commit-ID: 3D1xwv9k76m
services/sync/tests/unit/head_helpers.js
services/sync/tests/unit/test_bookmark_decline_undecline.js
services/sync/tests/unit/test_bookmark_duping.js
services/sync/tests/unit/test_bookmark_engine.js
services/sync/tests/unit/test_bookmark_repair.js
services/sync/tests/unit/test_bookmark_repair_responder.js
services/sync/tests/unit/test_bookmark_smart_bookmarks.js
services/sync/tests/unit/test_clients_engine.js
services/sync/tests/unit/test_password_engine.js
services/sync/tests/unit/test_telemetry.js
--- a/services/sync/tests/unit/head_helpers.js
+++ b/services/sync/tests/unit/head_helpers.js
@@ -496,8 +496,51 @@ function registerRotaryEngine() {
 
 // Set the validation prefs to attempt validation every time to avoid non-determinism.
 function enableValidationPrefs() {
   Svc.Prefs.set("engine.bookmarks.validation.interval", 0);
   Svc.Prefs.set("engine.bookmarks.validation.percentageChance", 100);
   Svc.Prefs.set("engine.bookmarks.validation.maxRecords", -1);
   Svc.Prefs.set("engine.bookmarks.validation.enabled", true);
 }
+
+function serverForEnginesWithKeys(users, engines, callback) {
+  // Generate and store a fake default key bundle to avoid resetting the client
+  // before the first sync.
+  let wbo = Service.collectionKeys.generateNewKeysWBO();
+  let modified = new_timestamp();
+  Service.collectionKeys.setContents(wbo.cleartext, modified);
+
+  let allEngines = [Service.clientsEngine].concat(engines);
+
+  let globalEngines = allEngines.reduce((entries, engine) => {
+    let { name, version, syncID } = engine;
+    entries[name] = { version, syncID };
+    return entries;
+  }, {});
+
+  let contents = allEngines.reduce((collections, engine) => {
+    collections[engine.name] = {};
+    return collections;
+  }, {
+    meta: {
+      global: {
+        syncID: Service.syncID,
+        storageVersion: STORAGE_VERSION,
+        engines: globalEngines,
+      },
+    },
+    crypto: {
+      keys: encryptPayload(wbo.cleartext),
+    },
+  });
+
+  return serverForUsers(users, contents, callback);
+}
+
+function serverForFoo(engine, callback) {
+  // The bookmarks engine *always* tracks changes, meaning we might try
+  // and sync due to the bookmarks we ourselves create! Worse, because we
+  // do an engine sync only, there's no locking - so we end up with multiple
+  // syncs running. Neuter that by making the threshold very large.
+  Service.scheduler.syncThreshold = 10000000;
+  return serverForEnginesWithKeys({"foo": "password"}, engine, callback);
+}
--- a/services/sync/tests/unit/test_bookmark_decline_undecline.js
+++ b/services/sync/tests/unit/test_bookmark_decline_undecline.js
@@ -11,55 +11,16 @@ Cu.import("resource://services-sync/engi
 Cu.import("resource://services-sync/service.js");
 Cu.import("resource://services-sync/util.js");
 Cu.import("resource://testing-common/services/sync/utils.js");
 
 initTestLogging("Trace");
 
 Service.engineManager.register(BookmarksEngine);
 
-function serverForFoo(engine) {
-  // The bookmarks engine *always* tracks changes, meaning we might try
-  // and sync due to the bookmarks we ourselves create! Worse, because we
-  // do an engine sync only, there's no locking - so we end up with multiple
-  // syncs running. Neuter that by making the threshold very large.
-  Service.scheduler.syncThreshold = 10000000;
-  let clientsEngine = Service.clientsEngine;
-  return serverForUsers({"foo": "password"}, {
-    meta: {
-      global: {
-        syncID: Service.syncID,
-        storageVersion: STORAGE_VERSION,
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: engine.version,
-            syncID: engine.syncID,
-          },
-        },
-      },
-    },
-    crypto: {
-      keys: encryptPayload({
-        id: "keys",
-        // Generate a fake default key bundle to avoid resetting the client
-        // before the first sync.
-        default: [
-          Svc.Crypto.generateRandomKey(),
-          Svc.Crypto.generateRandomKey(),
-        ],
-      }),
-    },
-    bookmarks: {}
-  });
-}
-
 // A stored reference to the collection won't be valid after disabling.
 function getBookmarkWBO(server, guid) {
   let coll = server.user("foo").collection("bookmarks");
   if (!coll) {
     return null;
   }
   return coll.wbo(guid);
 }
--- a/services/sync/tests/unit/test_bookmark_duping.js
+++ b/services/sync/tests/unit/test_bookmark_duping.js
@@ -20,34 +20,21 @@ const bms = PlacesUtils.bookmarks;
 Service.engineManager.register(BookmarksEngine);
 
 const engine = new BookmarksEngine(Service);
 const store = engine._store;
 store._log.level = Log.Level.Trace;
 engine._log.level = Log.Level.Trace;
 
 async function setup() {
- let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bookmarks: {version: engine.version,
-                                          syncID: engine.syncID}}}},
-    bookmarks: {},
-  });
-
-  generateNewKeys(Service.collectionKeys);
-
+ let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let collection = server.user("foo").collection("bookmarks");
 
-  // The bookmarks engine *always* tracks changes, meaning we might try
-  // and sync due to the bookmarks we ourselves create! Worse, because we
-  // do an engine sync only, there's no locking - so we end up with multiple
-  // syncs running. Neuter that by making the threshold very large.
-  Service.scheduler.syncThreshold = 10000000;
-
   Svc.Obs.notify("weave:engine:start-tracking");   // We skip usual startup...
 
   return { server, collection };
 }
 
 async function cleanup(server) {
   Svc.Obs.notify("weave:engine:stop-tracking");
   let promiseStartOver = promiseOneObserver("weave:service:start-over:finish");
--- a/services/sync/tests/unit/test_bookmark_engine.js
+++ b/services/sync/tests/unit/test_bookmark_engine.js
@@ -277,30 +277,16 @@ add_task(async function bad_record_allID
   do_check_true(all.has("toolbar"));
 
   _("Clean up.");
   PlacesUtils.bookmarks.removeItem(badRecordID);
   await PlacesSyncUtils.bookmarks.reset();
   await promiseStopServer(server);
 });
 
-function serverForFoo(engine) {
-  // The bookmarks engine *always* tracks changes, meaning we might try
-  // and sync due to the bookmarks we ourselves create! Worse, because we
-  // do an engine sync only, there's no locking - so we end up with multiple
-  // syncs running. Neuter that by making the threshold very large.
-  Service.scheduler.syncThreshold = 10000000;
-
-  return serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bookmarks: {version: engine.version,
-                                          syncID: engine.syncID}}}},
-    bookmarks: {}
-  });
-}
-
 add_task(async function test_processIncoming_error_orderChildren() {
   _("Ensure that _orderChildren() is called even when _processIncoming() throws an error.");
 
   let engine = new BookmarksEngine(Service);
   let store  = engine._store;
   let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
--- a/services/sync/tests/unit/test_bookmark_repair.js
+++ b/services/sync/tests/unit/test_bookmark_repair.js
@@ -84,36 +84,17 @@ async function cleanup(server) {
   await promiseStopServer(server);
 }
 
 add_task(async function test_bookmark_repair_integration() {
   enableValidationPrefs();
 
   _("Ensure that a validation error triggers a repair request.");
 
-  let contents = {
-    meta: {
-      global: {
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: bookmarksEngine.version,
-            syncID: bookmarksEngine.syncID,
-          },
-        }
-      }
-    },
-    clients: {},
-    bookmarks: {},
-    crypto: {},
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(bookmarksEngine);
   await SyncTestingInfrastructure(server);
 
   let user = server.user("foo");
 
   let initialID = Service.clientsEngine.localID;
   let remoteID = Utils.makeGUID();
   try {
 
@@ -324,36 +305,17 @@ add_task(async function test_bookmark_re
   }
 });
 
 add_task(async function test_repair_client_missing() {
   enableValidationPrefs();
 
   _("Ensure that a record missing from the client only will get re-downloaded from the server");
 
-  let contents = {
-    meta: {
-      global: {
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: bookmarksEngine.version,
-            syncID: bookmarksEngine.syncID,
-          },
-        }
-      }
-    },
-    clients: {},
-    bookmarks: {},
-    crypto: {},
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(bookmarksEngine);
   await SyncTestingInfrastructure(server);
 
   let user = server.user("foo");
 
   let initialID = Service.clientsEngine.localID;
   let remoteID = Utils.makeGUID();
   try {
 
@@ -415,36 +377,17 @@ add_task(async function test_repair_clie
   }
 });
 
 add_task(async function test_repair_server_missing() {
   enableValidationPrefs();
 
   _("Ensure that a record missing from the server only will get re-upload from the client");
 
-  let contents = {
-    meta: {
-      global: {
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: bookmarksEngine.version,
-            syncID: bookmarksEngine.syncID,
-          },
-        }
-      }
-    },
-    clients: {},
-    bookmarks: {},
-    crypto: {},
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(bookmarksEngine);
   await SyncTestingInfrastructure(server);
 
   let user = server.user("foo");
 
   let initialID = Service.clientsEngine.localID;
   let remoteID = Utils.makeGUID();
   try {
 
@@ -499,36 +442,17 @@ add_task(async function test_repair_serv
   }
 });
 
 add_task(async function test_repair_server_deleted() {
   enableValidationPrefs();
 
   _("Ensure that a record marked as deleted on the server but present on the client will get deleted on the client");
 
-  let contents = {
-    meta: {
-      global: {
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: bookmarksEngine.version,
-            syncID: bookmarksEngine.syncID,
-          },
-        }
-      }
-    },
-    clients: {},
-    bookmarks: {},
-    crypto: {},
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(bookmarksEngine);
   await SyncTestingInfrastructure(server);
 
   let user = server.user("foo");
 
   let initialID = Service.clientsEngine.localID;
   let remoteID = Utils.makeGUID();
   try {
 
--- a/services/sync/tests/unit/test_bookmark_repair_responder.js
+++ b/services/sync/tests/unit/test_bookmark_repair_responder.js
@@ -29,49 +29,19 @@ function checkRecordedEvents(expected) {
   recordedEvents = [];
 }
 
 function getServerBookmarks(server) {
   return server.user("foo").collection("bookmarks");
 }
 
 async function setup() {
-  let clientsEngine = Service.clientsEngine;
   let bookmarksEngine = Service.engineManager.get("bookmarks");
 
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {
-      global: {
-        syncID: Service.syncID,
-        storageVersion: STORAGE_VERSION,
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          bookmarks: {
-            version: bookmarksEngine.version,
-            syncID: bookmarksEngine.syncID,
-          },
-        },
-      },
-    },
-    crypto: {
-      keys: encryptPayload({
-        id: "keys",
-        // Generate a fake default key bundle to avoid resetting the client
-        // before the first sync.
-        default: [
-          Svc.Crypto.generateRandomKey(),
-          Svc.Crypto.generateRandomKey(),
-        ],
-      }),
-    },
-  });
-
+  let server = serverForFoo(bookmarksEngine);
   await SyncTestingInfrastructure(server);
 
   // Disable validation so that we don't try to automatically repair the server
   // when we sync.
   Svc.Prefs.set("engine.bookmarks.validation.enabled", false);
 
   return server;
 }
--- a/services/sync/tests/unit/test_bookmark_smart_bookmarks.js
+++ b/services/sync/tests/unit/test_bookmark_smart_bookmarks.js
@@ -41,24 +41,16 @@ function smartBookmarkCount() {
 function clearBookmarks() {
   _("Cleaning up existing items.");
   PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.bookmarksMenuFolder);
   PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.tagsFolder);
   PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.toolbarFolder);
   PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder);
 }
 
-function serverForFoo(engineData) {
-  return serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bookmarks: {version: engineData.version,
-                                          syncID: engineData.syncID}}}},
-    bookmarks: {}
-  });
-}
-
 // Verify that Places smart bookmarks have their annotation uploaded and
 // handled locally.
 add_task(async function test_annotation_uploaded() {
   let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let startCount = smartBookmarkCount();
 
--- a/services/sync/tests/unit/test_clients_engine.js
+++ b/services/sync/tests/unit/test_clients_engine.js
@@ -53,34 +53,28 @@ function cleanup() {
   engine._tracker.clearChangedIDs();
   engine._resetClient();
   // We don't finalize storage at cleanup, since we use the same clients engine
   // instance across all tests.
 }
 
 add_task(async function test_bad_hmac() {
   _("Ensure that Clients engine deletes corrupt records.");
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
   let deletedCollections = [];
   let deletedItems       = [];
   let callback = {
     __proto__: SyncServerCallback,
     onItemDeleted(username, coll, wboID) {
       deletedItems.push(coll + "/" + wboID);
     },
     onCollectionDeleted(username, coll) {
       deletedCollections.push(coll);
     }
   }
-  let server = serverForUsers({"foo": "password"}, contents, callback);
+  let server = serverForFoo(engine, callback);
   let user   = server.user("foo");
 
   function check_clients_count(expectedCount) {
     let stack = Components.stack.caller;
     let coll  = user.collection("clients");
 
     // Treat a non-existent collection as empty.
     equal(expectedCount, coll ? coll.count() : 0, stack);
@@ -207,23 +201,17 @@ add_task(async function test_properties(
     cleanup();
   }
 });
 
 add_task(async function test_full_sync() {
   _("Ensure that Clients engine fetches all records for each sync.");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
   let user   = server.user("foo");
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let activeID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
     id: activeID,
@@ -278,23 +266,17 @@ add_task(async function test_full_sync()
       await promiseStopServer(server);
     }
   }
 });
 
 add_task(async function test_sync() {
   _("Ensure that Clients engine uploads a new client record once a week.");
 
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
   let user   = server.user("foo");
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   function clientWBO() {
     return user.collection("clients").wbo(engine.localID);
   }
@@ -364,23 +346,17 @@ add_task(async function test_client_name
 
   cleanup();
 });
 
 add_task(async function test_last_modified() {
   _("Ensure that remote records have a sane serverLastModified attribute.");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
   let user   = server.user("foo");
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let activeID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
     id: activeID,
@@ -585,23 +561,17 @@ add_task(async function test_process_inc
 
   cleanup();
 });
 
 add_task(async function test_filter_duplicate_names() {
   _("Ensure that we exclude clients with identical names that haven't synced in a week.");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
   let user   = server.user("foo");
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   // Synced recently.
   let recentID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(recentID, encryptPayload({
@@ -742,23 +712,17 @@ add_task(async function test_filter_dupl
 });
 
 add_task(async function test_command_sync() {
   _("Ensure that commands are synced across clients.");
 
   engine._store.wipe();
   generateNewKeys(Service.collectionKeys);
 
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server   = serverForUsers({"foo": "password"}, contents);
+  let server   = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let user     = server.user("foo");
   let remoteId = Utils.makeGUID();
 
   function clientWBO(id) {
     return user.collection("clients").wbo(id);
   }
@@ -819,23 +783,17 @@ add_task(async function test_command_syn
 });
 
 add_task(async function test_clients_not_in_fxa_list() {
   _("Ensure that clients not in the FxA devices list are marked as stale.");
 
   engine._store.wipe();
   generateNewKeys(Service.collectionKeys);
 
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server   = serverForUsers({"foo": "password"}, contents);
+  let server   = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let user     = server.user("foo");
   let remoteId = Utils.makeGUID();
   let remoteId2 = Utils.makeGUID();
 
   _("Create remote client records");
   server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
@@ -1001,23 +959,17 @@ add_task(async function test_optional_cl
 
   cleanup();
 });
 
 add_task(async function test_merge_commands() {
   _("Verifies local commands for remote clients are merged with the server's");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let desktopID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
     id: desktopID,
     name: "Desktop client",
@@ -1077,23 +1029,17 @@ add_task(async function test_merge_comma
     }
   }
 });
 
 add_task(async function test_duplicate_remote_commands() {
   _("Verifies local commands for remote clients are sent only once (bug 1289287)");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let desktopID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
     id: desktopID,
     name: "Desktop client",
@@ -1142,23 +1088,17 @@ add_task(async function test_duplicate_r
     }
   }
 });
 
 add_task(async function test_upload_after_reboot() {
   _("Multiple downloads, reboot, then upload (bug 1289287)");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let deviceBID = Utils.makeGUID();
   let deviceCID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
     id: deviceBID,
@@ -1230,23 +1170,17 @@ add_task(async function test_upload_afte
     }
   }
 });
 
 add_task(async function test_keep_cleared_commands_after_reboot() {
   _("Download commands, fail upload, reboot, then apply new commands (bug 1289287)");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let deviceBID = Utils.makeGUID();
   let deviceCID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload({
     id: engine.localID,
@@ -1354,23 +1288,17 @@ add_task(async function test_keep_cleare
     }
   }
 });
 
 add_task(async function test_deleted_commands() {
   _("Verifies commands for a deleted client are discarded");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   let activeID = Utils.makeGUID();
   server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
     id: activeID,
     name: "Active client",
@@ -1418,23 +1346,17 @@ add_task(async function test_deleted_com
     }
   }
 });
 
 add_task(async function test_send_uri_ack() {
   _("Ensure a sent URI is deleted when the client syncs");
 
   let now = Date.now() / 1000;
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server = serverForUsers({"foo": "password"}, contents);
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   generateNewKeys(Service.collectionKeys);
 
   try {
     let fakeSenderID = Utils.makeGUID();
 
     _("Initial sync for empty clients collection");
@@ -1481,23 +1403,17 @@ add_task(async function test_send_uri_ac
 });
 
 add_task(async function test_command_sync() {
   _("Notify other clients when writing their record.");
 
   engine._store.wipe();
   generateNewKeys(Service.collectionKeys);
 
-  let contents = {
-    meta: {global: {engines: {clients: {version: engine.version,
-                                        syncID: engine.syncID}}}},
-    clients: {},
-    crypto: {}
-  };
-  let server    = serverForUsers({"foo": "password"}, contents);
+  let server    = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let collection = server.getCollection("foo", "clients");
   let remoteId   = Utils.makeGUID();
   let remoteId2  = Utils.makeGUID();
 
   _("Create remote client record 1");
   server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
@@ -1552,23 +1468,17 @@ add_task(async function ensureSameFlowID
   let origRecordTelemetryEvent = Service.recordTelemetryEvent;
   Service.recordTelemetryEvent = (object, method, value, extra) => {
     events.push({ object, method, value, extra });
   }
 
   try {
     // Setup 2 clients, send them a command, and ensure we get to events
     // written, both with the same flowID.
-    let contents = {
-      meta: {global: {engines: {clients: {version: engine.version,
-                                          syncID: engine.syncID}}}},
-      clients: {},
-      crypto: {}
-    };
-    let server    = serverForUsers({"foo": "password"}, contents);
+    let server    = serverForFoo(engine);
     await SyncTestingInfrastructure(server);
 
     let remoteId   = Utils.makeGUID();
     let remoteId2  = Utils.makeGUID();
 
     _("Create remote client record 1");
     server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
       id: remoteId,
--- a/services/sync/tests/unit/test_password_engine.js
+++ b/services/sync/tests/unit/test_password_engine.js
@@ -3,61 +3,26 @@ Cu.import("resource://services-sync/serv
 Cu.import("resource://testing-common/services/sync/utils.js");
 
 const LoginInfo = Components.Constructor(
   "@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init");
 
 const PropertyBag = Components.Constructor(
   "@mozilla.org/hash-property-bag;1", Ci.nsIWritablePropertyBag);
 
-function serverForEngine(engine) {
-  let clientsEngine = Service.clientsEngine;
-  return serverForUsers({"foo": "password"}, {
-    meta: {
-      global: {
-        syncID: Service.syncID,
-        storageVersion: STORAGE_VERSION,
-        engines: {
-          clients: {
-            version: clientsEngine.version,
-            syncID: clientsEngine.syncID,
-          },
-          [engine.name]: {
-            version: engine.version,
-            syncID: engine.syncID,
-          },
-        },
-      },
-    },
-    crypto: {
-      keys: encryptPayload({
-        id: "keys",
-        // Generate a fake default key bundle to avoid resetting the client
-        // before the first sync.
-        default: [
-          Svc.Crypto.generateRandomKey(),
-          Svc.Crypto.generateRandomKey(),
-        ],
-      }),
-    },
-    [engine.name]: {},
-  });
-}
-
 add_task(async function test_password_engine() {
   _("Basic password sync test");
 
   let engine = Service.engineManager.get("passwords");
   let store = engine._store;
 
-  let server = serverForEngine(engine);
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   let collection = server.user("foo").collection("passwords");
 
-  generateNewKeys(Service.collectionKeys);
   enableValidationPrefs();
 
   _("Add new login to upload during first sync");
   let newLogin;
   {
     let login = new LoginInfo("https://example.com", "", null, "username",
       "password", "", "");
     Services.logins.addLogin(login);
--- a/services/sync/tests/unit/test_telemetry.js
+++ b/services/sync/tests/unit/test_telemetry.js
@@ -95,21 +95,17 @@ add_task(async function test_basic() {
 
   Svc.Prefs.resetBranch("");
   await promiseStopServer(server);
 });
 
 add_task(async function test_processIncoming_error() {
   let engine = new BookmarksEngine(Service);
   let store  = engine._store;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bookmarks: {version: engine.version,
-                                           syncID: engine.syncID}}}},
-    bookmarks: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   let collection = server.user("foo").collection("bookmarks");
   try {
     // Create a bogus record that when synced down will provoke a
     // network error which in turn provokes an exception in _processIncoming.
     const BOGUS_GUID = "zzzzzzzzzzzz";
     let bogus_record = collection.insert(BOGUS_GUID, "I'm a bogus record!");
     bogus_record.get = function get() {
@@ -149,21 +145,17 @@ add_task(async function test_processInco
     store.wipe();
     await cleanAndGo(engine, server);
   }
 });
 
 add_task(async function test_uploading() {
   let engine = new BookmarksEngine(Service);
   let store  = engine._store;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bookmarks: {version: engine.version,
-                                           syncID: engine.syncID}}}},
-    bookmarks: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
 
   let parent = PlacesUtils.toolbarFolderId;
   let uri = Utils.makeURI("http://getfirefox.com/");
 
   let bmk_id = PlacesUtils.bookmarks.insertBookmark(parent, uri,
     PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!");
 
@@ -333,21 +325,17 @@ add_task(async function test_sync_partia
 });
 
 add_task(async function test_generic_engine_fail() {
   enableValidationPrefs();
 
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {steam: {version: engine.version,
-                                      syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   let e = new Error("generic failure message")
   engine._errToThrow = e;
 
   try {
     _(`test_generic_engine_fail: Steam tracker contents: ${
       JSON.stringify(engine._tracker.changedIDs)}`);
     let ping = await sync_and_validate_telem(true);
@@ -363,21 +351,17 @@ add_task(async function test_generic_eng
 });
 
 add_task(async function test_engine_fail_ioerror() {
   enableValidationPrefs();
 
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {steam: {version: engine.version,
-                                      syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   // create an IOError to re-throw as part of Sync.
   try {
     // (Note that fakeservices.js has replaced Utils.jsonMove etc, but for
     // this test we need the real one so we get real exceptions from the
     // filesystem.)
     await Utils._real_jsonMove("file-does-not-exist", "anything", {});
   } catch (ex) {
@@ -405,22 +389,19 @@ add_task(async function test_initial_syn
   enableValidationPrefs();
 
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
   let engines = {};
   // These are the only ones who actually have things to sync at startup.
   let engineNames = ["clients", "bookmarks", "prefs", "tabs"];
-  let conf = { meta: { global: { engines } } };
-  for (let e of engineNames) {
-    engines[e] = { version: engine.version, syncID: engine.syncID };
-    conf[e] = {};
-  }
-  let server = serverForUsers({"foo": "password"}, conf);
+  let server = serverForEnginesWithKeys({"foo": "password"}, ["bookmarks", "prefs", "tabs"].map(name =>
+    Service.engineManager.get(name)
+  ));
   await SyncTestingInfrastructure(server);
   try {
     _(`test_initial_sync_engines: Steam tracker contents: ${
       JSON.stringify(engine._tracker.changedIDs)}`);
     let ping = await wait_for_ping(() => Service.sync(), true);
 
     equal(ping.engines.find(e => e.name === "clients").outgoing[0].sent, 1);
     equal(ping.engines.find(e => e.name === "tabs").outgoing[0].sent, 1);
@@ -443,21 +424,17 @@ add_task(async function test_initial_syn
 });
 
 add_task(async function test_nserror() {
   enableValidationPrefs();
 
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {steam: {version: engine.version,
-                                      syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   engine._errToThrow = Components.Exception("NS_ERROR_UNKNOWN_HOST", Cr.NS_ERROR_UNKNOWN_HOST);
   try {
     _(`test_nserror: Steam tracker contents: ${
       JSON.stringify(engine._tracker.changedIDs)}`);
     let ping = await sync_and_validate_telem(true);
     deepEqual(ping.status, {
       service: SYNC_FAILED_PARTIAL,
@@ -522,20 +499,17 @@ add_task(async function test_discarding(
 })
 
 add_task(async function test_no_foreign_engines_in_error_ping() {
   enableValidationPrefs();
 
   Service.engineManager.register(BogusEngine);
   let engine = Service.engineManager.get("bogus");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
   engine._errToThrow = new Error("Oh no!");
   await SyncTestingInfrastructure(server);
   try {
     let ping = await sync_and_validate_telem(true);
     equal(ping.status.service, SYNC_FAILED_PARTIAL);
     ok(ping.engines.every(e => e.name !== "bogus"));
   } finally {
     await cleanAndGo(engine, server);
@@ -544,21 +518,17 @@ add_task(async function test_no_foreign_
 });
 
 add_task(async function test_sql_error() {
   enableValidationPrefs();
 
   Service.engineManager.register(SteamEngine);
   let engine = Service.engineManager.get("steam");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {steam: {version: engine.version,
-                                      syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
   await SyncTestingInfrastructure(server);
   engine._sync = function() {
     // Just grab a DB connection and issue a bogus SQL statement synchronously.
     let db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
     Async.querySpinningly(db.createAsyncStatement("select bar from foo"));
   };
   try {
     _(`test_sql_error: Steam tracker contents: ${
@@ -573,20 +543,17 @@ add_task(async function test_sql_error()
 });
 
 add_task(async function test_no_foreign_engines_in_success_ping() {
   enableValidationPrefs();
 
   Service.engineManager.register(BogusEngine);
   let engine = Service.engineManager.get("bogus");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   try {
     let ping = await sync_and_validate_telem();
     ok(ping.engines.every(e => e.name !== "bogus"));
   } finally {
     await cleanAndGo(engine, server);
     Service.engineManager.unregister(engine);
@@ -594,20 +561,17 @@ add_task(async function test_no_foreign_
 });
 
 add_task(async function test_events() {
   enableValidationPrefs();
 
   Service.engineManager.register(BogusEngine);
   let engine = Service.engineManager.get("bogus");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   try {
     let serverTime = AsyncResource.serverTime;
     Service.recordTelemetryEvent("object", "method", "value", { foo: "bar" });
     let ping = await wait_for_ping(() => Service.sync(), true, true);
     equal(ping.events.length, 1);
     let [timestamp, category, method, object, value, extra] = ping.events[0];
@@ -641,20 +605,17 @@ add_task(async function test_events() {
 });
 
 add_task(async function test_invalid_events() {
   enableValidationPrefs();
 
   Service.engineManager.register(BogusEngine);
   let engine = Service.engineManager.get("bogus");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
 
   async function checkNotRecorded(...args) {
     Service.recordTelemetryEvent.call(args);
     let ping = await wait_for_ping(() => Service.sync(), false, true);
     equal(ping.events, undefined);
   }
 
   await SyncTestingInfrastructure(server);
@@ -690,20 +651,17 @@ add_task(async function test_no_ping_for
   enableValidationPrefs();
 
   let telem = get_sync_test_telemetry();
   let oldSubmit = telem.submit;
 
   Service.engineManager.register(BogusEngine);
   let engine = Service.engineManager.get("bogus");
   engine.enabled = true;
-  let server = serverForUsers({"foo": "password"}, {
-    meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}},
-    steam: {}
-  });
+  let server = serverForFoo(engine);
 
   await SyncTestingInfrastructure(server);
   try {
     let submitPromise = new Promise(resolve => {
       telem.submit = function() {
         let result = oldSubmit.apply(this, arguments);
         resolve(result);
       };