Bug 673548 - Part 0a: set Content-Type in ServerWBO responses; enhance ServerCollection. r=philikon

This commit is contained in:
Richard Newman 2011-09-29 11:50:28 -07:00
Родитель 4e0565d416
Коммит 91dc3d13cf
9 изменённых файлов: 253 добавлений и 148 удалений

Просмотреть файл

@ -138,6 +138,7 @@ ServerWBO.prototype = {
case "PUT":
self.put(readBytesFromInputStream(request.bodyInputStream));
body = JSON.stringify(self.modified);
response.setHeader("Content-Type", "application/json");
response.newModified = self.modified;
break;
@ -145,6 +146,7 @@ ServerWBO.prototype = {
self.delete();
let ts = new_timestamp();
body = JSON.stringify(ts);
response.setHeader("Content-Type", "application/json");
response.newModified = ts;
break;
}
@ -157,22 +159,118 @@ ServerWBO.prototype = {
};
/*
* Represent a collection on the server. The 'wbo' attribute is a
/**
* Represent a collection on the server. The '_wbos' attribute is a
* mapping of id -> ServerWBO objects.
*
*
* Note that if you want these records to be accessible individually,
* you need to register their handlers with the server separately!
*
* Passing `true` for acceptNew will allow POSTs of new WBOs to this
* collection. New WBOs will be created and wired in on the fly.
* you need to register their handlers with the server separately, or use a
* containing HTTP server that will do so on your behalf.
*
* @param wbos
* An object mapping WBO IDs to ServerWBOs.
* @param acceptNew
* If true, POSTs to this collection URI will result in new WBOs being
* created and wired in on the fly.
* @param timestamp
* An optional timestamp value to initialize the modified time of the
* collection. This should be in the format returned by new_timestamp().
*
* @return the new ServerCollection instance.
*
*/
function ServerCollection(wbos, acceptNew) {
this.wbos = wbos || {};
function ServerCollection(wbos, acceptNew, timestamp) {
this._wbos = wbos || {};
this.acceptNew = acceptNew || false;
/*
* Track modified timestamp.
* We can't just use the timestamps of contained WBOs: an empty collection
* has a modified time.
*/
this.timestamp = timestamp || new_timestamp();
}
ServerCollection.prototype = {
/**
* Convenience accessor for our WBO keys.
* Excludes deleted items, of course.
*
* @param filter
* A predicate function (applied to the ID and WBO) which dictates
* whether to include the WBO's ID in the output.
*
* @return an array of IDs.
*/
keys: function keys(filter) {
return [id for ([id, wbo] in Iterator(this._wbos))
if (wbo.payload &&
(!filter || filter(id, wbo)))];
},
/**
* Convenience method to get an array of WBOs.
* Optionally provide a filter function.
*
* @param filter
* A predicate function, applied to the WBO, which dictates whether to
* include the WBO in the output.
*
* @return an array of ServerWBOs.
*/
wbos: function wbos(filter) {
let os = [wbo for ([id, wbo] in Iterator(this._wbos))
if (wbo.payload)];
if (filter) {
return os.filter(filter);
}
return os;
},
/**
* Convenience method to get an array of parsed ciphertexts.
*
* @return an array of the payloads of each stored WBO.
*/
payloads: function () {
return this.wbos().map(function (wbo) {
return JSON.parse(JSON.parse(wbo.payload).ciphertext);
});
},
// Just for syntactic elegance.
wbo: function wbo(id) {
return this._wbos[id];
},
payload: function payload(id) {
return this.wbo(id).payload;
},
/**
* Insert the provided WBO under its ID.
*
* @return the provided WBO.
*/
insertWBO: function insertWBO(wbo) {
return this._wbos[wbo.id] = wbo;
},
/**
* Insert the provided payload as part of a new ServerWBO with the provided
* ID.
*
* @param id
* The GUID for the WBO.
* @param payload
* The payload, as provided to the ServerWBO constructor.
*
* @return the inserted WBO.
*/
insert: function insert(id, payload) {
return this.insertWBO(new ServerWBO(id, payload));
},
_inResultSet: function(wbo, options) {
return wbo.payload
&& (!options.ids || (options.ids.indexOf(wbo.id) != -1))
@ -182,7 +280,7 @@ ServerCollection.prototype = {
count: function(options) {
options = options || {};
let c = 0;
for (let [id, wbo] in Iterator(this.wbos)) {
for (let [id, wbo] in Iterator(this._wbos)) {
if (wbo.modified && this._inResultSet(wbo, options)) {
c++;
}
@ -193,7 +291,7 @@ ServerCollection.prototype = {
get: function(options) {
let result;
if (options.full) {
let data = [wbo.get() for ([id, wbo] in Iterator(this.wbos))
let data = [wbo.get() for ([id, wbo] in Iterator(this._wbos))
// Drop deleted.
if (wbo.modified &&
this._inResultSet(wbo, options))];
@ -203,7 +301,7 @@ ServerCollection.prototype = {
// Our implementation of application/newlines
result = data.join("\n") + "\n";
} else {
let data = [id for ([id, wbo] in Iterator(this.wbos))
let data = [id for ([id, wbo] in Iterator(this._wbos))
if (this._inResultSet(wbo, options))];
if (options.limit) {
data = data.slice(0, options.limit);
@ -221,11 +319,11 @@ ServerCollection.prototype = {
// This will count records where we have an existing ServerWBO
// registered with us as successful and all other records as failed.
for each (let record in input) {
let wbo = this.wbos[record.id];
let wbo = this.wbo(record.id);
if (!wbo && this.acceptNew) {
_("Creating WBO " + JSON.stringify(record.id) + " on the fly.");
wbo = new ServerWBO(record.id);
this.wbos[record.id] = wbo;
this.insertWBO(wbo);
}
if (wbo) {
wbo.payload = record.payload;
@ -241,7 +339,7 @@ ServerCollection.prototype = {
},
delete: function(options) {
for (let [id, wbo] in Iterator(this.wbos)) {
for (let [id, wbo] in Iterator(this._wbos)) {
if (this._inResultSet(wbo, options)) {
_("Deleting " + JSON.stringify(wbo));
wbo.delete();
@ -305,6 +403,14 @@ ServerCollection.prototype = {
false);
response.setStatusLine(request.httpVersion, statusCode, status);
response.bodyOutputStream.write(body, body.length);
// Update the collection timestamp to the appropriate modified time.
// This is either a value set by the handler, or the current time.
if (request.method != "GET") {
this.timestamp = (response.newModified >= 0) ?
response.newModified :
new_timestamp();
}
};
}

Просмотреть файл

@ -119,14 +119,12 @@ add_test(function test_processIncoming_error_orderChildren() {
// the children.
let folder1_payload = store.createRecord(folder1_guid).cleartext;
folder1_payload.children.reverse();
collection.wbos[folder1_guid] = new ServerWBO(
folder1_guid, encryptPayload(folder1_payload));
collection.insert(folder1_guid, encryptPayload(folder1_payload));
// 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.wbos[BOGUS_GUID]
= new ServerWBO(BOGUS_GUID, "I'm a bogus record!");
let bogus_record = collection.insert(BOGUS_GUID, "I'm a bogus record!");
bogus_record.get = function get() {
throw "Sync this!";
};
@ -230,8 +228,9 @@ add_test(function test_restorePromptsReupload() {
_("Verify that there's only one bookmark on the server, and it's Thunderbird.");
// Of course, there's also the Bookmarks Toolbar and Bookmarks Menu...
let wbos = [id for ([id, wbo] in Iterator(collection.wbos))
if (["menu", "toolbar", "mobile", folder1_guid].indexOf(id) == -1)];
let wbos = collection.keys(function (id) {
return ["menu", "toolbar", "mobile", folder1_guid].indexOf(id) == -1;
});
do_check_eq(wbos.length, 1);
do_check_eq(wbos[0], bmk2_guid);
@ -273,9 +272,7 @@ add_test(function test_restorePromptsReupload() {
_("Verify that there's only one bookmark on the server, and it's Firefox.");
// Of course, there's also the Bookmarks Toolbar and Bookmarks Menu...
wbos = [JSON.parse(JSON.parse(wbo.payload).ciphertext)
for ([id, wbo] in Iterator(collection.wbos))
if (wbo.payload)];
wbos = collection.payloads();
_("WBOs: " + JSON.stringify(wbos));
let bookmarks = [wbo for each (wbo in wbos) if (wbo.type == "bookmark")];
@ -407,7 +404,7 @@ add_test(function test_bookmark_guidMap_fail() {
let itemGUID = store.GUIDForId(itemID);
let itemPayload = store.createRecord(itemGUID).cleartext;
let encPayload = encryptPayload(itemPayload);
collection.wbos[itemGUID] = new ServerWBO(itemGUID, encPayload);
collection.insert(itemGUID, encPayload);
engine.lastSync = 1; // So we don't back up.

Просмотреть файл

@ -113,14 +113,15 @@ add_test(function test_annotation_uploaded() {
try {
engine.sync();
let wbos = [id for ([id, wbo] in Iterator(collection.wbos))
if (["menu", "toolbar", "mobile"].indexOf(id) == -1)];
let wbos = collection.keys(function (id) {
return ["menu", "toolbar", "mobile"].indexOf(id) == -1;
});
do_check_eq(wbos.length, 1);
_("Verify that the server WBO has the annotation.");
let serverGUID = wbos[0];
do_check_eq(serverGUID, guid);
let serverWBO = collection.wbos[serverGUID];
let serverWBO = collection.wbo(serverGUID);
do_check_true(!!serverWBO);
let body = JSON.parse(JSON.parse(serverWBO.payload).ciphertext);
do_check_eq(body.queryId, "MostVisited");

Просмотреть файл

@ -93,7 +93,7 @@ add_test(function test_bad_hmac() {
_("Now try the scenario where our keys are wrong *and* there's a bad record.");
// Clean up and start fresh.
clientsColl.wbos = {};
clientsColl._wbos = {};
Service.lastHMACEvent = 0;
Clients.localID = Utils.makeGUID();
Clients.resetClient();
@ -164,7 +164,7 @@ add_test(function test_sync() {
{engines: {clients: {version: Clients.version,
syncID: Clients.syncID}}});
let coll = new ServerCollection();
let clientwbo = coll.wbos[Clients.localID] = new ServerWBO(Clients.localID);
let clientwbo = coll.insert(Clients.localID);
let server = httpd_setup({
"/1.1/foo/storage/meta/global": global.handler(),
"/1.1/foo/storage/clients": coll.handler()
@ -402,13 +402,13 @@ add_test(function test_command_sync() {
{engines: {clients: {version: Clients.version,
syncID: Clients.syncID}}});
let coll = new ServerCollection();
let clientwbo = coll.wbos[Clients.localID] = new ServerWBO(Clients.localID);
let clientwbo = coll.insert(Clients.localID);
let server = httpd_setup({
"/1.1/foo/storage/meta/global": global.handler(),
"/1.1/foo/storage/clients": coll.handler()
});
let remoteId = Utils.makeGUID();
let remotewbo = coll.wbos[remoteId] = new ServerWBO(remoteId);
let remotewbo = coll.insert(remoteId);
server.registerPathHandler(
"/1.1/foo/storage/clients/" + Clients.localID, clientwbo.handler());
server.registerPathHandler(

Просмотреть файл

@ -141,7 +141,7 @@ add_test(function test_locally_changed_keys() {
IV: w.IV,
hmac: w.hmac});
wbo.modified = modified;
history.wbos[id] = wbo;
history.insertWBO(wbo);
server.registerPathHandler(
"/1.1/johndoe/storage/history/record-no--" + i,
upd("history", wbo.handler()));
@ -201,7 +201,7 @@ add_test(function test_locally_changed_keys() {
IV: w.IV,
hmac: w.hmac});
wbo.modified = modified;
history.wbos[id] = wbo;
history.insertWBO(wbo);
server.registerPathHandler(
"/1.1/johndoe/storage/history/record-no--" + i,
upd("history", wbo.handler()));

Просмотреть файл

@ -18,7 +18,7 @@ add_test(function test_processIncoming_abort() {
let collection = new ServerCollection();
let id = Utils.makeGUID();
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler()

Просмотреть файл

@ -43,7 +43,7 @@ add_test(function test_processIncoming_mobile_history_batched() {
let wbo = new ServerWBO(id, payload);
wbo.modified = modified;
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
let server = sync_httpd_setup({

Просмотреть файл

@ -188,8 +188,8 @@ add_test(function hmac_error_during_node_reassignment() {
_("== Invoking first sync.");
Service.sync();
_("We should not simultaneously have data but no keys on the server.");
let hasData = rotaryColl.wbos["flying"] ||
rotaryColl.wbos["scotsman"];
let hasData = rotaryColl.wbo("flying") ||
rotaryColl.wbo("scotsman");
let hasKeys = keysWBO.modified;
_("We correctly handle 401s by aborting the sync and starting again.");
@ -204,8 +204,8 @@ add_test(function hmac_error_during_node_reassignment() {
_("---------------------------");
onSyncFinished = function() {
_("== Second (automatic) sync done.");
hasData = rotaryColl.wbos["flying"] ||
rotaryColl.wbos["scotsman"];
hasData = rotaryColl.wbo("flying") ||
rotaryColl.wbo("scotsman");
hasKeys = keysWBO.modified;
do_check_true(!hasData == !hasKeys);

Просмотреть файл

@ -45,12 +45,12 @@ add_test(function test_syncStartup_emptyOrOutdatedGlobalsResetsSync() {
// Some server side data that's going to be wiped
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.wbos.scotsman = new ServerWBO(
'scotsman', encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.insert('flying',
encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.insert('scotsman',
encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler()
@ -64,8 +64,8 @@ add_test(function test_syncStartup_emptyOrOutdatedGlobalsResetsSync() {
do_check_eq(engine._tracker.changedIDs["rekolok"], undefined);
let metaGlobal = Records.get(engine.metaURL);
do_check_eq(metaGlobal.payload.engines, undefined);
do_check_true(!!collection.wbos.flying.payload);
do_check_true(!!collection.wbos.scotsman.payload);
do_check_true(!!collection.payload("flying"));
do_check_true(!!collection.payload("scotsman"));
engine.lastSync = Date.now() / 1000;
engine.lastSyncLocal = Date.now();
@ -81,8 +81,8 @@ add_test(function test_syncStartup_emptyOrOutdatedGlobalsResetsSync() {
// Sync was reset and server data was wiped
do_check_eq(engine.lastSync, 0);
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_eq(collection.wbos.scotsman.payload, undefined);
do_check_eq(collection.payload("flying"), undefined);
do_check_eq(collection.payload("scotsman"), undefined);
} finally {
cleanAndGo(server);
@ -192,22 +192,22 @@ add_test(function test_processIncoming_createFromServer() {
// Some server records that will be downloaded
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.wbos.scotsman = new ServerWBO(
'scotsman', encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.insert('flying',
encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.insert('scotsman',
encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
// Two pathological cases involving relative URIs gone wrong.
collection.wbos['../pathological'] = new ServerWBO(
'../pathological', encryptPayload({id: '../pathological',
denomination: "Pathological Case"}));
let pathologicalPayload = encryptPayload({id: '../pathological',
denomination: "Pathological Case"});
collection.insert('../pathological', pathologicalPayload);
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler(),
"/1.1/foo/storage/rotary/flying": collection.wbos.flying.handler(),
"/1.1/foo/storage/rotary/scotsman": collection.wbos.scotsman.handler()
"/1.1/foo/storage/rotary/flying": collection.wbo("flying").handler(),
"/1.1/foo/storage/rotary/scotsman": collection.wbo("scotsman").handler()
});
let engine = makeRotaryEngine();
@ -252,48 +252,48 @@ add_test(function test_processIncoming_reconcile() {
// This server record is newer than the corresponding client one,
// so it'll update its data.
collection.wbos.newrecord = new ServerWBO(
'newrecord', encryptPayload({id: 'newrecord',
denomination: "New stuff..."}));
collection.insert('newrecord',
encryptPayload({id: 'newrecord',
denomination: "New stuff..."}));
// This server record is newer than the corresponding client one,
// so it'll update its data.
collection.wbos.newerserver = new ServerWBO(
'newerserver', encryptPayload({id: 'newerserver',
denomination: "New data!"}));
collection.insert('newerserver',
encryptPayload({id: 'newerserver',
denomination: "New data!"}));
// This server record is 2 mins older than the client counterpart
// but identical to it, so we're expecting the client record's
// changedID to be reset.
collection.wbos.olderidentical = new ServerWBO(
'olderidentical', encryptPayload({id: 'olderidentical',
denomination: "Older but identical"}));
collection.wbos.olderidentical.modified -= 120;
collection.insert('olderidentical',
encryptPayload({id: 'olderidentical',
denomination: "Older but identical"}));
collection._wbos.olderidentical.modified -= 120;
// This item simply has different data than the corresponding client
// record (which is unmodified), so it will update the client as well
collection.wbos.updateclient = new ServerWBO(
'updateclient', encryptPayload({id: 'updateclient',
denomination: "Get this!"}));
collection.insert('updateclient',
encryptPayload({id: 'updateclient',
denomination: "Get this!"}));
// This is a dupe of 'original' but with a longer GUID, so we're
// expecting it to be marked for deletion from the server
collection.wbos.duplication = new ServerWBO(
'duplication', encryptPayload({id: 'duplication',
denomination: "Original Entry"}));
collection.insert('duplication',
encryptPayload({id: 'duplication',
denomination: "Original Entry"}));
// This is a dupe of 'long_original' but with a shorter GUID, so we're
// expecting it to replace 'long_original'.
collection.wbos.dupe = new ServerWBO(
'dupe', encryptPayload({id: 'dupe',
denomination: "Long Original Entry"}));
collection.insert('dupe',
encryptPayload({id: 'dupe',
denomination: "Long Original Entry"}));
// This record is marked as deleted, so we're expecting the client
// record to be removed.
collection.wbos.nukeme = new ServerWBO(
'nukeme', encryptPayload({id: 'nukeme',
denomination: "Nuke me!",
deleted: true}));
collection.insert('nukeme',
encryptPayload({id: 'nukeme',
denomination: "Nuke me!",
deleted: true}));
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler()
@ -380,12 +380,12 @@ add_test(function test_processIncoming_mobile_batchSize() {
// Let's create some 234 server side records. They're all at least
// 10 minutes old.
for (var i = 0; i < 234; i++) {
for (let i = 0; i < 234; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + i});
let wbo = new ServerWBO(id, payload);
wbo.modified = Date.now()/1000 - 60*(i+10);
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
let server = sync_httpd_setup({
@ -456,7 +456,7 @@ add_test(function test_processIncoming_store_toFetch() {
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
let wbo = new ServerWBO(id, payload);
wbo.modified = Date.now()/1000 + 60 * (i - MOBILE_BATCH_SIZE * 3);
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
let engine = makeRotaryEngine();
@ -490,7 +490,7 @@ add_test(function test_processIncoming_store_toFetch() {
// The third batch is stuck in toFetch. lastSync has been moved forward to
// the last successful item's timestamp.
do_check_eq(engine.toFetch.length, MOBILE_BATCH_SIZE);
do_check_eq(engine.lastSync, collection.wbos["record-no-99"].modified);
do_check_eq(engine.lastSync, collection.wbo("record-no-99").modified);
} finally {
cleanAndGo(server);
@ -508,26 +508,26 @@ add_test(function test_processIncoming_resume_toFetch() {
// Server records that will be downloaded
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.wbos.scotsman = new ServerWBO(
'scotsman', encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.wbos.rekolok = new ServerWBO(
'rekolok', encryptPayload({id: 'rekolok',
denomination: "Rekonstruktionslokomotive"}));
for (var i = 0; i < 3; i++) {
collection.insert('flying',
encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.insert('scotsman',
encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.insert('rekolok',
encryptPayload({id: 'rekolok',
denomination: "Rekonstruktionslokomotive"}));
for (let i = 0; i < 3; i++) {
let id = 'failed' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + i});
let wbo = new ServerWBO(id, payload);
wbo.modified = LASTSYNC - 10;
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
collection.wbos.flying.modified = collection.wbos.scotsman.modified
= LASTSYNC - 10;
collection.wbos.rekolok.modified = LASTSYNC + 10;
collection.wbo("flying").modified =
collection.wbo("scotsman").modified = LASTSYNC - 10;
collection._wbos.rekolok.modified = LASTSYNC + 10;
// Time travel 10 seconds into the future but still download the above WBOs.
let engine = makeRotaryEngine();
@ -589,7 +589,7 @@ add_test(function test_processIncoming_applyIncomingBatchSize_smaller() {
for (let i = 0; i < APPLY_BATCH_SIZE - 1; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -644,7 +644,7 @@ add_test(function test_processIncoming_applyIncomingBatchSize_multiple() {
for (let i = 0; i < APPLY_BATCH_SIZE * 3; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -695,7 +695,7 @@ add_test(function test_processIncoming_notify_count() {
for (var i = 0; i < NUMBER_OF_RECORDS; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -782,7 +782,7 @@ add_test(function test_processIncoming_previousFailed() {
for (var i = 0; i < NUMBER_OF_RECORDS; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + i});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -857,7 +857,7 @@ add_test(function test_processIncoming_failed_records() {
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
let wbo = new ServerWBO(id, payload);
wbo.modified = Date.now()/1000 + 60 * (i - MOBILE_BATCH_SIZE * 3);
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
// Engine that batches but likes to throw on a couple of records,
@ -986,16 +986,16 @@ add_test(function test_processIncoming_decrypt_failed() {
// Some good and some bogus records. One doesn't contain valid JSON,
// the other will throw during decrypt.
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
collection._wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.wbos.nojson = new ServerWBO("nojson", "This is invalid JSON");
collection.wbos.nojson2 = new ServerWBO("nojson2", "This is invalid JSON");
collection.wbos.scotsman = new ServerWBO(
collection._wbos.nojson = new ServerWBO("nojson", "This is invalid JSON");
collection._wbos.nojson2 = new ServerWBO("nojson2", "This is invalid JSON");
collection._wbos.scotsman = new ServerWBO(
'scotsman', encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.wbos.nodecrypt = new ServerWBO("nodecrypt", "Decrypt this!");
collection.wbos.nodecrypt2 = new ServerWBO("nodecrypt2", "Decrypt this!");
collection._wbos.nodecrypt = new ServerWBO("nodecrypt", "Decrypt this!");
collection._wbos.nodecrypt2 = new ServerWBO("nodecrypt2", "Decrypt this!");
// Patch the fake crypto service to throw on the record above.
Svc.Crypto._decrypt = Svc.Crypto.decrypt;
@ -1033,7 +1033,7 @@ add_test(function test_processIncoming_decrypt_failed() {
observerData = data;
});
engine.lastSync = collection.wbos.nojson.modified - 1;
engine.lastSync = collection.wbo("nojson").modified - 1;
engine.sync();
do_check_eq(engine.previousFailed.length, 4);
@ -1060,13 +1060,13 @@ add_test(function test_uploadOutgoing_toEmptyServer() {
Svc.Prefs.set("clusterURL", "http://localhost:8080/");
Svc.Prefs.set("username", "foo");
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO('flying');
collection.wbos.scotsman = new ServerWBO('scotsman');
collection._wbos.flying = new ServerWBO('flying');
collection._wbos.scotsman = new ServerWBO('scotsman');
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler(),
"/1.1/foo/storage/rotary/flying": collection.wbos.flying.handler(),
"/1.1/foo/storage/rotary/scotsman": collection.wbos.scotsman.handler()
"/1.1/foo/storage/rotary/flying": collection.wbo("flying").handler(),
"/1.1/foo/storage/rotary/scotsman": collection.wbo("scotsman").handler()
});
generateNewKeys();
@ -1085,8 +1085,8 @@ add_test(function test_uploadOutgoing_toEmptyServer() {
// Confirm initial environment
do_check_eq(engine.lastSyncLocal, 0);
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_eq(collection.wbos.scotsman.payload, undefined);
do_check_eq(collection.payload("flying"), undefined);
do_check_eq(collection.payload("scotsman"), undefined);
engine._syncStartup();
engine._uploadOutgoing();
@ -1096,14 +1096,14 @@ add_test(function test_uploadOutgoing_toEmptyServer() {
// Ensure the marked record ('scotsman') has been uploaded and is
// no longer marked.
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_true(!!collection.wbos.scotsman.payload);
do_check_eq(JSON.parse(collection.wbos.scotsman.data.ciphertext).id,
'scotsman');
do_check_eq(engine._tracker.changedIDs['scotsman'], undefined);
do_check_eq(collection.payload("flying"), undefined);
do_check_true(!!collection.payload("scotsman"));
do_check_eq(JSON.parse(collection.wbo("scotsman").data.ciphertext).id,
"scotsman");
do_check_eq(engine._tracker.changedIDs["scotsman"], undefined);
// The 'flying' record wasn't marked so it wasn't uploaded
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_eq(collection.payload("flying"), undefined);
} finally {
cleanAndGo(server);
@ -1120,7 +1120,7 @@ add_test(function test_uploadOutgoing_failed() {
let collection = new ServerCollection();
// We only define the "flying" WBO on the server, not the "scotsman"
// and "peppercorn" ones.
collection.wbos.flying = new ServerWBO('flying');
collection._wbos.flying = new ServerWBO('flying');
let server = sync_httpd_setup({
"/1.1/foo/storage/rotary": collection.handler()
@ -1147,7 +1147,7 @@ add_test(function test_uploadOutgoing_failed() {
// Confirm initial environment
do_check_eq(engine.lastSyncLocal, 0);
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_eq(collection.payload("flying"), undefined);
do_check_eq(engine._tracker.changedIDs['flying'], FLYING_CHANGED);
do_check_eq(engine._tracker.changedIDs['scotsman'], SCOTSMAN_CHANGED);
do_check_eq(engine._tracker.changedIDs['peppercorn'], PEPPERCORN_CHANGED);
@ -1159,7 +1159,7 @@ add_test(function test_uploadOutgoing_failed() {
do_check_true(engine.lastSyncLocal > 0);
// Ensure the 'flying' record has been uploaded and is no longer marked.
do_check_true(!!collection.wbos.flying.payload);
do_check_true(!!collection.payload("flying"));
do_check_eq(engine._tracker.changedIDs['flying'], undefined);
// The 'scotsman' and 'peppercorn' records couldn't be uploaded so
@ -1196,7 +1196,7 @@ add_test(function test_uploadOutgoing_MAX_UPLOAD_RECORDS() {
let id = 'record-no-' + i;
engine._store.items[id] = "Record No. " + i;
engine._tracker.addChangedID(id, 0);
collection.wbos[id] = new ServerWBO(id);
collection.insert(id);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -1209,18 +1209,18 @@ add_test(function test_uploadOutgoing_MAX_UPLOAD_RECORDS() {
try {
// Confirm initial environment
// Confirm initial environment.
do_check_eq(noOfUploads, 0);
engine._syncStartup();
engine._uploadOutgoing();
// Ensure all records have been uploaded
// Ensure all records have been uploaded.
for (i = 0; i < 234; i++) {
do_check_true(!!collection.wbos['record-no-'+i].payload);
do_check_true(!!collection.payload('record-no-' + i));
}
// Ensure that the uploads were performed in batches of MAX_UPLOAD_RECORDS
// Ensure that the uploads were performed in batches of MAX_UPLOAD_RECORDS.
do_check_eq(noOfUploads, Math.ceil(234/MAX_UPLOAD_RECORDS));
} finally {
@ -1251,13 +1251,13 @@ add_test(function test_syncFinish_deleteByIds() {
Svc.Prefs.set("clusterURL", "http://localhost:8080/");
Svc.Prefs.set("username", "foo");
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
collection._wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
collection.wbos.scotsman = new ServerWBO(
collection._wbos.scotsman = new ServerWBO(
'scotsman', encryptPayload({id: 'scotsman',
denomination: "Flying Scotsman"}));
collection.wbos.rekolok = new ServerWBO(
collection._wbos.rekolok = new ServerWBO(
'rekolok', encryptPayload({id: 'rekolok',
denomination: "Rekonstruktionslokomotive"}));
@ -1272,9 +1272,9 @@ add_test(function test_syncFinish_deleteByIds() {
// The 'flying' and 'rekolok' records were deleted while the
// 'scotsman' one wasn't.
do_check_eq(collection.wbos.flying.payload, undefined);
do_check_true(!!collection.wbos.scotsman.payload);
do_check_eq(collection.wbos.rekolok.payload, undefined);
do_check_eq(collection.payload("flying"), undefined);
do_check_true(!!collection.payload("scotsman"));
do_check_eq(collection.payload("rekolok"), undefined);
// The deletion todo list has been reset.
do_check_eq(engine._delete.ids, undefined);
@ -1309,7 +1309,7 @@ add_test(function test_syncFinish_deleteLotsInBatches() {
let payload = encryptPayload({id: id, denomination: "Record No. " + i});
let wbo = new ServerWBO(id, payload);
wbo.modified = now / 1000 - 60 * (i + 110);
collection.wbos[id] = wbo;
collection.insertWBO(wbo);
}
let server = httpd_setup({
@ -1338,9 +1338,9 @@ add_test(function test_syncFinish_deleteLotsInBatches() {
for (i = 0; i < 234; i++) {
let id = 'record-no-' + i;
if (i <= 90 || i >= 100) {
do_check_eq(collection.wbos[id].payload, undefined);
do_check_eq(collection.payload(id), undefined);
} else {
do_check_true(!!collection.wbos[id].payload);
do_check_true(!!collection.payload(id));
}
}
@ -1390,8 +1390,9 @@ add_test(function test_sync_partialUpload() {
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.wbos[id] = new ServerWBO(id);
if ((i != 23) && (i != 42)) {
collection.insert(id);
}
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));
@ -1439,7 +1440,7 @@ add_test(function test_canDecrypt_noCryptoKeys() {
CollectionKeys.clear();
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
collection._wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
@ -1467,7 +1468,7 @@ add_test(function test_canDecrypt_true() {
generateNewKeys();
let collection = new ServerCollection();
collection.wbos.flying = new ServerWBO(
collection._wbos.flying = new ServerWBO(
'flying', encryptPayload({id: 'flying',
denomination: "LNER Class A3 4472"}));
@ -1500,7 +1501,7 @@ add_test(function test_syncapplied_observer() {
for (var i = 0; i < NUMBER_OF_RECORDS; i++) {
let id = 'record-no-' + i;
let payload = encryptPayload({id: id, denomination: "Record No. " + id});
collection.wbos[id] = new ServerWBO(id, payload);
collection.insert(id, payload);
}
let meta_global = Records.set(engine.metaURL, new WBORecord(engine.metaURL));