summaryrefslogtreecommitdiffstats
path: root/services/sync
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync')
-rw-r--r--services/sync/modules/healthreport.jsm262
-rw-r--r--services/sync/moz.build1
-rw-r--r--services/sync/tests/unit/test_block_sync.js37
-rw-r--r--services/sync/tests/unit/test_fxa_migration.js279
-rw-r--r--services/sync/tests/unit/test_fxa_migration_sentinel.js150
-rw-r--r--services/sync/tests/unit/test_healthreport.js194
-rw-r--r--services/sync/tests/unit/test_healthreport_migration.js155
-rw-r--r--services/sync/tests/unit/xpcshell.ini11
8 files changed, 0 insertions, 1089 deletions
diff --git a/services/sync/modules/healthreport.jsm b/services/sync/modules/healthreport.jsm
deleted file mode 100644
index 47161c095..000000000
--- a/services/sync/modules/healthreport.jsm
+++ /dev/null
@@ -1,262 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = [
- "SyncProvider",
-];
-
-const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
-
-Cu.import("resource://gre/modules/Metrics.jsm", this);
-Cu.import("resource://gre/modules/Promise.jsm", this);
-Cu.import("resource://gre/modules/Services.jsm", this);
-Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
-
-const DAILY_LAST_NUMERIC_FIELD = {type: Metrics.Storage.FIELD_DAILY_LAST_NUMERIC};
-const DAILY_LAST_TEXT_FIELD = {type: Metrics.Storage.FIELD_DAILY_LAST_TEXT};
-const DAILY_COUNTER_FIELD = {type: Metrics.Storage.FIELD_DAILY_COUNTER};
-
-XPCOMUtils.defineLazyModuleGetter(this, "Weave",
- "resource://services-sync/main.js");
-
-function SyncMeasurement1() {
- Metrics.Measurement.call(this);
-}
-
-SyncMeasurement1.prototype = Object.freeze({
- __proto__: Metrics.Measurement.prototype,
-
- name: "sync",
- version: 1,
-
- fields: {
- enabled: DAILY_LAST_NUMERIC_FIELD,
- preferredProtocol: DAILY_LAST_TEXT_FIELD,
- activeProtocol: DAILY_LAST_TEXT_FIELD,
- syncStart: DAILY_COUNTER_FIELD,
- syncSuccess: DAILY_COUNTER_FIELD,
- syncError: DAILY_COUNTER_FIELD,
- },
-});
-
-function SyncDevicesMeasurement1() {
- Metrics.Measurement.call(this);
-}
-
-SyncDevicesMeasurement1.prototype = Object.freeze({
- __proto__: Metrics.Measurement.prototype,
-
- name: "devices",
- version: 1,
-
- fields: {},
-
- shouldIncludeField: function (name) {
- return true;
- },
-
- fieldType: function (name) {
- return Metrics.Storage.FIELD_DAILY_COUNTER;
- },
-});
-
-function SyncMigrationMeasurement1() {
- Metrics.Measurement.call(this);
-}
-
-SyncMigrationMeasurement1.prototype = Object.freeze({
- __proto__: Metrics.Measurement.prototype,
-
- name: "migration",
- version: 1,
-
- fields: {
- state: DAILY_LAST_TEXT_FIELD, // last "user" or "internal" state we saw for the day
- accepted: DAILY_COUNTER_FIELD, // number of times user tried to start migration
- declined: DAILY_COUNTER_FIELD, // number of times user closed nagging infobar
- unlinked: DAILY_LAST_NUMERIC_FIELD, // did the user decline and unlink
- },
-});
-
-this.SyncProvider = function () {
- Metrics.Provider.call(this);
-};
-SyncProvider.prototype = Object.freeze({
- __proto__: Metrics.Provider.prototype,
-
- name: "org.mozilla.sync",
-
- measurementTypes: [
- SyncDevicesMeasurement1,
- SyncMeasurement1,
- SyncMigrationMeasurement1,
- ],
-
- _OBSERVERS: [
- "weave:service:sync:start",
- "weave:service:sync:finish",
- "weave:service:sync:error",
- "fxa-migration:state-changed",
- "fxa-migration:internal-state-changed",
- "fxa-migration:internal-telemetry",
- ],
-
- postInit: function () {
- for (let o of this._OBSERVERS) {
- Services.obs.addObserver(this, o, false);
- }
-
- return Promise.resolve();
- },
-
- onShutdown: function () {
- for (let o of this._OBSERVERS) {
- Services.obs.removeObserver(this, o);
- }
-
- return Promise.resolve();
- },
-
- observe: function (subject, topic, data) {
- switch (topic) {
- case "weave:service:sync:start":
- case "weave:service:sync:finish":
- case "weave:service:sync:error":
- return this._observeSync(subject, topic, data);
-
- case "fxa-migration:state-changed":
- case "fxa-migration:internal-state-changed":
- case "fxa-migration:internal-telemetry":
- return this._observeMigration(subject, topic, data);
- }
- Cu.reportError("unexpected topic in sync healthreport provider: " + topic);
- },
-
- _observeSync: function (subject, topic, data) {
- let field;
- switch (topic) {
- case "weave:service:sync:start":
- field = "syncStart";
- break;
-
- case "weave:service:sync:finish":
- field = "syncSuccess";
- break;
-
- case "weave:service:sync:error":
- field = "syncError";
- break;
-
- default:
- Cu.reportError("unexpected sync topic in sync healthreport provider: " + topic);
- return;
- }
-
- let m = this.getMeasurement(SyncMeasurement1.prototype.name,
- SyncMeasurement1.prototype.version);
- return this.enqueueStorageOperation(function recordSyncEvent() {
- return m.incrementDailyCounter(field);
- });
- },
-
- _observeMigration: function(subject, topic, data) {
- switch (topic) {
- case "fxa-migration:state-changed":
- case "fxa-migration:internal-state-changed": {
- // We record both "user" and "internal" states in the same field. This
- // works for us as user state is always null when there is an internal
- // state.
- if (!data) {
- return; // we don't count the |null| state
- }
- let m = this.getMeasurement(SyncMigrationMeasurement1.prototype.name,
- SyncMigrationMeasurement1.prototype.version);
- return this.enqueueStorageOperation(function() {
- return m.setDailyLastText("state", data);
- });
- }
-
- case "fxa-migration:internal-telemetry": {
- // |data| is our field name.
- let m = this.getMeasurement(SyncMigrationMeasurement1.prototype.name,
- SyncMigrationMeasurement1.prototype.version);
- return this.enqueueStorageOperation(function() {
- switch (data) {
- case "accepted":
- case "declined":
- return m.incrementDailyCounter(data);
- case "unlinked":
- return m.setDailyLastNumeric(data, 1);
- default:
- Cu.reportError("Unexpected migration field in sync healthreport provider: " + data);
- return Promise.resolve();
- }
- });
- }
-
- default:
- Cu.reportError("unexpected migration topic in sync healthreport provider: " + topic);
- return;
- }
- },
-
- collectDailyData: function () {
- return this.storage.enqueueTransaction(this._populateDailyData.bind(this));
- },
-
- _populateDailyData: function* () {
- let m = this.getMeasurement(SyncMeasurement1.prototype.name,
- SyncMeasurement1.prototype.version);
-
- let svc = Cc["@mozilla.org/weave/service;1"]
- .getService(Ci.nsISupports)
- .wrappedJSObject;
-
- let enabled = svc.enabled;
- yield m.setDailyLastNumeric("enabled", enabled ? 1 : 0);
-
- // preferredProtocol is constant and only changes as the client
- // evolves.
- yield m.setDailyLastText("preferredProtocol", "1.5");
-
- let protocol = svc.fxAccountsEnabled ? "1.5" : "1.1";
- yield m.setDailyLastText("activeProtocol", protocol);
-
- if (!enabled) {
- return;
- }
-
- // Before grabbing more information, be sure the Sync service
- // is fully initialized. This has the potential to initialize
- // Sync on the spot. This may be undesired if Sync appears to
- // be enabled but it really isn't. That responsibility should
- // be up to svc.enabled to not return false positives, however.
- yield svc.whenLoaded();
-
- if (Weave.Status.service != Weave.STATUS_OK) {
- return;
- }
-
- // Device types are dynamic. So we need to dynamically create fields if
- // they don't exist.
- let dm = this.getMeasurement(SyncDevicesMeasurement1.prototype.name,
- SyncDevicesMeasurement1.prototype.version);
- let devices = Weave.Service.clientsEngine.deviceTypes;
- for (let [field, count] of devices) {
- let hasField = this.storage.hasFieldFromMeasurement(dm.id, field,
- this.storage.FIELD_DAILY_LAST_NUMERIC);
- let fieldID;
- if (hasField) {
- fieldID = this.storage.fieldIDFromMeasurement(dm.id, field);
- } else {
- fieldID = yield this.storage.registerField(dm.id, field,
- this.storage.FIELD_DAILY_LAST_NUMERIC);
- }
-
- yield this.storage.setDailyLastNumericFromFieldID(fieldID, count);
- }
- },
-});
diff --git a/services/sync/moz.build b/services/sync/moz.build
index be3aadb0a..36607ec80 100644
--- a/services/sync/moz.build
+++ b/services/sync/moz.build
@@ -21,7 +21,6 @@ EXTRA_JS_MODULES['services-sync'] += [
'modules/addonutils.js',
'modules/browserid_identity.js',
'modules/engines.js',
- 'modules/healthreport.jsm',
'modules/identity.js',
'modules/jpakeclient.js',
'modules/keys.js',
diff --git a/services/sync/tests/unit/test_block_sync.js b/services/sync/tests/unit/test_block_sync.js
deleted file mode 100644
index f83b7b740..000000000
--- a/services/sync/tests/unit/test_block_sync.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-Cu.import("resource://services-sync/main.js");
-Cu.import("resource://services-sync/util.js");
-
-// Simple test for block/unblock.
-add_task(function *() {
- Assert.ok(!Weave.Service.scheduler.isBlocked, "sync is not blocked.")
- Assert.ok(!Svc.Prefs.has("scheduler.blocked-until"), "have no blocked pref");
- Weave.Service.scheduler.blockSync();
-
- Assert.ok(Weave.Service.scheduler.isBlocked, "sync is blocked.")
- Assert.ok(Svc.Prefs.has("scheduler.blocked-until"), "have the blocked pref");
-
- Weave.Service.scheduler.unblockSync();
- Assert.ok(!Weave.Service.scheduler.isBlocked, "sync is not blocked.")
- Assert.ok(!Svc.Prefs.has("scheduler.blocked-until"), "have no blocked pref");
-
- // now check the "until" functionality.
- let until = Date.now() + 1000;
- Weave.Service.scheduler.blockSync(until);
- Assert.ok(Weave.Service.scheduler.isBlocked, "sync is blocked.")
- Assert.ok(Svc.Prefs.has("scheduler.blocked-until"), "have the blocked pref");
-
- // wait for 'until' to pass.
- yield new Promise((resolve, reject) => {
- CommonUtils.namedTimer(resolve, 1000, {}, "timer");
- });
-
- // should have automagically unblocked and removed the pref.
- Assert.ok(!Weave.Service.scheduler.isBlocked, "sync is not blocked.")
- Assert.ok(!Svc.Prefs.has("scheduler.blocked-until"), "have no blocked pref");
-});
-
-function run_test() {
- run_next_test();
-}
diff --git a/services/sync/tests/unit/test_fxa_migration.js b/services/sync/tests/unit/test_fxa_migration.js
deleted file mode 100644
index 7c65d5996..000000000
--- a/services/sync/tests/unit/test_fxa_migration.js
+++ /dev/null
@@ -1,279 +0,0 @@
-// Test the FxAMigration module
-Cu.import("resource://services-sync/FxaMigrator.jsm");
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-Cu.import("resource://services-sync/browserid_identity.js");
-
-// Set our username pref early so sync initializes with the legacy provider.
-Services.prefs.setCharPref("services.sync.username", "foo");
-// And ensure all debug messages end up being printed.
-Services.prefs.setCharPref("services.sync.log.appender.dump", "Debug");
-
-// Now import sync
-Cu.import("resource://services-sync/service.js");
-Cu.import("resource://services-sync/record.js");
-Cu.import("resource://services-sync/util.js");
-
-// And reset the username.
-Services.prefs.clearUserPref("services.sync.username");
-
-Cu.import("resource://testing-common/services/sync/utils.js");
-Cu.import("resource://testing-common/services/common/logging.js");
-Cu.import("resource://testing-common/services/sync/rotaryengine.js");
-
-const FXA_USERNAME = "someone@somewhere";
-
-// Utilities
-function promiseOneObserver(topic) {
- return new Promise((resolve, reject) => {
- let observer = function(subject, topic, data) {
- Services.obs.removeObserver(observer, topic);
- resolve({ subject: subject, data: data });
- }
- Services.obs.addObserver(observer, topic, false);
- });
-}
-
-function promiseStopServer(server) {
- return new Promise((resolve, reject) => {
- server.stop(resolve);
- });
-}
-
-
-// Helpers
-function configureLegacySync() {
- let engine = new RotaryEngine(Service);
- engine.enabled = true;
- Svc.Prefs.set("registerEngines", engine.name);
- Svc.Prefs.set("log.logger.engine.rotary", "Trace");
-
- let contents = {
- meta: {global: {engines: {rotary: {version: engine.version,
- syncID: engine.syncID}}}},
- crypto: {},
- rotary: {}
- };
-
- const USER = "foo";
- const PASSPHRASE = "abcdeabcdeabcdeabcdeabcdea";
-
- setBasicCredentials(USER, "password", PASSPHRASE);
-
- let onRequest = function(request, response) {
- // ideally we'd only do this while a legacy user is configured, but WTH.
- response.setHeader("x-weave-alert", JSON.stringify({code: "soft-eol"}));
- }
- let server = new SyncServer({onRequest: onRequest});
- server.registerUser(USER, "password");
- server.createContents(USER, contents);
- server.start();
-
- Service.serverURL = server.baseURI;
- Service.clusterURL = server.baseURI;
- Service.identity.username = USER;
- Service._updateCachedURLs();
-
- Service.engineManager._engines[engine.name] = engine;
-
- return [engine, server];
-}
-
-function configureFxa() {
- Services.prefs.setCharPref("identity.fxaccounts.auth.uri", "http://localhost");
-}
-
-add_task(function *testMigration() {
- configureFxa();
-
- // when we do a .startOver we want the new provider.
- let oldValue = Services.prefs.getBoolPref("services.sync-testing.startOverKeepIdentity");
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", false);
-
- // disable the addons engine - this engine choice is arbitrary, but we
- // want to check it remains disabled after migration.
- Services.prefs.setBoolPref("services.sync.engine.addons", false);
-
- do_register_cleanup(() => {
- Services.prefs.setBoolPref("services.sync-testing.startOverKeepIdentity", oldValue)
- Services.prefs.setBoolPref("services.sync.engine.addons", true);
- });
-
- // No sync user - that should report no user-action necessary.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()), null,
- "no user state when complete");
-
- // Arrange for a legacy sync user and manually bump the migrator
- let [engine, server] = configureLegacySync();
-
- // Check our disabling of the "addons" engine worked, and for good measure,
- // that the "passwords" engine is enabled.
- Assert.ok(!Service.engineManager.get("addons").enabled, "addons is disabled");
- Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is enabled");
-
- // monkey-patch the migration sentinel code so we know it was called.
- let haveStartedSentinel = false;
- let origSetFxAMigrationSentinel = Service.setFxAMigrationSentinel;
- let promiseSentinelWritten = new Promise((resolve, reject) => {
- Service.setFxAMigrationSentinel = function(arg) {
- haveStartedSentinel = true;
- return origSetFxAMigrationSentinel.call(Service, arg).then(result => {
- Service.setFxAMigrationSentinel = origSetFxAMigrationSentinel;
- resolve(result);
- return result;
- });
- }
- });
-
- // We are now configured for legacy sync, but we aren't in an EOL state yet,
- // so should still be not waiting for a user.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()), null,
- "no user state before server EOL");
-
- // Start a sync - this will cause an EOL notification which the migrator's
- // observer will notice.
- let promise = promiseOneObserver("fxa-migration:state-changed");
- _("Starting sync");
- Service.sync();
- _("Finished sync");
-
- // We should have seen the observer, so be waiting for an FxA user.
- Assert.equal((yield promise).data, fxaMigrator.STATE_USER_FXA, "now waiting for FxA.")
-
- // Re-calling our user-state promise should also reflect the same state.
- Assert.equal((yield fxaMigrator._queueCurrentUserState()),
- fxaMigrator.STATE_USER_FXA,
- "still waiting for FxA.");
-
- // arrange for an unverified FxA user.
- let config = makeIdentityConfig({username: FXA_USERNAME});
- let fxa = new FxAccounts({});
- config.fxaccount.user.email = config.username;
- delete config.fxaccount.user.verified;
- // *sob* - shouldn't need this boilerplate
- fxa.internal.currentAccountState.getCertificate = function(data, keyPair, mustBeValidUntil) {
- this.cert = {
- validUntil: fxa.internal.now() + CERT_LIFETIME,
- cert: "certificate",
- };
- return Promise.resolve(this.cert.cert);
- };
-
- // As soon as we set the FxA user the observers should fire and magically
- // transition.
- promise = promiseOneObserver("fxa-migration:state-changed");
- fxAccounts.setSignedInUser(config.fxaccount.user);
-
- let observerInfo = yield promise;
- Assert.equal(observerInfo.data,
- fxaMigrator.STATE_USER_FXA_VERIFIED,
- "now waiting for verification");
- Assert.ok(observerInfo.subject instanceof Ci.nsISupportsString,
- "email was passed to observer");
- Assert.equal(observerInfo.subject.data,
- FXA_USERNAME,
- "email passed to observer is correct");
-
- // should have seen the user set, so state should automatically update.
- Assert.equal((yield fxaMigrator._queueCurrentUserState()),
- fxaMigrator.STATE_USER_FXA_VERIFIED,
- "now waiting for verification");
-
- // Before we verify the user, fire off a sync that calls us back during
- // the sync and before it completes - this way we can ensure we do the right
- // thing in terms of blocking sync and waiting for it to complete.
-
- let wasWaiting = false;
- // This is a PITA as sync is pseudo-blocking.
- engine._syncFinish = function () {
- // We aren't in a generator here, so use a helper to block on promises.
- function getState() {
- let cb = Async.makeSpinningCallback();
- fxaMigrator._queueCurrentUserState().then(state => cb(null, state));
- return cb.wait();
- }
- // should still be waiting for verification.
- Assert.equal(getState(), fxaMigrator.STATE_USER_FXA_VERIFIED,
- "still waiting for verification");
-
- // arrange for the user to be verified. The fxAccount's mock story is
- // broken, so go behind its back.
- config.fxaccount.user.verified = true;
- fxAccounts.setSignedInUser(config.fxaccount.user);
- Services.obs.notifyObservers(null, ONVERIFIED_NOTIFICATION, null);
-
- // spinningly wait for the migrator to catch up - sync is running so
- // we should be in a 'null' user-state as there is no user-action
- // necessary.
- let cb = Async.makeSpinningCallback();
- promiseOneObserver("fxa-migration:state-changed").then(({ data: state }) => cb(null, state));
- Assert.equal(cb.wait(), null, "no user action necessary while sync completes.");
-
- // We must not have started writing the sentinel yet.
- Assert.ok(!haveStartedSentinel, "haven't written a sentinel yet");
-
- // sync should be blocked from continuing
- Assert.ok(Service.scheduler.isBlocked, "sync is blocked.")
-
- wasWaiting = true;
- throw ex;
- };
-
- _("Starting sync");
- Service.sync();
- _("Finished sync");
-
- // mock sync so we can ensure the final sync is scheduled with the FxA user.
- // (letting a "normal" sync complete is a PITA without mocking huge amounts
- // of FxA infra)
- let promiseFinalSync = new Promise((resolve, reject) => {
- let oldSync = Service.sync;
- Service.sync = function() {
- Service.sync = oldSync;
- resolve();
- }
- });
-
- Assert.ok(wasWaiting, "everything was good while sync was running.")
-
- // The migration is now going to run to completion.
- // sync should still be "blocked"
- Assert.ok(Service.scheduler.isBlocked, "sync is blocked.");
-
- // We should see the migration sentinel written and it should return true.
- Assert.ok((yield promiseSentinelWritten), "wrote the sentinel");
-
- // And we should see a new sync start
- yield promiseFinalSync;
-
- // and we should be configured for FxA
- let WeaveService = Cc["@mozilla.org/weave/service;1"]
- .getService(Components.interfaces.nsISupports)
- .wrappedJSObject;
- Assert.ok(WeaveService.fxAccountsEnabled, "FxA is enabled");
- Assert.ok(Service.identity instanceof BrowserIDManager,
- "sync is configured with the browserid_identity provider.");
- Assert.equal(Service.identity.username, config.username, "correct user configured")
- Assert.ok(!Service.scheduler.isBlocked, "sync is not blocked.")
- // and the user state should remain null.
- Assert.deepEqual((yield fxaMigrator._queueCurrentUserState()),
- null,
- "still no user action necessary");
- // and our engines should be in the same enabled/disabled state as before.
- Assert.ok(!Service.engineManager.get("addons").enabled, "addons is still disabled");
- Assert.ok(Service.engineManager.get("passwords").enabled, "passwords is still enabled");
-
- // aaaand, we are done - clean up.
- yield promiseStopServer(server);
-});
-
-
-function run_test() {
- initTestLogging();
- do_register_cleanup(() => {
- fxaMigrator.finalize();
- Svc.Prefs.resetBranch("");
- });
- run_next_test();
-}
diff --git a/services/sync/tests/unit/test_fxa_migration_sentinel.js b/services/sync/tests/unit/test_fxa_migration_sentinel.js
deleted file mode 100644
index bed2dd756..000000000
--- a/services/sync/tests/unit/test_fxa_migration_sentinel.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// Test the reading and writing of the sync migration sentinel.
-Cu.import("resource://gre/modules/Promise.jsm");
-Cu.import("resource://gre/modules/FxAccounts.jsm");
-Cu.import("resource://gre/modules/FxAccountsCommon.js");
-
-Cu.import("resource://testing-common/services/sync/utils.js");
-Cu.import("resource://testing-common/services/common/logging.js");
-
-Cu.import("resource://services-sync/record.js");
-
-// Set our username pref early so sync initializes with the legacy provider.
-Services.prefs.setCharPref("services.sync.username", "foo");
-
-// Now import sync
-Cu.import("resource://services-sync/service.js");
-
-const USER = "foo";
-const PASSPHRASE = "abcdeabcdeabcdeabcdeabcdea";
-
-function promiseStopServer(server) {
- return new Promise((resolve, reject) => {
- server.stop(resolve);
- });
-}
-
-let numServerRequests = 0;
-
-// Helpers
-function configureLegacySync() {
- let contents = {
- meta: {global: {}},
- crypto: {},
- };
-
- setBasicCredentials(USER, "password", PASSPHRASE);
-
- numServerRequests = 0;
- let server = new SyncServer({
- onRequest: () => {
- ++numServerRequests
- }
- });
- server.registerUser(USER, "password");
- server.createContents(USER, contents);
- server.start();
-
- Service.serverURL = server.baseURI;
- Service.clusterURL = server.baseURI;
- Service.identity.username = USER;
- Service._updateCachedURLs();
-
- return server;
-}
-
-// Test a simple round-trip of the get/set functions.
-add_task(function *() {
- // Arrange for a legacy sync user.
- let server = configureLegacySync();
-
- Assert.equal((yield Service.getFxAMigrationSentinel()), null, "no sentinel to start");
-
- let sentinel = {foo: "bar"};
- yield Service.setFxAMigrationSentinel(sentinel);
-
- Assert.deepEqual((yield Service.getFxAMigrationSentinel()), sentinel, "got the sentinel back");
-
- yield promiseStopServer(server);
-});
-
-// Test the records are cached by the record manager.
-add_task(function *() {
- // Arrange for a legacy sync user.
- let server = configureLegacySync();
- Service.login();
-
- // Reset the request count here as the login would have made some.
- numServerRequests = 0;
-
- Assert.equal((yield Service.getFxAMigrationSentinel()), null, "no sentinel to start");
- Assert.equal(numServerRequests, 1, "first fetch should hit the server");
-
- let sentinel = {foo: "bar"};
- yield Service.setFxAMigrationSentinel(sentinel);
- Assert.equal(numServerRequests, 2, "setting sentinel should hit the server");
-
- Assert.deepEqual((yield Service.getFxAMigrationSentinel()), sentinel, "got the sentinel back");
- Assert.equal(numServerRequests, 2, "second fetch should not should hit the server");
-
- // Clobber the caches and ensure we still get the correct value back when we
- // do hit the server.
- Service.recordManager.clearCache();
- Assert.deepEqual((yield Service.getFxAMigrationSentinel()), sentinel, "got the sentinel back");
- Assert.equal(numServerRequests, 3, "should have re-hit the server with empty caches");
-
- yield promiseStopServer(server);
-});
-
-// Test the records are cached by a sync.
-add_task(function* () {
- let server = configureLegacySync();
-
- // A first sync clobbers meta/global due to it being empty, so we first
- // do a sync which forces a good set of data on the server.
- Service.sync();
-
- // Now create a sentinel exists on the server. It's encrypted, so we need to
- // put an encrypted version.
- let cryptoWrapper = new CryptoWrapper("meta", "fxa_credentials");
- let sentinel = {foo: "bar"};
- cryptoWrapper.cleartext = {
- id: "fxa_credentials",
- sentinel: sentinel,
- deleted: false,
- }
- cryptoWrapper.encrypt(Service.identity.syncKeyBundle);
- let payload = {
- ciphertext: cryptoWrapper.ciphertext,
- IV: cryptoWrapper.IV,
- hmac: cryptoWrapper.hmac,
- };
-
- server.createContents(USER, {
- meta: {fxa_credentials: payload},
- crypto: {},
- });
-
- // Another sync - this will cause the encrypted record to be fetched.
- Service.sync();
- // Reset the request count here as the sync will have made many!
- numServerRequests = 0;
-
- // Asking for the sentinel should use the copy cached in the record manager.
- Assert.deepEqual((yield Service.getFxAMigrationSentinel()), sentinel, "got it");
- Assert.equal(numServerRequests, 0, "should not have hit the server");
-
- // And asking for it again should work (we have to work around the fact the
- // ciphertext is clobbered on first decrypt...)
- Assert.deepEqual((yield Service.getFxAMigrationSentinel()), sentinel, "got it again");
- Assert.equal(numServerRequests, 0, "should not have hit the server");
-
- yield promiseStopServer(server);
-});
-
-function run_test() {
- initTestLogging();
- run_next_test();
-}
diff --git a/services/sync/tests/unit/test_healthreport.js b/services/sync/tests/unit/test_healthreport.js
deleted file mode 100644
index 486320b6a..000000000
--- a/services/sync/tests/unit/test_healthreport.js
+++ /dev/null
@@ -1,194 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Metrics.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
-Cu.import("resource://gre/modules/Promise.jsm", this);
-Cu.import("resource://services-sync/main.js", this);
-Cu.import("resource://services-sync/healthreport.jsm", this);
-Cu.import("resource://testing-common/services/common/logging.js", this);
-Cu.import("resource://testing-common/services/healthreport/utils.jsm", this);
-
-function run_test() {
- initTestLogging();
-
- run_next_test();
-}
-
-add_task(function test_constructor() {
- let provider = new SyncProvider();
-});
-
-// Provider can initialize and de-initialize properly.
-add_task(function* test_init() {
- let storage = yield Metrics.Storage("init");
- let provider = new SyncProvider();
- yield provider.init(storage);
- yield provider.shutdown();
- yield storage.close();
-});
-
-add_task(function* test_collect() {
- let storage = yield Metrics.Storage("collect");
- let provider = new SyncProvider();
- yield provider.init(storage);
-
- // Initially nothing should be configured.
- let now = new Date();
- yield provider.collectDailyData();
-
- let m = provider.getMeasurement("sync", 1);
- let values = yield m.getValues();
- Assert.equal(values.days.size, 1);
- Assert.ok(values.days.hasDay(now));
- let day = values.days.getDay(now);
- Assert.ok(day.has("enabled"));
- Assert.ok(day.has("activeProtocol"));
- Assert.ok(day.has("preferredProtocol"));
- Assert.equal(day.get("enabled"), 0);
- Assert.equal(day.get("preferredProtocol"), "1.5");
- Assert.equal(day.get("activeProtocol"), "1.5",
- "Protocol without setup should be FX Accounts version.");
-
- // Now check for old Sync setup.
- let branch = new Preferences("services.sync.");
- branch.set("username", "foo");
- branch.reset("fxaccounts.enabled");
- yield provider.collectDailyData();
- values = yield m.getValues();
- Assert.equal(values.days.getDay(now).get("activeProtocol"), "1.1",
- "Protocol with old Sync setup is correct.");
-
- Assert.equal(Weave.Status.__authManager, undefined, "Detect code changes");
-
- // Let's enable Sync so we can get more useful data.
- // We need to do this because the FHR probe only records more info if Sync
- // is configured properly.
- Weave.Service.identity.account = "johndoe";
- Weave.Service.identity.basicPassword = "ilovejane";
- Weave.Service.identity.syncKey = Weave.Utils.generatePassphrase();
- Weave.Service.clusterURL = "http://localhost/";
- Assert.equal(Weave.Status.checkSetup(), Weave.STATUS_OK);
-
- yield provider.collectDailyData();
- values = yield m.getValues();
- day = values.days.getDay(now);
- Assert.equal(day.get("enabled"), 1);
-
- // An empty account should have 1 device: us.
- let dm = provider.getMeasurement("devices", 1);
- values = yield dm.getValues();
- Assert.ok(values.days.hasDay(now));
- day = values.days.getDay(now);
- Assert.equal(day.size, 1);
- let engine = Weave.Service.clientsEngine;
- Assert.ok(engine);
- Assert.ok(day.has(engine.localType));
- Assert.equal(day.get(engine.localType), 1);
-
- // Add some devices and ensure they show up.
- engine._store._remoteClients["id1"] = {type: "mobile"};
- engine._store._remoteClients["id2"] = {type: "tablet"};
- engine._store._remoteClients["id3"] = {type: "mobile"};
-
- yield provider.collectDailyData();
- values = yield dm.getValues();
- day = values.days.getDay(now);
-
- let expected = {
- "foobar": 0,
- "tablet": 1,
- "mobile": 2,
- "desktop": 0,
- };
-
- for (let type in expected) {
- let count = expected[type];
-
- if (engine.localType == type) {
- count++;
- }
-
- if (!count) {
- Assert.ok(!day.has(type));
- } else {
- Assert.ok(day.has(type));
- Assert.equal(day.get(type), count);
- }
- }
-
- engine._store._remoteClients = {};
-
- yield provider.shutdown();
- yield storage.close();
-});
-
-add_task(function* test_sync_events() {
- let storage = yield Metrics.Storage("sync_events");
- let provider = new SyncProvider();
- yield provider.init(storage);
-
- let m = provider.getMeasurement("sync", 1);
-
- for (let i = 0; i < 5; i++) {
- Services.obs.notifyObservers(null, "weave:service:sync:start", null);
- }
-
- for (let i = 0; i < 3; i++) {
- Services.obs.notifyObservers(null, "weave:service:sync:finish", null);
- }
-
- for (let i = 0; i < 2; i++) {
- Services.obs.notifyObservers(null, "weave:service:sync:error", null);
- }
-
- // Wait for storage to complete.
- yield m.storage.enqueueOperation(() => {
- return Promise.resolve();
- });
-
- let values = yield m.getValues();
- let now = new Date();
- Assert.ok(values.days.hasDay(now));
- let day = values.days.getDay(now);
-
- Assert.ok(day.has("syncStart"));
- Assert.ok(day.has("syncSuccess"));
- Assert.ok(day.has("syncError"));
- Assert.equal(day.get("syncStart"), 5);
- Assert.equal(day.get("syncSuccess"), 3);
- Assert.equal(day.get("syncError"), 2);
-
- yield provider.shutdown();
- yield storage.close();
-});
-
-add_task(function* test_healthreporter_json() {
- let reporter = yield getHealthReporter("healthreporter_json");
- yield reporter.init();
- try {
- yield reporter._providerManager.registerProvider(new SyncProvider());
- yield reporter.collectMeasurements();
- let payload = yield reporter.getJSONPayload(true);
- let now = new Date();
- let today = reporter._formatDate(now);
-
- Assert.ok(today in payload.data.days);
- let day = payload.data.days[today];
-
- Assert.ok("org.mozilla.sync.sync" in day);
- Assert.ok("org.mozilla.sync.devices" in day);
-
- let devices = day["org.mozilla.sync.devices"];
- let engine = Weave.Service.clientsEngine;
- Assert.ok(engine);
- let type = engine.localType;
- Assert.ok(type);
- Assert.ok(type in devices);
- Assert.equal(devices[type], 1);
- } finally {
- reporter._shutdown();
- }
-});
diff --git a/services/sync/tests/unit/test_healthreport_migration.js b/services/sync/tests/unit/test_healthreport_migration.js
deleted file mode 100644
index 23f756748..000000000
--- a/services/sync/tests/unit/test_healthreport_migration.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-Cu.import("resource://gre/modules/Metrics.jsm", this);
-Cu.import("resource://gre/modules/Preferences.jsm", this);
-Cu.import("resource://gre/modules/Promise.jsm", this);
-Cu.import("resource://services-sync/healthreport.jsm", this);
-Cu.import("resource://services-sync/FxaMigrator.jsm", this);
-Cu.import("resource://testing-common/services/common/logging.js", this);
-Cu.import("resource://testing-common/services/healthreport/utils.jsm", this);
-
-
-function run_test() {
- initTestLogging();
-
- run_next_test();
-}
-
-add_task(function* test_no_data() {
- let storage = yield Metrics.Storage("collect");
- let provider = new SyncProvider();
- yield provider.init(storage);
-
- try {
- // Initially nothing should be configured.
- let now = new Date();
- yield provider.collectDailyData();
-
- let m = provider.getMeasurement("migration", 1);
- let values = yield m.getValues();
- Assert.equal(values.days.size, 0);
- Assert.ok(!values.days.hasDay(now));
- } finally {
- yield provider.shutdown();
- yield storage.close();
- }
-});
-
-function checkCorrectStateRecorded(provider, state) {
- // Wait for storage to complete.
- yield m.storage.enqueueOperation(() => {
- return Promise.resolve();
- });
-
- let m = provider.getMeasurement("migration", 1);
- let values = yield m.getValues();
- Assert.equal(values.days.size, 1);
- Assert.ok(values.days.hasDay(now));
- let day = values.days.getDay(now);
-
- Assert.ok(day.has("state"));
- Assert.equal(day.get("state"), state);
-}
-
-add_task(function* test_state() {
- let storage = yield Metrics.Storage("collect");
- let provider = new SyncProvider();
- yield provider.init(storage);
-
- try {
- // Initially nothing should be configured.
- let now = new Date();
-
- // We record both a "user" and "internal" state in the same field.
- // So simulate a "user" state first.
- Services.obs.notifyObservers(null, "fxa-migration:state-changed",
- fxaMigrator.STATE_USER_FXA_VERIFIED);
- checkCorrectStateRecorded(provider, fxaMigrator.STATE_USER_FXA_VERIFIED);
-
- // And an internal state.
- Services.obs.notifyObservers(null, "fxa-migration:internal-state-changed",
- fxaMigrator.STATE_INTERNAL_WAITING_SYNC_COMPLETE);
- checkCorrectStateRecorded(provider, fxaMigrator.STATE_INTERNAL_WAITING_SYNC_COMPLETE);
- } finally {
- yield provider.shutdown();
- yield storage.close();
- }
-});
-
-add_task(function* test_flags() {
- let storage = yield Metrics.Storage("collect");
- let provider = new SyncProvider();
- yield provider.init(storage);
-
- try {
- // Initially nothing should be configured.
- let now = new Date();
-
- let m = provider.getMeasurement("migration", 1);
-
- let record = function*(what) {
- Services.obs.notifyObservers(null, "fxa-migration:internal-telemetry", what);
- // Wait for storage to complete.
- yield m.storage.enqueueOperation(Promise.resolve);
- let values = yield m.getValues();
- Assert.equal(values.days.size, 1);
- return values.days.getDay(now);
- }
-
- let values = yield m.getValues();
- Assert.equal(values.days.size, 1);
- let day = values.days.getDay(now);
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_UNLINKED));
-
- // let's send an unknown value to ensure our error mitigation works.
- day = yield record("unknown");
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_UNLINKED));
-
- // record an fxaMigrator.TELEMETRY_ACCEPTED state.
- day = yield record(fxaMigrator.TELEMETRY_ACCEPTED);
- Assert.ok(day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_UNLINKED));
- Assert.equal(day.get(fxaMigrator.TELEMETRY_ACCEPTED), 1);
-
- // and again - it should get 2.
- day = yield record(fxaMigrator.TELEMETRY_ACCEPTED);
- Assert.equal(day.get(fxaMigrator.TELEMETRY_ACCEPTED), 2);
-
- // record fxaMigrator.TELEMETRY_DECLINED - also a counter.
- day = yield record(fxaMigrator.TELEMETRY_DECLINED);
- Assert.ok(day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_UNLINKED));
- Assert.equal(day.get(fxaMigrator.TELEMETRY_ACCEPTED), 2);
- Assert.equal(day.get(fxaMigrator.TELEMETRY_DECLINED), 1);
-
- day = yield record(fxaMigrator.TELEMETRY_DECLINED);
- Assert.ok(day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(!day.has(fxaMigrator.TELEMETRY_UNLINKED));
- Assert.equal(day.get(fxaMigrator.TELEMETRY_ACCEPTED), 2);
- Assert.equal(day.get(fxaMigrator.TELEMETRY_DECLINED), 2);
-
- // and fxaMigrator.TELEMETRY_UNLINKED - this is conceptually a "daily bool".
- // (ie, it's DAILY_LAST_NUMERIC_FIELD and only ever has |1| written to it)
- day = yield record(fxaMigrator.TELEMETRY_UNLINKED);
- Assert.ok(day.has(fxaMigrator.TELEMETRY_ACCEPTED));
- Assert.ok(day.has(fxaMigrator.TELEMETRY_DECLINED));
- Assert.ok(day.has(fxaMigrator.TELEMETRY_UNLINKED));
- Assert.equal(day.get(fxaMigrator.TELEMETRY_UNLINKED), 1);
- // and doing it again still leaves us with |1|
- day = yield record(fxaMigrator.TELEMETRY_UNLINKED);
- Assert.equal(day.get(fxaMigrator.TELEMETRY_UNLINKED), 1);
- } finally {
- yield provider.shutdown();
- yield storage.close();
- }
-});
diff --git a/services/sync/tests/unit/xpcshell.ini b/services/sync/tests/unit/xpcshell.ini
index dc33c0eb2..7e97835ac 100644
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -168,15 +168,4 @@ skip-if = debug
[test_tab_store.js]
[test_tab_tracker.js]
-[test_healthreport.js]
-skip-if = ! healthreport
-
-[test_healthreport_migration.js]
-skip-if = ! healthreport
-
[test_warn_on_truncated_response.js]
-
-# FxA migration
-[test_block_sync.js]
-[test_fxa_migration.js]
-[test_fxa_migration_sentinel.js]