summaryrefslogtreecommitdiffstats
path: root/services/sync/tests/unit/test_clients_engine.js
diff options
context:
space:
mode:
Diffstat (limited to 'services/sync/tests/unit/test_clients_engine.js')
-rw-r--r--services/sync/tests/unit/test_clients_engine.js1027
1 files changed, 99 insertions, 928 deletions
diff --git a/services/sync/tests/unit/test_clients_engine.js b/services/sync/tests/unit/test_clients_engine.js
index d2123f80a..919913f82 100644
--- a/services/sync/tests/unit/test_clients_engine.js
+++ b/services/sync/tests/unit/test_clients_engine.js
@@ -12,7 +12,7 @@ Cu.import("resource://testing-common/services/sync/utils.js");
const MORE_THAN_CLIENTS_TTL_REFRESH = 691200; // 8 days
const LESS_THAN_CLIENTS_TTL_REFRESH = 86400; // 1 day
-var engine = Service.clientsEngine;
+let engine = Service.clientsEngine;
/**
* Unpack the record with this ID, and verify that it has the same version that
@@ -31,10 +31,10 @@ function check_record_version(user, id) {
let cleartext = rec.decrypt(Service.collectionKeys.keyForCollection("clients"));
_("Payload is " + JSON.stringify(cleartext));
- equal(Services.appinfo.version, cleartext.version);
- equal(2, cleartext.protocols.length);
- equal("1.1", cleartext.protocols[0]);
- equal("1.5", cleartext.protocols[1]);
+ do_check_eq(Services.appinfo.version, cleartext.version);
+ do_check_eq(2, cleartext.protocols.length);
+ do_check_eq("1.1", cleartext.protocols[0]);
+ do_check_eq("1.5", cleartext.protocols[1]);
}
add_test(function test_bad_hmac() {
@@ -64,7 +64,7 @@ add_test(function test_bad_hmac() {
let coll = user.collection("clients");
// Treat a non-existent collection as empty.
- equal(expectedCount, coll ? coll.count() : 0, stack);
+ do_check_eq(expectedCount, coll ? coll.count() : 0, stack);
}
function check_client_deleted(id) {
@@ -77,7 +77,7 @@ add_test(function test_bad_hmac() {
generateNewKeys(Service.collectionKeys);
let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
serverKeys.encrypt(Service.identity.syncKeyBundle);
- ok(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
+ do_check_true(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
}
try {
@@ -89,11 +89,11 @@ add_test(function test_bad_hmac() {
generateNewKeys(Service.collectionKeys);
_("First sync, client record is uploaded");
- equal(engine.lastRecordUpload, 0);
+ do_check_eq(engine.lastRecordUpload, 0);
check_clients_count(0);
engine._sync();
check_clients_count(1);
- ok(engine.lastRecordUpload > 0);
+ do_check_true(engine.lastRecordUpload > 0);
// Our uploaded record has a version.
check_record_version(user, engine.localID);
@@ -109,7 +109,7 @@ add_test(function test_bad_hmac() {
generateNewKeys(Service.collectionKeys);
let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
serverKeys.encrypt(Service.identity.syncKeyBundle);
- ok(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
+ do_check_true(serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success);
_("Sync.");
engine._sync();
@@ -130,8 +130,8 @@ add_test(function test_bad_hmac() {
engine._sync();
_("Old record was not deleted, new one uploaded.");
- equal(deletedCollections.length, 0);
- equal(deletedItems.length, 0);
+ do_check_eq(deletedCollections.length, 0);
+ do_check_eq(deletedItems.length, 0);
check_clients_count(2);
_("Now try the scenario where our keys are wrong *and* there's a bad record.");
@@ -162,14 +162,14 @@ add_test(function test_bad_hmac() {
generateNewKeys(Service.collectionKeys);
let oldKey = Service.collectionKeys.keyForCollection();
- equal(deletedCollections.length, 0);
- equal(deletedItems.length, 0);
+ do_check_eq(deletedCollections.length, 0);
+ do_check_eq(deletedItems.length, 0);
engine._sync();
- equal(deletedItems.length, 1);
+ do_check_eq(deletedItems.length, 1);
check_client_deleted(oldLocalID);
check_clients_count(1);
let newKey = Service.collectionKeys.keyForCollection();
- ok(!oldKey.equals(newKey));
+ do_check_false(oldKey.equals(newKey));
} finally {
Svc.Prefs.resetBranch("");
@@ -181,91 +181,18 @@ add_test(function test_bad_hmac() {
add_test(function test_properties() {
_("Test lastRecordUpload property");
try {
- equal(Svc.Prefs.get("clients.lastRecordUpload"), undefined);
- equal(engine.lastRecordUpload, 0);
+ do_check_eq(Svc.Prefs.get("clients.lastRecordUpload"), undefined);
+ do_check_eq(engine.lastRecordUpload, 0);
let now = Date.now();
engine.lastRecordUpload = now / 1000;
- equal(engine.lastRecordUpload, Math.floor(now / 1000));
+ do_check_eq(engine.lastRecordUpload, Math.floor(now / 1000));
} finally {
Svc.Prefs.resetBranch("");
run_next_test();
}
});
-add_test(function test_full_sync() {
- _("Ensure that Clients engine fetches all records for each sync.");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let activeID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
- id: activeID,
- name: "Active client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- let deletedID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(deletedID, encryptPayload({
- id: deletedID,
- name: "Client to delete",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. 2 records downloaded; our record uploaded.");
- strictEqual(engine.lastRecordUpload, 0);
- engine._sync();
- ok(engine.lastRecordUpload > 0);
- deepEqual(user.collection("clients").keys().sort(),
- [activeID, deletedID, engine.localID].sort(),
- "Our record should be uploaded on first sync");
- deepEqual(Object.keys(store.getAllIDs()).sort(),
- [activeID, deletedID, engine.localID].sort(),
- "Other clients should be downloaded on first sync");
-
- _("Delete a record, then sync again");
- let collection = server.getCollection("foo", "clients");
- collection.remove(deletedID);
- // Simulate a timestamp update in info/collections.
- engine.lastModified = now;
- engine._sync();
-
- _("Record should be updated");
- deepEqual(Object.keys(store.getAllIDs()).sort(),
- [activeID, engine.localID].sort(),
- "Deleted client should be removed on next sync");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
add_test(function test_sync() {
_("Ensure that Clients engine uploads a new client record once a week.");
@@ -288,30 +215,30 @@ add_test(function test_sync() {
try {
_("First sync. Client record is uploaded.");
- equal(clientWBO(), undefined);
- equal(engine.lastRecordUpload, 0);
+ do_check_eq(clientWBO(), undefined);
+ do_check_eq(engine.lastRecordUpload, 0);
engine._sync();
- ok(!!clientWBO().payload);
- ok(engine.lastRecordUpload > 0);
+ do_check_true(!!clientWBO().payload);
+ do_check_true(engine.lastRecordUpload > 0);
_("Let's time travel more than a week back, new record should've been uploaded.");
engine.lastRecordUpload -= MORE_THAN_CLIENTS_TTL_REFRESH;
let lastweek = engine.lastRecordUpload;
clientWBO().payload = undefined;
engine._sync();
- ok(!!clientWBO().payload);
- ok(engine.lastRecordUpload > lastweek);
+ do_check_true(!!clientWBO().payload);
+ do_check_true(engine.lastRecordUpload > lastweek);
_("Remove client record.");
engine.removeClientData();
- equal(clientWBO().payload, undefined);
+ do_check_eq(clientWBO().payload, undefined);
_("Time travel one day back, no record uploaded.");
engine.lastRecordUpload -= LESS_THAN_CLIENTS_TTL_REFRESH;
let yesterday = engine.lastRecordUpload;
engine._sync();
- equal(clientWBO().payload, undefined);
- equal(engine.lastRecordUpload, yesterday);
+ do_check_eq(clientWBO().payload, undefined);
+ do_check_eq(engine.lastRecordUpload, yesterday);
} finally {
Svc.Prefs.resetBranch("");
@@ -336,16 +263,16 @@ add_test(function test_client_name_change() {
let initialScore = tracker.score;
- equal(Object.keys(tracker.changedIDs).length, 0);
+ do_check_eq(Object.keys(tracker.changedIDs).length, 0);
Svc.Prefs.set("client.name", "new name");
_("new name: " + engine.localName);
- notEqual(initialName, engine.localName);
- equal(Object.keys(tracker.changedIDs).length, 1);
- ok(engine.localID in tracker.changedIDs);
- ok(tracker.score > initialScore);
- ok(tracker.score >= SCORE_INCREMENT_XLARGE);
+ do_check_neq(initialName, engine.localName);
+ do_check_eq(Object.keys(tracker.changedIDs).length, 1);
+ do_check_true(engine.localID in tracker.changedIDs);
+ do_check_true(tracker.score > initialScore);
+ do_check_true(tracker.score >= SCORE_INCREMENT_XLARGE);
Svc.Obs.notify("weave:engine:stop-tracking");
@@ -369,16 +296,15 @@ add_test(function test_send_command() {
engine._sendCommandToClient(action, args, remoteId);
let newRecord = store._remoteClients[remoteId];
- let clientCommands = engine._readCommands()[remoteId];
- notEqual(newRecord, undefined);
- equal(clientCommands.length, 1);
+ do_check_neq(newRecord, undefined);
+ do_check_eq(newRecord.commands.length, 1);
- let command = clientCommands[0];
- equal(command.command, action);
- equal(command.args.length, 2);
- deepEqual(command.args, args);
+ let command = newRecord.commands[0];
+ do_check_eq(command.command, action);
+ do_check_eq(command.args.length, 2);
+ do_check_eq(command.args, args);
- notEqual(tracker.changedIDs[remoteId], undefined);
+ do_check_neq(tracker.changedIDs[remoteId], undefined);
run_next_test();
});
@@ -402,7 +328,7 @@ add_test(function test_command_validation() {
["__UNKNOWN__", [], false]
];
- for (let [action, args, expectedResult] of testCommands) {
+ for each (let [action, args, expectedResult] in testCommands) {
let remoteId = Utils.makeGUID();
let rec = new ClientsRec("clients", remoteId);
@@ -412,26 +338,24 @@ add_test(function test_command_validation() {
engine.sendCommand(action, args, remoteId);
let newRecord = store._remoteClients[remoteId];
- notEqual(newRecord, undefined);
-
- let clientCommands = engine._readCommands()[remoteId];
+ do_check_neq(newRecord, undefined);
if (expectedResult) {
_("Ensuring command is sent: " + action);
- equal(clientCommands.length, 1);
+ do_check_eq(newRecord.commands.length, 1);
- let command = clientCommands[0];
- equal(command.command, action);
- deepEqual(command.args, args);
+ let command = newRecord.commands[0];
+ do_check_eq(command.command, action);
+ do_check_eq(command.args, args);
- notEqual(engine._tracker, undefined);
- notEqual(engine._tracker.changedIDs[remoteId], undefined);
+ do_check_neq(engine._tracker, undefined);
+ do_check_neq(engine._tracker.changedIDs[remoteId], undefined);
} else {
_("Ensuring command is scrubbed: " + action);
- equal(clientCommands, undefined);
+ do_check_eq(newRecord.commands, undefined);
if (store._tracker) {
- equal(engine._tracker[remoteId], undefined);
+ do_check_eq(engine._tracker[remoteId], undefined);
}
}
@@ -455,11 +379,10 @@ add_test(function test_command_duplication() {
engine.sendCommand(action, args, remoteId);
let newRecord = store._remoteClients[remoteId];
- let clientCommands = engine._readCommands()[remoteId];
- equal(clientCommands.length, 1);
+ do_check_eq(newRecord.commands.length, 1);
_("Check variant args length");
- engine._saveCommands({});
+ newRecord.commands = [];
action = "resetEngine";
engine.sendCommand(action, [{ x: "foo" }], remoteId);
@@ -468,8 +391,7 @@ add_test(function test_command_duplication() {
_("Make sure we spot a real dupe argument.");
engine.sendCommand(action, [{ x: "bar" }], remoteId);
- clientCommands = engine._readCommands()[remoteId];
- equal(clientCommands.length, 2);
+ do_check_eq(newRecord.commands.length, 2);
run_next_test();
});
@@ -486,7 +408,7 @@ add_test(function test_command_invalid_client() {
error = ex;
}
- equal(error.message.indexOf("Unknown remote client ID: "), 0);
+ do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
run_next_test();
});
@@ -500,174 +422,13 @@ add_test(function test_process_incoming_commands() {
var handler = function() {
Svc.Obs.remove(ev, handler);
-
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
run_next_test();
};
Svc.Obs.add(ev, handler);
// logout command causes processIncomingCommands to return explicit false.
- ok(!engine.processIncomingCommands());
-});
-
-add_test(function test_filter_duplicate_names() {
- _("Ensure that we exclude clients with identical names that haven't synced in a week.");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- // Synced recently.
- let recentID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(recentID, encryptPayload({
- id: recentID,
- name: "My Phone",
- type: "mobile",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- // Dupe of our client, synced more than 1 week ago.
- let dupeID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(dupeID, encryptPayload({
- id: dupeID,
- name: engine.localName,
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 604810));
-
- // Synced more than 1 week ago, but not a dupe.
- let oldID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(oldID, encryptPayload({
- id: oldID,
- name: "My old desktop",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 604820));
-
- try {
- let store = engine._store;
-
- _("First sync");
- strictEqual(engine.lastRecordUpload, 0);
- engine._sync();
- ok(engine.lastRecordUpload > 0);
- deepEqual(user.collection("clients").keys().sort(),
- [recentID, dupeID, oldID, engine.localID].sort(),
- "Our record should be uploaded on first sync");
-
- deepEqual(Object.keys(store.getAllIDs()).sort(),
- [recentID, dupeID, oldID, engine.localID].sort(),
- "Duplicate ID should remain in getAllIDs");
- ok(engine._store.itemExists(dupeID), "Dupe ID should be considered as existing for Sync methods.");
- ok(!engine.remoteClientExists(dupeID), "Dupe ID should not be considered as existing for external methods.");
-
- // dupe desktop should not appear in .deviceTypes.
- equal(engine.deviceTypes.get("desktop"), 2);
- equal(engine.deviceTypes.get("mobile"), 1);
-
- // dupe desktop should not appear in stats
- deepEqual(engine.stats, {
- hasMobile: 1,
- names: [engine.localName, "My Phone", "My old desktop"],
- numClients: 3,
- });
-
- ok(engine.remoteClientExists(oldID), "non-dupe ID should exist.");
- ok(!engine.remoteClientExists(dupeID), "dupe ID should not exist");
- equal(engine.remoteClients.length, 2, "dupe should not be in remoteClients");
-
- // Check that a subsequent Sync doesn't report anything as being processed.
- let counts;
- Svc.Obs.add("weave:engine:sync:applied", function observe(subject, data) {
- Svc.Obs.remove("weave:engine:sync:applied", observe);
- counts = subject;
- });
-
- engine._sync();
- equal(counts.applied, 0); // We didn't report applying any records.
- equal(counts.reconciled, 4); // We reported reconcilliation for all records
- equal(counts.succeeded, 0);
- equal(counts.failed, 0);
- equal(counts.newFailed, 0);
-
- _("Broadcast logout to all clients");
- engine.sendCommand("logout", []);
- engine._sync();
-
- let collection = server.getCollection("foo", "clients");
- let recentPayload = JSON.parse(JSON.parse(collection.payload(recentID)).ciphertext);
- deepEqual(recentPayload.commands, [{ command: "logout", args: [] }],
- "Should send commands to the recent client");
-
- let oldPayload = JSON.parse(JSON.parse(collection.payload(oldID)).ciphertext);
- deepEqual(oldPayload.commands, [{ command: "logout", args: [] }],
- "Should send commands to the week-old client");
-
- let dupePayload = JSON.parse(JSON.parse(collection.payload(dupeID)).ciphertext);
- deepEqual(dupePayload.commands, [],
- "Should not send commands to the dupe client");
-
- _("Update the dupe client's modified time");
- server.insertWBO("foo", "clients", new ServerWBO(dupeID, encryptPayload({
- id: dupeID,
- name: engine.localName,
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- _("Second sync.");
- engine._sync();
-
- deepEqual(Object.keys(store.getAllIDs()).sort(),
- [recentID, oldID, dupeID, engine.localID].sort(),
- "Stale client synced, so it should no longer be marked as a dupe");
-
- ok(engine.remoteClientExists(dupeID), "Dupe ID should appear as it synced.");
-
- // Recently synced dupe desktop should appear in .deviceTypes.
- equal(engine.deviceTypes.get("desktop"), 3);
-
- // Recently synced dupe desktop should now appear in stats
- deepEqual(engine.stats, {
- hasMobile: 1,
- names: [engine.localName, "My Phone", engine.localName, "My old desktop"],
- numClients: 4,
- });
-
- ok(engine.remoteClientExists(dupeID), "recently synced dupe ID should now exist");
- equal(engine.remoteClients.length, 3, "recently synced dupe should now be in remoteClients");
-
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
+ do_check_false(engine.processIncomingCommands());
});
add_test(function test_command_sync() {
@@ -693,58 +454,40 @@ add_test(function test_command_sync() {
}
_("Create remote client record");
- server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
- id: remoteId,
- name: "Remote client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), Date.now() / 1000));
+ let rec = new ClientsRec("clients", remoteId);
+ engine._store.create(rec);
+ let remoteRecord = engine._store.createRecord(remoteId, "clients");
+ engine.sendCommand("wipeAll", []);
+
+ let clientRecord = engine._store._remoteClients[remoteId];
+ do_check_neq(clientRecord, undefined);
+ do_check_eq(clientRecord.commands.length, 1);
try {
_("Syncing.");
engine._sync();
-
- _("Checking remote record was downloaded.");
- let clientRecord = engine._store._remoteClients[remoteId];
- notEqual(clientRecord, undefined);
- equal(clientRecord.commands.length, 0);
-
- _("Send a command to the remote client.");
- engine.sendCommand("wipeAll", []);
- let clientCommands = engine._readCommands()[remoteId];
- equal(clientCommands.length, 1);
- engine._sync();
-
_("Checking record was uploaded.");
- notEqual(clientWBO(engine.localID).payload, undefined);
- ok(engine.lastRecordUpload > 0);
+ do_check_neq(clientWBO(engine.localID).payload, undefined);
+ do_check_true(engine.lastRecordUpload > 0);
- notEqual(clientWBO(remoteId).payload, undefined);
+ do_check_neq(clientWBO(remoteId).payload, undefined);
Svc.Prefs.set("client.GUID", remoteId);
engine._resetClient();
- equal(engine.localID, remoteId);
+ do_check_eq(engine.localID, remoteId);
_("Performing sync on resetted client.");
engine._sync();
- notEqual(engine.localCommands, undefined);
- equal(engine.localCommands.length, 1);
+ do_check_neq(engine.localCommands, undefined);
+ do_check_eq(engine.localCommands.length, 1);
let command = engine.localCommands[0];
- equal(command.command, "wipeAll");
- equal(command.args.length, 0);
+ do_check_eq(command.command, "wipeAll");
+ do_check_eq(command.args.length, 0);
} finally {
Svc.Prefs.resetBranch("");
Service.recordManager.clearCache();
-
- try {
- let collection = server.getCollection("foo", "clients");
- collection.remove(remoteId);
- } finally {
- server.stop(run_next_test);
- }
+ server.stop(run_next_test);
}
});
@@ -769,19 +512,18 @@ add_test(function test_send_uri_to_client_for_display() {
let newRecord = store._remoteClients[remoteId];
- notEqual(newRecord, undefined);
- let clientCommands = engine._readCommands()[remoteId];
- equal(clientCommands.length, 1);
+ do_check_neq(newRecord, undefined);
+ do_check_eq(newRecord.commands.length, 1);
- let command = clientCommands[0];
- equal(command.command, "displayURI");
- equal(command.args.length, 3);
- equal(command.args[0], uri);
- equal(command.args[1], engine.localID);
- equal(command.args[2], title);
+ let command = newRecord.commands[0];
+ do_check_eq(command.command, "displayURI");
+ do_check_eq(command.args.length, 3);
+ do_check_eq(command.args[0], uri);
+ do_check_eq(command.args[1], engine.localID);
+ do_check_eq(command.args[2], title);
- ok(tracker.score > initialScore);
- ok(tracker.score - initialScore >= SCORE_INCREMENT_XLARGE);
+ do_check_true(tracker.score > initialScore);
+ do_check_true(tracker.score - initialScore >= SCORE_INCREMENT_XLARGE);
_("Ensure unknown client IDs result in exception.");
let unknownId = Utils.makeGUID();
@@ -793,11 +535,7 @@ add_test(function test_send_uri_to_client_for_display() {
error = ex;
}
- equal(error.message.indexOf("Unknown remote client ID: "), 0);
-
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
+ do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
run_next_test();
});
@@ -821,26 +559,22 @@ add_test(function test_receive_display_uri() {
// Received 'displayURI' command should result in the topic defined below
// being called.
- let ev = "weave:engine:clients:display-uris";
+ let ev = "weave:engine:clients:display-uri";
let handler = function(subject, data) {
Svc.Obs.remove(ev, handler);
- equal(subject[0].uri, uri);
- equal(subject[0].clientId, remoteId);
- equal(subject[0].title, title);
- equal(data, null);
+ do_check_eq(subject.uri, uri);
+ do_check_eq(subject.client, remoteId);
+ do_check_eq(subject.title, title);
+ do_check_eq(data, null);
run_next_test();
};
Svc.Obs.add(ev, handler);
- ok(engine.processIncomingCommands());
-
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
+ do_check_true(engine.processIncomingCommands());
});
add_test(function test_optional_client_fields() {
@@ -848,590 +582,27 @@ add_test(function test_optional_client_fields() {
const SUPPORTED_PROTOCOL_VERSIONS = ["1.1", "1.5"];
let local = engine._store.createRecord(engine.localID, "clients");
- equal(local.name, engine.localName);
- equal(local.type, engine.localType);
- equal(local.version, Services.appinfo.version);
- deepEqual(local.protocols, SUPPORTED_PROTOCOL_VERSIONS);
+ do_check_eq(local.name, engine.localName);
+ do_check_eq(local.type, engine.localType);
+ do_check_eq(local.version, Services.appinfo.version);
+ do_check_array_eq(local.protocols, SUPPORTED_PROTOCOL_VERSIONS);
// Optional fields.
// Make sure they're what they ought to be...
- equal(local.os, Services.appinfo.OS);
- equal(local.appPackage, Services.appinfo.ID);
+ do_check_eq(local.os, Services.appinfo.OS);
+ do_check_eq(local.appPackage, Services.appinfo.ID);
// ... and also that they're non-empty.
- ok(!!local.os);
- ok(!!local.appPackage);
- ok(!!local.application);
+ do_check_true(!!local.os);
+ do_check_true(!!local.appPackage);
+ do_check_true(!!local.application);
// We don't currently populate device or formfactor.
// See Bug 1100722, Bug 1100723.
- engine._resetClient();
run_next_test();
});
-add_test(function test_merge_commands() {
- _("Verifies local commands for remote clients are merged with the server's");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let desktopID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
- id: desktopID,
- name: "Desktop client",
- type: "desktop",
- commands: [{
- command: "displayURI",
- args: ["https://example.com", engine.localID, "Yak Herders Anonymous"],
- }],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- let mobileID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(mobileID, encryptPayload({
- id: mobileID,
- name: "Mobile client",
- type: "mobile",
- commands: [{
- command: "logout",
- args: [],
- }],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. 2 records downloaded.");
- strictEqual(engine.lastRecordUpload, 0);
- engine._sync();
-
- _("Broadcast logout to all clients");
- engine.sendCommand("logout", []);
- engine._sync();
-
- let collection = server.getCollection("foo", "clients");
- let desktopPayload = JSON.parse(JSON.parse(collection.payload(desktopID)).ciphertext);
- deepEqual(desktopPayload.commands, [{
- command: "displayURI",
- args: ["https://example.com", engine.localID, "Yak Herders Anonymous"],
- }, {
- command: "logout",
- args: [],
- }], "Should send the logout command to the desktop client");
-
- let mobilePayload = JSON.parse(JSON.parse(collection.payload(mobileID)).ciphertext);
- deepEqual(mobilePayload.commands, [{ command: "logout", args: [] }],
- "Should not send a duplicate logout to the mobile client");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_duplicate_remote_commands() {
- _("Verifies local commands for remote clients are sent only once (bug 1289287)");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let desktopID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
- id: desktopID,
- name: "Desktop client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. 1 record downloaded.");
- strictEqual(engine.lastRecordUpload, 0);
- engine._sync();
-
- _("Send tab to client");
- engine.sendCommand("displayURI", ["https://example.com", engine.localID, "Yak Herders Anonymous"]);
- engine._sync();
-
- _("Simulate the desktop client consuming the command and syncing to the server");
- server.insertWBO("foo", "clients", new ServerWBO(desktopID, encryptPayload({
- id: desktopID,
- name: "Desktop client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- _("Send another tab to the desktop client");
- engine.sendCommand("displayURI", ["https://foobar.com", engine.localID, "Foo bar!"], desktopID);
- engine._sync();
-
- let collection = server.getCollection("foo", "clients");
- let desktopPayload = JSON.parse(JSON.parse(collection.payload(desktopID)).ciphertext);
- deepEqual(desktopPayload.commands, [{
- command: "displayURI",
- args: ["https://foobar.com", engine.localID, "Foo bar!"],
- }], "Should only send the second command to the desktop client");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_upload_after_reboot() {
- _("Multiple downloads, reboot, then upload (bug 1289287)");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let deviceBID = Utils.makeGUID();
- let deviceCID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
- id: deviceBID,
- name: "Device B",
- type: "desktop",
- commands: [{
- command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
- }],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
- server.insertWBO("foo", "clients", new ServerWBO(deviceCID, encryptPayload({
- id: deviceCID,
- name: "Device C",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. 2 records downloaded.");
- strictEqual(engine.lastRecordUpload, 0);
- engine._sync();
-
- _("Send tab to client");
- engine.sendCommand("displayURI", ["https://example.com", engine.localID, "Yak Herders Anonymous"], deviceBID);
-
- const oldUploadOutgoing = SyncEngine.prototype._uploadOutgoing;
- SyncEngine.prototype._uploadOutgoing = () => engine._onRecordsWritten.call(engine, [], [deviceBID]);
- engine._sync();
-
- let collection = server.getCollection("foo", "clients");
- let deviceBPayload = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
- deepEqual(deviceBPayload.commands, [{
- command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
- }], "Should be the same because the upload failed");
-
- _("Simulate the client B consuming the command and syncing to the server");
- server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
- id: deviceBID,
- name: "Device B",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- // Simulate reboot
- SyncEngine.prototype._uploadOutgoing = oldUploadOutgoing;
- engine = Service.clientsEngine = new ClientEngine(Service);
-
- engine._sync();
-
- deviceBPayload = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
- deepEqual(deviceBPayload.commands, [{
- command: "displayURI",
- args: ["https://example.com", engine.localID, "Yak Herders Anonymous"],
- }], "Should only had written our outgoing command");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_keep_cleared_commands_after_reboot() {
- _("Download commands, fail upload, reboot, then apply new commands (bug 1289287)");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let deviceBID = Utils.makeGUID();
- let deviceCID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload({
- id: engine.localID,
- name: "Device A",
- type: "desktop",
- commands: [{
- command: "displayURI", args: ["https://deviceblink.com", deviceBID, "Device B link"]
- },
- {
- command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
- }],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
- server.insertWBO("foo", "clients", new ServerWBO(deviceBID, encryptPayload({
- id: deviceBID,
- name: "Device B",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
- server.insertWBO("foo", "clients", new ServerWBO(deviceCID, encryptPayload({
- id: deviceCID,
- name: "Device C",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. Download remote and our record.");
- strictEqual(engine.lastRecordUpload, 0);
-
- let collection = server.getCollection("foo", "clients");
- const oldUploadOutgoing = SyncEngine.prototype._uploadOutgoing;
- SyncEngine.prototype._uploadOutgoing = () => engine._onRecordsWritten.call(engine, [], [deviceBID]);
- let commandsProcessed = 0;
- engine._handleDisplayURIs = (uris) => { commandsProcessed = uris.length };
-
- engine._sync();
- engine.processIncomingCommands(); // Not called by the engine.sync(), gotta call it ourselves
- equal(commandsProcessed, 2, "We processed 2 commands");
-
- let localRemoteRecord = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
- deepEqual(localRemoteRecord.commands, [{
- command: "displayURI", args: ["https://deviceblink.com", deviceBID, "Device B link"]
- },
- {
- command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
- }], "Should be the same because the upload failed");
-
- // Another client sends another link
- server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload({
- id: engine.localID,
- name: "Device A",
- type: "desktop",
- commands: [{
- command: "displayURI", args: ["https://deviceblink.com", deviceBID, "Device B link"]
- },
- {
- command: "displayURI", args: ["https://deviceclink.com", deviceCID, "Device C link"]
- },
- {
- command: "displayURI", args: ["https://deviceclink2.com", deviceCID, "Device C link 2"]
- }],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- // Simulate reboot
- SyncEngine.prototype._uploadOutgoing = oldUploadOutgoing;
- engine = Service.clientsEngine = new ClientEngine(Service);
-
- commandsProcessed = 0;
- engine._handleDisplayURIs = (uris) => { commandsProcessed = uris.length };
- engine._sync();
- engine.processIncomingCommands();
- equal(commandsProcessed, 1, "We processed one command (the other were cleared)");
-
- localRemoteRecord = JSON.parse(JSON.parse(collection.payload(deviceBID)).ciphertext);
- deepEqual(localRemoteRecord.commands, [], "Should be empty");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
-
- // Reset service (remove mocks)
- engine = Service.clientsEngine = new ClientEngine(Service);
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_deleted_commands() {
- _("Verifies commands for a deleted client are discarded");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- let activeID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(activeID, encryptPayload({
- id: activeID,
- name: "Active client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- let deletedID = Utils.makeGUID();
- server.insertWBO("foo", "clients", new ServerWBO(deletedID, encryptPayload({
- id: deletedID,
- name: "Client to delete",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"],
- }), now - 10));
-
- try {
- let store = engine._store;
-
- _("First sync. 2 records downloaded.");
- engine._sync();
-
- _("Delete a record on the server.");
- let collection = server.getCollection("foo", "clients");
- collection.remove(deletedID);
-
- _("Broadcast a command to all clients");
- engine.sendCommand("logout", []);
- engine._sync();
-
- deepEqual(collection.keys().sort(), [activeID, engine.localID].sort(),
- "Should not reupload deleted clients");
-
- let activePayload = JSON.parse(JSON.parse(collection.payload(activeID)).ciphertext);
- deepEqual(activePayload.commands, [{ command: "logout", args: [] }],
- "Should send the command to the active client");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_send_uri_ack() {
- _("Ensure a sent URI is deleted when the client syncs");
-
- let now = Date.now() / 1000;
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- let user = server.user("foo");
-
- new SyncTestingInfrastructure(server.server);
- generateNewKeys(Service.collectionKeys);
-
- try {
- let fakeSenderID = Utils.makeGUID();
-
- _("Initial sync for empty clients collection");
- engine._sync();
- let collection = server.getCollection("foo", "clients");
- let ourPayload = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
- ok(ourPayload, "Should upload our client record");
-
- _("Send a URL to the device on the server");
- ourPayload.commands = [{
- command: "displayURI",
- args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
- }];
- server.insertWBO("foo", "clients", new ServerWBO(engine.localID, encryptPayload(ourPayload), now));
-
- _("Sync again");
- engine._sync();
- deepEqual(engine.localCommands, [{
- command: "displayURI",
- args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
- }], "Should receive incoming URI");
- ok(engine.processIncomingCommands(), "Should process incoming commands");
- const clearedCommands = engine._readCommands()[engine.localID];
- deepEqual(clearedCommands, [{
- command: "displayURI",
- args: ["https://example.com", fakeSenderID, "Yak Herders Anonymous"],
- }], "Should mark the commands as cleared after processing");
-
- _("Check that the command was removed on the server");
- engine._sync();
- ourPayload = JSON.parse(JSON.parse(collection.payload(engine.localID)).ciphertext);
- ok(ourPayload, "Should upload the synced client record");
- deepEqual(ourPayload.commands, [], "Should not reupload cleared commands");
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
- engine._resetClient();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
-add_test(function test_command_sync() {
- _("Notify other clients when writing their record.");
-
- engine._store.wipe();
- generateNewKeys(Service.collectionKeys);
-
- let contents = {
- meta: {global: {engines: {clients: {version: engine.version,
- syncID: engine.syncID}}}},
- clients: {},
- crypto: {}
- };
- let server = serverForUsers({"foo": "password"}, contents);
- new SyncTestingInfrastructure(server.server);
-
- let user = server.user("foo");
- let collection = server.getCollection("foo", "clients");
- let remoteId = Utils.makeGUID();
- let remoteId2 = Utils.makeGUID();
-
- function clientWBO(id) {
- return user.collection("clients").wbo(id);
- }
-
- _("Create remote client record 1");
- server.insertWBO("foo", "clients", new ServerWBO(remoteId, encryptPayload({
- id: remoteId,
- name: "Remote client",
- type: "desktop",
- commands: [],
- version: "48",
- protocols: ["1.5"]
- }), Date.now() / 1000));
-
- _("Create remote client record 2");
- server.insertWBO("foo", "clients", new ServerWBO(remoteId2, encryptPayload({
- id: remoteId2,
- name: "Remote client 2",
- type: "mobile",
- commands: [],
- version: "48",
- protocols: ["1.5"]
- }), Date.now() / 1000));
-
- try {
- equal(collection.count(), 2, "2 remote records written");
- engine._sync();
- equal(collection.count(), 3, "3 remote records written (+1 for the synced local record)");
-
- let notifiedIds;
- engine.sendCommand("wipeAll", []);
- engine._tracker.addChangedID(engine.localID);
- engine.getClientFxaDeviceId = (id) => "fxa-" + id;
- engine._notifyCollectionChanged = (ids) => (notifiedIds = ids);
- _("Syncing.");
- engine._sync();
- deepEqual(notifiedIds, ["fxa-fake-guid-00","fxa-fake-guid-01"]);
- ok(!notifiedIds.includes(engine.getClientFxaDeviceId(engine.localID)),
- "We never notify the local device");
-
- } finally {
- Svc.Prefs.resetBranch("");
- Service.recordManager.clearCache();
-
- try {
- server.deleteCollections("foo");
- } finally {
- server.stop(run_next_test);
- }
- }
-});
-
function run_test() {
initTestLogging("Trace");
Log.repository.getLogger("Sync.Engine.Clients").level = Log.Level.Trace;