diff options
Diffstat (limited to 'services/sync/tests/unit/test_telemetry.js')
-rw-r--r-- | services/sync/tests/unit/test_telemetry.js | 564 |
1 files changed, 0 insertions, 564 deletions
diff --git a/services/sync/tests/unit/test_telemetry.js b/services/sync/tests/unit/test_telemetry.js deleted file mode 100644 index 50a3d136b..000000000 --- a/services/sync/tests/unit/test_telemetry.js +++ /dev/null @@ -1,564 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -Cu.import("resource://services-common/observers.js"); -Cu.import("resource://services-sync/telemetry.js"); -Cu.import("resource://services-sync/service.js"); -Cu.import("resource://services-sync/record.js"); -Cu.import("resource://services-sync/resource.js"); -Cu.import("resource://services-sync/constants.js"); -Cu.import("resource://services-sync/engines.js"); -Cu.import("resource://services-sync/engines/bookmarks.js"); -Cu.import("resource://services-sync/engines/clients.js"); -Cu.import("resource://testing-common/services/sync/utils.js"); -Cu.import("resource://testing-common/services/sync/fxa_utils.js"); -Cu.import("resource://testing-common/services/sync/rotaryengine.js"); -Cu.import("resource://gre/modules/osfile.jsm", this); - -Cu.import("resource://gre/modules/PlacesUtils.jsm"); -Cu.import("resource://services-sync/util.js"); - -initTestLogging("Trace"); - -function SteamStore(engine) { - Store.call(this, "Steam", engine); -} - -SteamStore.prototype = { - __proto__: Store.prototype, -}; - -function SteamTracker(name, engine) { - Tracker.call(this, name || "Steam", engine); -} - -SteamTracker.prototype = { - __proto__: Tracker.prototype -}; - -function SteamEngine(service) { - Engine.call(this, "steam", service); -} - -SteamEngine.prototype = { - __proto__: Engine.prototype, - _storeObj: SteamStore, - _trackerObj: SteamTracker, - _errToThrow: null, - _sync() { - if (this._errToThrow) { - throw this._errToThrow; - } - } -}; - -function BogusEngine(service) { - Engine.call(this, "bogus", service); -} - -BogusEngine.prototype = Object.create(SteamEngine.prototype); - -function cleanAndGo(server) { - Svc.Prefs.resetBranch(""); - Svc.Prefs.set("log.logger.engine.rotary", "Trace"); - Service.recordManager.clearCache(); - return new Promise(resolve => server.stop(resolve)); -} - -// Avoid addon manager complaining about not being initialized -Service.engineManager.unregister("addons"); - -add_identity_test(this, function *test_basic() { - let helper = track_collections_helper(); - let upd = helper.with_updated_collection; - - yield configureIdentity({ username: "johndoe" }); - let handlers = { - "/1.1/johndoe/info/collections": helper.handler, - "/1.1/johndoe/storage/crypto/keys": upd("crypto", new ServerWBO("keys").handler()), - "/1.1/johndoe/storage/meta/global": upd("meta", new ServerWBO("global").handler()) - }; - - let collections = ["clients", "bookmarks", "forms", "history", "passwords", "prefs", "tabs"]; - - for (let coll of collections) { - handlers["/1.1/johndoe/storage/" + coll] = upd(coll, new ServerCollection({}, true).handler()); - } - - let server = httpd_setup(handlers); - Service.serverURL = server.baseURI; - - yield sync_and_validate_telem(true); - - yield new Promise(resolve => server.stop(resolve)); -}); - -add_task(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: {} - }); - new SyncTestingInfrastructure(server.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() { - throw "Sync this!"; - }; - // Make the 10 minutes old so it will only be synced in the toFetch phase. - bogus_record.modified = Date.now() / 1000 - 60 * 10; - engine.lastSync = Date.now() / 1000 - 60; - engine.toFetch = [BOGUS_GUID]; - - let error, ping; - try { - yield sync_engine_and_validate_telem(engine, true, errPing => ping = errPing); - } catch(ex) { - error = ex; - } - ok(!!error); - ok(!!ping); - equal(ping.uid, "0".repeat(32)); - deepEqual(ping.failureReason, { - name: "othererror", - error: "error.engine.reason.record_download_fail" - }); - - equal(ping.engines.length, 1); - equal(ping.engines[0].name, "bookmarks"); - deepEqual(ping.engines[0].failureReason, { - name: "othererror", - error: "error.engine.reason.record_download_fail" - }); - - } finally { - store.wipe(); - yield cleanAndGo(server); - } -}); - -add_task(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: {} - }); - new SyncTestingInfrastructure(server.server); - - let parent = PlacesUtils.toolbarFolderId; - let uri = Utils.makeURI("http://getfirefox.com/"); - let title = "Get Firefox"; - - let bmk_id = PlacesUtils.bookmarks.insertBookmark(parent, uri, - PlacesUtils.bookmarks.DEFAULT_INDEX, "Get Firefox!"); - - let guid = store.GUIDForId(bmk_id); - let record = store.createRecord(guid); - - let collection = server.user("foo").collection("bookmarks"); - try { - let ping = yield sync_engine_and_validate_telem(engine, false); - ok(!!ping); - equal(ping.engines.length, 1); - equal(ping.engines[0].name, "bookmarks"); - ok(!!ping.engines[0].outgoing); - greater(ping.engines[0].outgoing[0].sent, 0) - ok(!ping.engines[0].incoming); - - PlacesUtils.bookmarks.setItemTitle(bmk_id, "New Title"); - - store.wipe(); - engine.resetClient(); - - ping = yield sync_engine_and_validate_telem(engine, false); - equal(ping.engines.length, 1); - equal(ping.engines[0].name, "bookmarks"); - equal(ping.engines[0].outgoing.length, 1); - ok(!!ping.engines[0].incoming); - - } finally { - // Clean up. - store.wipe(); - yield cleanAndGo(server); - } -}); - -add_task(function *test_upload_failed() { - Service.identity.username = "foo"; - let collection = new ServerCollection(); - collection._wbos.flying = new ServerWBO('flying'); - - let server = sync_httpd_setup({ - "/1.1/foo/storage/rotary": collection.handler() - }); - - let syncTesting = new SyncTestingInfrastructure(server); - - let engine = new RotaryEngine(Service); - engine.lastSync = 123; // needs to be non-zero so that tracker is queried - engine.lastSyncLocal = 456; - engine._store.items = { - flying: "LNER Class A3 4472", - scotsman: "Flying Scotsman", - peppercorn: "Peppercorn Class" - }; - const FLYING_CHANGED = 12345; - const SCOTSMAN_CHANGED = 23456; - const PEPPERCORN_CHANGED = 34567; - engine._tracker.addChangedID("flying", FLYING_CHANGED); - engine._tracker.addChangedID("scotsman", SCOTSMAN_CHANGED); - engine._tracker.addChangedID("peppercorn", PEPPERCORN_CHANGED); - - let meta_global = Service.recordManager.set(engine.metaURL, new WBORecord(engine.metaURL)); - meta_global.payload.engines = { rotary: { version: engine.version, syncID: engine.syncID } }; - - try { - engine.enabled = true; - let ping = yield sync_engine_and_validate_telem(engine, true); - ok(!!ping); - equal(ping.engines.length, 1); - equal(ping.engines[0].incoming, null); - deepEqual(ping.engines[0].outgoing, [{ sent: 3, failed: 2 }]); - engine.lastSync = 123; - engine.lastSyncLocal = 456; - - ping = yield 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 { - yield cleanAndGo(server); - } -}); - -add_task(function *test_sync_partialUpload() { - Service.identity.username = "foo"; - - let collection = new ServerCollection(); - let server = sync_httpd_setup({ - "/1.1/foo/storage/rotary": collection.handler() - }); - let syncTesting = new SyncTestingInfrastructure(server); - generateNewKeys(Service.collectionKeys); - - let engine = new RotaryEngine(Service); - engine.lastSync = 123; - engine.lastSyncLocal = 456; - - - // Create a bunch of records (and server side handlers) - for (let i = 0; i < 234; i++) { - let id = 'record-no-' + i; - engine._store.items[id] = "Record No. " + i; - engine._tracker.addChangedID(id, i); - // Let two items in the first upload batch fail. - if (i != 23 && i != 42) { - collection.insert(id); - } - } - - let meta_global = Service.recordManager.set(engine.metaURL, - new WBORecord(engine.metaURL)); - meta_global.payload.engines = {rotary: {version: engine.version, - syncID: engine.syncID}}; - - try { - engine.enabled = true; - let ping = yield sync_engine_and_validate_telem(engine, true); - - ok(!!ping); - ok(!ping.failureReason); - equal(ping.engines.length, 1); - equal(ping.engines[0].name, "rotary"); - ok(!ping.engines[0].incoming); - ok(!ping.engines[0].failureReason); - deepEqual(ping.engines[0].outgoing, [{ sent: 234, failed: 2 }]); - - collection.post = function() { throw "Failure"; } - - engine._store.items["record-no-1000"] = "Record No. 1000"; - engine._tracker.addChangedID("record-no-1000", 1000); - collection.insert("record-no-1000", 1000); - - engine.lastSync = 123; - engine.lastSyncLocal = 456; - ping = null; - - try { - // should throw - yield sync_engine_and_validate_telem(engine, true, errPing => ping = errPing); - } catch (e) {} - // It would be nice if we had a more descriptive error for this... - let uploadFailureError = { - name: "othererror", - error: "error.engine.reason.record_upload_fail" - }; - - ok(!!ping); - deepEqual(ping.failureReason, uploadFailureError); - equal(ping.engines.length, 1); - equal(ping.engines[0].name, "rotary"); - deepEqual(ping.engines[0].incoming, { - failed: 1, - newFailed: 1, - reconciled: 232 - }); - ok(!ping.engines[0].outgoing); - deepEqual(ping.engines[0].failureReason, uploadFailureError); - - } finally { - yield cleanAndGo(server); - } -}); - -add_task(function* test_generic_engine_fail() { - Service.engineManager.register(SteamEngine); - let engine = Service.engineManager.get("steam"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {steam: {version: engine.version, - syncID: engine.syncID}}}}, - steam: {} - }); - new SyncTestingInfrastructure(server.server); - let e = new Error("generic failure message") - engine._errToThrow = e; - - try { - let ping = yield sync_and_validate_telem(true); - equal(ping.status.service, SYNC_FAILED_PARTIAL); - deepEqual(ping.engines.find(e => e.name === "steam").failureReason, { - name: "unexpectederror", - error: String(e) - }); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -}); - -add_task(function* test_engine_fail_ioerror() { - Service.engineManager.register(SteamEngine); - let engine = Service.engineManager.get("steam"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {steam: {version: engine.version, - syncID: engine.syncID}}}}, - steam: {} - }); - new SyncTestingInfrastructure(server.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.) - yield Utils._real_jsonMove("file-does-not-exist", "anything", {}); - } catch (ex) { - engine._errToThrow = ex; - } - ok(engine._errToThrow, "expecting exception"); - - try { - let ping = yield sync_and_validate_telem(true); - equal(ping.status.service, SYNC_FAILED_PARTIAL); - let failureReason = ping.engines.find(e => e.name === "steam").failureReason; - equal(failureReason.name, "unexpectederror"); - // ensure the profile dir in the exception message has been stripped. - ok(!failureReason.error.includes(OS.Constants.Path.profileDir), failureReason.error); - ok(failureReason.error.includes("[profileDir]"), failureReason.error); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -}); - -add_task(function* test_initial_sync_engines() { - Service.engineManager.register(SteamEngine); - let engine = Service.engineManager.get("steam"); - engine.enabled = true; - let store = engine._store; - 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); - new SyncTestingInfrastructure(server.server); - try { - let ping = yield 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); - - // for the rest we don't care about specifics - for (let e of ping.engines) { - if (!engineNames.includes(engine.name)) { - continue; - } - greaterOrEqual(e.took, 1); - ok(!!e.outgoing) - equal(e.outgoing.length, 1); - notEqual(e.outgoing[0].sent, undefined); - equal(e.outgoing[0].failed, undefined); - } - } finally { - yield cleanAndGo(server); - } -}); - -add_task(function* test_nserror() { - Service.engineManager.register(SteamEngine); - let engine = Service.engineManager.get("steam"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {steam: {version: engine.version, - syncID: engine.syncID}}}}, - steam: {} - }); - new SyncTestingInfrastructure(server.server); - engine._errToThrow = Components.Exception("NS_ERROR_UNKNOWN_HOST", Cr.NS_ERROR_UNKNOWN_HOST); - try { - let ping = yield sync_and_validate_telem(true); - deepEqual(ping.status, { - service: SYNC_FAILED_PARTIAL, - sync: LOGIN_FAILED_NETWORK_ERROR - }); - let enginePing = ping.engines.find(e => e.name === "steam"); - deepEqual(enginePing.failureReason, { - name: "nserror", - code: Cr.NS_ERROR_UNKNOWN_HOST - }); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -}); - -add_identity_test(this, function *test_discarding() { - let helper = track_collections_helper(); - let upd = helper.with_updated_collection; - let telem = get_sync_test_telemetry(); - telem.maxPayloadCount = 2; - telem.submissionInterval = Infinity; - let oldSubmit = telem.submit; - - let server; - try { - - yield configureIdentity({ username: "johndoe" }); - let handlers = { - "/1.1/johndoe/info/collections": helper.handler, - "/1.1/johndoe/storage/crypto/keys": upd("crypto", new ServerWBO("keys").handler()), - "/1.1/johndoe/storage/meta/global": upd("meta", new ServerWBO("global").handler()) - }; - - let collections = ["clients", "bookmarks", "forms", "history", "passwords", "prefs", "tabs"]; - - for (let coll of collections) { - handlers["/1.1/johndoe/storage/" + coll] = upd(coll, new ServerCollection({}, true).handler()); - } - - server = httpd_setup(handlers); - Service.serverURL = server.baseURI; - telem.submit = () => ok(false, "Submitted telemetry ping when we should not have"); - - for (let i = 0; i < 5; ++i) { - Service.sync(); - } - telem.submit = oldSubmit; - telem.submissionInterval = -1; - let ping = yield sync_and_validate_telem(true, true); // with this we've synced 6 times - equal(ping.syncs.length, 2); - equal(ping.discarded, 4); - } finally { - telem.maxPayloadCount = 500; - telem.submissionInterval = -1; - telem.submit = oldSubmit; - if (server) { - yield new Promise(resolve => server.stop(resolve)); - } - } -}) - -add_task(function* test_no_foreign_engines_in_error_ping() { - Service.engineManager.register(BogusEngine); - let engine = Service.engineManager.get("bogus"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}}, - steam: {} - }); - engine._errToThrow = new Error("Oh no!"); - new SyncTestingInfrastructure(server.server); - try { - let ping = yield sync_and_validate_telem(true); - equal(ping.status.service, SYNC_FAILED_PARTIAL); - ok(ping.engines.every(e => e.name !== "bogus")); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -}); - -add_task(function* test_sql_error() { - Service.engineManager.register(SteamEngine); - let engine = Service.engineManager.get("steam"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {steam: {version: engine.version, - syncID: engine.syncID}}}}, - steam: {} - }); - new SyncTestingInfrastructure(server.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 { - let ping = yield sync_and_validate_telem(true); - let enginePing = ping.engines.find(e => e.name === "steam"); - deepEqual(enginePing.failureReason, { name: "sqlerror", code: 1 }); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -}); - -add_task(function* test_no_foreign_engines_in_success_ping() { - Service.engineManager.register(BogusEngine); - let engine = Service.engineManager.get("bogus"); - engine.enabled = true; - let store = engine._store; - let server = serverForUsers({"foo": "password"}, { - meta: {global: {engines: {bogus: {version: engine.version, syncID: engine.syncID}}}}, - steam: {} - }); - - new SyncTestingInfrastructure(server.server); - try { - let ping = yield sync_and_validate_telem(); - ok(ping.engines.every(e => e.name !== "bogus")); - } finally { - Service.engineManager.unregister(engine); - yield cleanAndGo(server); - } -});
\ No newline at end of file |