зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1435588 - (part 3) Avoid applying the bookmarks buffer if we failed to store all records r=kitcambridge
MozReview-Commit-ID: GJ8OHBuh6m0 --HG-- extra : rebase_source : ea3fc302c64d4119d8e407411f9a3a1ba0b428cb
This commit is contained in:
Родитель
c82baa71a3
Коммит
28add38cd6
|
@ -723,15 +723,12 @@ BufferedBookmarksEngine.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
async _processIncoming(newitems) {
|
async _processIncoming(newitems) {
|
||||||
try {
|
await super._processIncoming(newitems);
|
||||||
await super._processIncoming(newitems);
|
let buf = await this._store.ensureOpenMirror();
|
||||||
} finally {
|
let recordsToUpload = await buf.apply({
|
||||||
let buf = await this._store.ensureOpenMirror();
|
remoteTimeSeconds: Resource.serverTime,
|
||||||
let recordsToUpload = await buf.apply({
|
});
|
||||||
remoteTimeSeconds: Resource.serverTime,
|
this._modified.replace(recordsToUpload);
|
||||||
});
|
|
||||||
this._modified.replace(recordsToUpload);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async _reconcile(item) {
|
async _reconcile(item) {
|
||||||
|
|
|
@ -220,12 +220,12 @@ add_bookmark_test(async function test_processIncoming_error_orderChildren(engine
|
||||||
// Verify that the bookmark order has been applied.
|
// Verify that the bookmark order has been applied.
|
||||||
folder1_record = await store.createRecord(folder1.guid);
|
folder1_record = await store.createRecord(folder1.guid);
|
||||||
let new_children = folder1_record.children;
|
let new_children = folder1_record.children;
|
||||||
Assert.deepEqual(new_children,
|
Assert.deepEqual(new_children.sort(),
|
||||||
[folder1_payload.children[0], folder1_payload.children[1]]);
|
[folder1_payload.children[0], folder1_payload.children[1]].sort());
|
||||||
|
|
||||||
let localChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
|
let localChildIds = await PlacesSyncUtils.bookmarks.fetchChildRecordIds(
|
||||||
folder1.guid);
|
folder1.guid);
|
||||||
Assert.deepEqual(localChildIds, [bmk2.guid, bmk1.guid]);
|
Assert.deepEqual(localChildIds.sort(), [bmk2.guid, bmk1.guid].sort());
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
await cleanup(engine, server);
|
await cleanup(engine, server);
|
||||||
|
@ -877,3 +877,97 @@ add_task(async function test_sync_imap_URLs() {
|
||||||
await cleanup(engine, server);
|
await cleanup(engine, server);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
add_task(async function test_resume_buffer() {
|
||||||
|
await Service.recordManager.clearCache();
|
||||||
|
let engine = new BufferedBookmarksEngine(Service);
|
||||||
|
await engine.initialize();
|
||||||
|
await engine._store.wipe();
|
||||||
|
await engine.resetClient();
|
||||||
|
|
||||||
|
let server = await serverForFoo(engine);
|
||||||
|
await SyncTestingInfrastructure(server);
|
||||||
|
|
||||||
|
let collection = server.user("foo").collection("bookmarks");
|
||||||
|
|
||||||
|
engine._tracker.start(); // We skip usual startup...
|
||||||
|
|
||||||
|
const batchChunkSize = 50;
|
||||||
|
|
||||||
|
engine._store._batchChunkSize = batchChunkSize;
|
||||||
|
try {
|
||||||
|
let children = [];
|
||||||
|
|
||||||
|
let timestamp = Math.floor(Date.now() / 1000);
|
||||||
|
// Add two chunks worth of records to the server
|
||||||
|
for (let i = 0; i < batchChunkSize * 2; ++i) {
|
||||||
|
let cleartext = {
|
||||||
|
id: Utils.makeGUID(),
|
||||||
|
type: "bookmark",
|
||||||
|
parentid: "toolbar",
|
||||||
|
title: `Bookmark ${i}`,
|
||||||
|
parentName: "Bookmarks Toolbar",
|
||||||
|
bmkUri: `https://example.com/${i}`,
|
||||||
|
};
|
||||||
|
let wbo = collection.insert(cleartext.id,
|
||||||
|
encryptPayload(cleartext),
|
||||||
|
timestamp + 10 * i);
|
||||||
|
// Something that is effectively random, but deterministic.
|
||||||
|
// (This is just to ensure we don't accidentally start using the
|
||||||
|
// sortindex again).
|
||||||
|
wbo.sortindex = 1000 + Math.round(Math.sin(i / 5) * 100);
|
||||||
|
children.push(cleartext.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the parent of those records, and ensure its timestamp is the most recent.
|
||||||
|
collection.insert("toolbar", encryptPayload({
|
||||||
|
id: "toolbar",
|
||||||
|
type: "folder",
|
||||||
|
parentid: "places",
|
||||||
|
title: "Bookmarks Toolbar",
|
||||||
|
children
|
||||||
|
}), timestamp + 10 * children.length);
|
||||||
|
|
||||||
|
// Replace applyIncomingBatch with a custom one that calls the original,
|
||||||
|
// but forces it to throw on the 2nd chunk.
|
||||||
|
let origApplyIncomingBatch = engine._store.applyIncomingBatch;
|
||||||
|
engine._store.applyIncomingBatch = function(records) {
|
||||||
|
if (records.length > batchChunkSize) {
|
||||||
|
// Hacky way to make reading from the batchChunkSize'th record throw.
|
||||||
|
delete records[batchChunkSize];
|
||||||
|
Object.defineProperty(records, batchChunkSize, {
|
||||||
|
get() { throw new Error("D:"); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return origApplyIncomingBatch.call(this, records);
|
||||||
|
};
|
||||||
|
|
||||||
|
let caughtError;
|
||||||
|
_("We expect this to fail");
|
||||||
|
try {
|
||||||
|
await sync_engine_and_validate_telem(engine, true);
|
||||||
|
} catch (e) {
|
||||||
|
caughtError = e;
|
||||||
|
}
|
||||||
|
Assert.ok(caughtError, "Expected engine.sync to throw");
|
||||||
|
Assert.equal(caughtError.message, "D:");
|
||||||
|
|
||||||
|
// The buffer subtracts one second from the actual timestamp.
|
||||||
|
let lastSync = await engine.getLastSync() + 1;
|
||||||
|
// We poisoned the batchChunkSize'th record, so the last successfully
|
||||||
|
// applied record will be batchChunkSize - 1.
|
||||||
|
let expectedLastSync = timestamp + 10 * (batchChunkSize - 1);
|
||||||
|
Assert.equal(expectedLastSync, lastSync);
|
||||||
|
|
||||||
|
engine._store.applyIncomingBatch = origApplyIncomingBatch;
|
||||||
|
|
||||||
|
await sync_engine_and_validate_telem(engine, false);
|
||||||
|
|
||||||
|
// Check that all the children made it onto the correct record.
|
||||||
|
let toolbarRecord = await engine._store.createRecord("toolbar");
|
||||||
|
Assert.deepEqual(toolbarRecord.children.sort(), children.sort());
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
await cleanup(engine, server);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
Загрузка…
Ссылка в новой задаче