michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: Cu.import("resource://gre/modules/PlacesUtils.jsm"); michael@0: Cu.import("resource://services-sync/constants.js"); michael@0: Cu.import("resource://services-sync/engines/history.js"); michael@0: Cu.import("resource://services-sync/engines.js"); michael@0: Cu.import("resource://services-sync/identity.js"); michael@0: Cu.import("resource://services-sync/record.js"); michael@0: Cu.import("resource://services-sync/service.js"); michael@0: Cu.import("resource://services-sync/util.js"); michael@0: Cu.import("resource://testing-common/services/sync/utils.js"); michael@0: michael@0: Service.engineManager.clear(); michael@0: michael@0: add_test(function test_processIncoming_mobile_history_batched() { michael@0: _("SyncEngine._processIncoming works on history engine."); michael@0: michael@0: let FAKE_DOWNLOAD_LIMIT = 100; michael@0: michael@0: Svc.Prefs.set("client.type", "mobile"); michael@0: PlacesUtils.history.removeAllPages(); michael@0: Service.engineManager.register(HistoryEngine); michael@0: michael@0: // A collection that logs each GET michael@0: let collection = new ServerCollection(); michael@0: collection.get_log = []; michael@0: collection._get = collection.get; michael@0: collection.get = function (options) { michael@0: this.get_log.push(options); michael@0: return this._get(options); michael@0: }; michael@0: michael@0: let server = sync_httpd_setup({ michael@0: "/1.1/foo/storage/history": collection.handler() michael@0: }); michael@0: michael@0: new SyncTestingInfrastructure(server); michael@0: michael@0: // Let's create some 234 server side history records. They're all at least michael@0: // 10 minutes old. michael@0: let visitType = Ci.nsINavHistoryService.TRANSITION_LINK; michael@0: for (var i = 0; i < 234; i++) { michael@0: let id = 'record-no' + ("00" + i).slice(-3); michael@0: let modified = Date.now()/1000 - 60*(i+10); michael@0: let payload = encryptPayload({ michael@0: id: id, michael@0: histUri: "http://foo/bar?" + id, michael@0: title: id, michael@0: sortindex: i, michael@0: visits: [{date: (modified - 5) * 1000000, type: visitType}], michael@0: deleted: false}); michael@0: michael@0: let wbo = new ServerWBO(id, payload); michael@0: wbo.modified = modified; michael@0: collection.insertWBO(wbo); michael@0: } michael@0: michael@0: let engine = Service.engineManager.get("history"); michael@0: let meta_global = Service.recordManager.set(engine.metaURL, michael@0: new WBORecord(engine.metaURL)); michael@0: meta_global.payload.engines = {history: {version: engine.version, michael@0: syncID: engine.syncID}}; michael@0: michael@0: try { michael@0: michael@0: _("On a mobile client, we get new records from the server in batches of 50."); michael@0: engine._syncStartup(); michael@0: michael@0: // Fake a lower limit. michael@0: engine.downloadLimit = FAKE_DOWNLOAD_LIMIT; michael@0: _("Last modified: " + engine.lastModified); michael@0: _("Processing..."); michael@0: engine._processIncoming(); michael@0: michael@0: _("Last modified: " + engine.lastModified); michael@0: engine._syncFinish(); michael@0: michael@0: // Back to the normal limit. michael@0: _("Running again. Should fetch none, because of lastModified"); michael@0: engine.downloadLimit = MAX_HISTORY_DOWNLOAD; michael@0: _("Processing..."); michael@0: engine._processIncoming(); michael@0: michael@0: _("Last modified: " + engine.lastModified); michael@0: _("Running again. Expecting to pull everything"); michael@0: michael@0: engine.lastModified = undefined; michael@0: engine.lastSync = 0; michael@0: _("Processing..."); michael@0: engine._processIncoming(); michael@0: michael@0: _("Last modified: " + engine.lastModified); michael@0: michael@0: // Verify that the right number of GET requests with the right michael@0: // kind of parameters were made. michael@0: do_check_eq(collection.get_log.length, michael@0: // First try: michael@0: 1 + // First 50... michael@0: 1 + // 1 GUID fetch... michael@0: // 1 fetch... michael@0: Math.ceil((FAKE_DOWNLOAD_LIMIT - 50) / MOBILE_BATCH_SIZE) + michael@0: // Second try: none michael@0: // Third try: michael@0: 1 + // First 50... michael@0: 1 + // 1 GUID fetch... michael@0: // 4 fetch... michael@0: Math.ceil((234 - 50) / MOBILE_BATCH_SIZE)); michael@0: michael@0: // Check the structure of each HTTP request. michael@0: do_check_eq(collection.get_log[0].full, 1); michael@0: do_check_eq(collection.get_log[0].limit, MOBILE_BATCH_SIZE); michael@0: do_check_eq(collection.get_log[1].full, undefined); michael@0: do_check_eq(collection.get_log[1].sort, "index"); michael@0: do_check_eq(collection.get_log[1].limit, FAKE_DOWNLOAD_LIMIT); michael@0: do_check_eq(collection.get_log[2].full, 1); michael@0: do_check_eq(collection.get_log[3].full, 1); michael@0: do_check_eq(collection.get_log[3].limit, MOBILE_BATCH_SIZE); michael@0: do_check_eq(collection.get_log[4].full, undefined); michael@0: do_check_eq(collection.get_log[4].sort, "index"); michael@0: do_check_eq(collection.get_log[4].limit, MAX_HISTORY_DOWNLOAD); michael@0: for (let i = 0; i <= Math.floor((234 - 50) / MOBILE_BATCH_SIZE); i++) { michael@0: let j = i + 5; michael@0: do_check_eq(collection.get_log[j].full, 1); michael@0: do_check_eq(collection.get_log[j].limit, undefined); michael@0: if (i < Math.floor((234 - 50) / MOBILE_BATCH_SIZE)) michael@0: do_check_eq(collection.get_log[j].ids.length, MOBILE_BATCH_SIZE); michael@0: else michael@0: do_check_eq(collection.get_log[j].ids.length, 234 % MOBILE_BATCH_SIZE); michael@0: } michael@0: michael@0: } finally { michael@0: PlacesUtils.history.removeAllPages(); michael@0: server.stop(do_test_finished); michael@0: Svc.Prefs.resetBranch(""); michael@0: Service.recordManager.clearCache(); michael@0: } michael@0: }); michael@0: michael@0: function run_test() { michael@0: generateNewKeys(Service.collectionKeys); michael@0: michael@0: run_next_test(); michael@0: }