Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 Cu.import("resource://services-sync/constants.js");
5 Cu.import("resource://services-sync/engines.js");
6 Cu.import("resource://services-sync/engines/clients.js");
7 Cu.import("resource://services-sync/record.js");
8 Cu.import("resource://services-sync/service.js");
9 Cu.import("resource://services-sync/util.js");
10 Cu.import("resource://testing-common/services/sync/utils.js");
12 initTestLogging();
13 Service.engineManager.clear();
15 function QuietStore() {
16 Store.call("Quiet");
17 }
18 QuietStore.prototype = {
19 getAllIDs: function getAllIDs() {
20 return [];
21 }
22 }
24 function SteamEngine() {
25 SyncEngine.call(this, "Steam", Service);
26 }
27 SteamEngine.prototype = {
28 __proto__: SyncEngine.prototype,
29 // We're not interested in engine sync but what the service does.
30 _storeObj: QuietStore,
32 _sync: function _sync() {
33 this._syncStartup();
34 }
35 };
36 Service.engineManager.register(SteamEngine);
38 function StirlingEngine() {
39 SyncEngine.call(this, "Stirling", Service);
40 }
41 StirlingEngine.prototype = {
42 __proto__: SteamEngine.prototype,
43 // This engine's enabled state is the same as the SteamEngine's.
44 get prefName() "steam"
45 };
46 Service.engineManager.register(StirlingEngine);
48 // Tracking info/collections.
49 let collectionsHelper = track_collections_helper();
50 let upd = collectionsHelper.with_updated_collection;
52 function sync_httpd_setup(handlers) {
54 handlers["/1.1/johndoe/info/collections"] = collectionsHelper.handler;
55 delete collectionsHelper.collections.crypto;
56 delete collectionsHelper.collections.meta;
58 let cr = new ServerWBO("keys");
59 handlers["/1.1/johndoe/storage/crypto/keys"] =
60 upd("crypto", cr.handler());
62 let cl = new ServerCollection();
63 handlers["/1.1/johndoe/storage/clients"] =
64 upd("clients", cl.handler());
66 return httpd_setup(handlers);
67 }
69 function setUp(server) {
70 new SyncTestingInfrastructure(server, "johndoe", "ilovejane",
71 "abcdeabcdeabcdeabcdeabcdea");
72 // Ensure that the server has valid keys so that logging in will work and not
73 // result in a server wipe, rendering many of these tests useless.
74 generateNewKeys(Service.collectionKeys);
75 let serverKeys = Service.collectionKeys.asWBO("crypto", "keys");
76 serverKeys.encrypt(Service.identity.syncKeyBundle);
77 return serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success;
78 }
80 const PAYLOAD = 42;
83 function run_test() {
84 initTestLogging("Trace");
85 Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
86 Log.repository.getLogger("Sync.ErrorHandler").level = Log.Level.Trace;
88 run_next_test();
89 }
91 add_test(function test_newAccount() {
92 _("Test: New account does not disable locally enabled engines.");
93 let engine = Service.engineManager.get("steam");
94 let server = sync_httpd_setup({
95 "/1.1/johndoe/storage/meta/global": new ServerWBO("global", {}).handler(),
96 "/1.1/johndoe/storage/steam": new ServerWBO("steam", {}).handler()
97 });
98 setUp(server);
100 try {
101 _("Engine is enabled from the beginning.");
102 Service._ignorePrefObserver = true;
103 engine.enabled = true;
104 Service._ignorePrefObserver = false;
106 _("Sync.");
107 Service.sync();
109 _("Engine continues to be enabled.");
110 do_check_true(engine.enabled);
111 } finally {
112 Service.startOver();
113 server.stop(run_next_test);
114 }
115 });
117 add_test(function test_enabledLocally() {
118 _("Test: Engine is disabled on remote clients and enabled locally");
119 Service.syncID = "abcdefghij";
120 let engine = Service.engineManager.get("steam");
121 let metaWBO = new ServerWBO("global", {syncID: Service.syncID,
122 storageVersion: STORAGE_VERSION,
123 engines: {}});
124 let server = sync_httpd_setup({
125 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
126 "/1.1/johndoe/storage/steam": new ServerWBO("steam", {}).handler()
127 });
128 setUp(server);
130 try {
131 _("Enable engine locally.");
132 engine.enabled = true;
134 _("Sync.");
135 Service.sync();
137 _("Meta record now contains the new engine.");
138 do_check_true(!!metaWBO.data.engines.steam);
140 _("Engine continues to be enabled.");
141 do_check_true(engine.enabled);
142 } finally {
143 Service.startOver();
144 server.stop(run_next_test);
145 }
146 });
148 add_test(function test_disabledLocally() {
149 _("Test: Engine is enabled on remote clients and disabled locally");
150 Service.syncID = "abcdefghij";
151 let engine = Service.engineManager.get("steam");
152 let metaWBO = new ServerWBO("global", {
153 syncID: Service.syncID,
154 storageVersion: STORAGE_VERSION,
155 engines: {steam: {syncID: engine.syncID,
156 version: engine.version}}
157 });
158 let steamCollection = new ServerWBO("steam", PAYLOAD);
160 let server = sync_httpd_setup({
161 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
162 "/1.1/johndoe/storage/steam": steamCollection.handler()
163 });
164 setUp(server);
166 try {
167 _("Disable engine locally.");
168 Service._ignorePrefObserver = true;
169 engine.enabled = true;
170 Service._ignorePrefObserver = false;
171 engine.enabled = false;
173 _("Sync.");
174 Service.sync();
176 _("Meta record no longer contains engine.");
177 do_check_false(!!metaWBO.data.engines.steam);
179 _("Server records are wiped.");
180 do_check_eq(steamCollection.payload, undefined);
182 _("Engine continues to be disabled.");
183 do_check_false(engine.enabled);
184 } finally {
185 Service.startOver();
186 server.stop(run_next_test);
187 }
188 });
190 add_test(function test_disabledLocally_wipe503() {
191 _("Test: Engine is enabled on remote clients and disabled locally");
192 Service.syncID = "abcdefghij";
193 let engine = Service.engineManager.get("steam");
194 let metaWBO = new ServerWBO("global", {
195 syncID: Service.syncID,
196 storageVersion: STORAGE_VERSION,
197 engines: {steam: {syncID: engine.syncID,
198 version: engine.version}}
199 });
200 let steamCollection = new ServerWBO("steam", PAYLOAD);
202 function service_unavailable(request, response) {
203 let body = "Service Unavailable";
204 response.setStatusLine(request.httpVersion, 503, "Service Unavailable");
205 response.setHeader("Retry-After", "23");
206 response.bodyOutputStream.write(body, body.length);
207 }
209 let server = sync_httpd_setup({
210 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
211 "/1.1/johndoe/storage/steam": service_unavailable
212 });
213 setUp(server);
215 _("Disable engine locally.");
216 Service._ignorePrefObserver = true;
217 engine.enabled = true;
218 Service._ignorePrefObserver = false;
219 engine.enabled = false;
221 Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
222 Svc.Obs.remove("weave:ui:sync:error", onSyncError);
224 do_check_eq(Service.status.sync, SERVER_MAINTENANCE);
226 Service.startOver();
227 server.stop(run_next_test);
228 });
230 _("Sync.");
231 Service.errorHandler.syncAndReportErrors();
232 });
234 add_test(function test_enabledRemotely() {
235 _("Test: Engine is disabled locally and enabled on a remote client");
236 Service.syncID = "abcdefghij";
237 let engine = Service.engineManager.get("steam");
238 let metaWBO = new ServerWBO("global", {
239 syncID: Service.syncID,
240 storageVersion: STORAGE_VERSION,
241 engines: {steam: {syncID: engine.syncID,
242 version: engine.version}}
243 });
244 let server = sync_httpd_setup({
245 "/1.1/johndoe/storage/meta/global":
246 upd("meta", metaWBO.handler()),
248 "/1.1/johndoe/storage/steam":
249 upd("steam", new ServerWBO("steam", {}).handler())
250 });
251 setUp(server);
253 // We need to be very careful how we do this, so that we don't trigger a
254 // fresh start!
255 try {
256 _("Upload some keys to avoid a fresh start.");
257 let wbo = Service.collectionKeys.generateNewKeysWBO();
258 wbo.encrypt(Service.identity.syncKeyBundle);
259 do_check_eq(200, wbo.upload(Service.resource(Service.cryptoKeysURL)).status);
261 _("Engine is disabled.");
262 do_check_false(engine.enabled);
264 _("Sync.");
265 Service.sync();
267 _("Engine is enabled.");
268 do_check_true(engine.enabled);
270 _("Meta record still present.");
271 do_check_eq(metaWBO.data.engines.steam.syncID, engine.syncID);
272 } finally {
273 Service.startOver();
274 server.stop(run_next_test);
275 }
276 });
278 add_test(function test_disabledRemotelyTwoClients() {
279 _("Test: Engine is enabled locally and disabled on a remote client... with two clients.");
280 Service.syncID = "abcdefghij";
281 let engine = Service.engineManager.get("steam");
282 let metaWBO = new ServerWBO("global", {syncID: Service.syncID,
283 storageVersion: STORAGE_VERSION,
284 engines: {}});
285 let server = sync_httpd_setup({
286 "/1.1/johndoe/storage/meta/global":
287 upd("meta", metaWBO.handler()),
289 "/1.1/johndoe/storage/steam":
290 upd("steam", new ServerWBO("steam", {}).handler())
291 });
292 setUp(server);
294 try {
295 _("Enable engine locally.");
296 Service._ignorePrefObserver = true;
297 engine.enabled = true;
298 Service._ignorePrefObserver = false;
300 _("Sync.");
301 Service.sync();
303 _("Disable engine by deleting from meta/global.");
304 let d = metaWBO.data;
305 delete d.engines["steam"];
306 metaWBO.payload = JSON.stringify(d);
307 metaWBO.modified = Date.now() / 1000;
309 _("Add a second client and verify that the local pref is changed.");
310 Service.clientsEngine._store._remoteClients["foobar"] = {name: "foobar", type: "desktop"};
311 Service.sync();
313 _("Engine is disabled.");
314 do_check_false(engine.enabled);
316 } finally {
317 Service.startOver();
318 server.stop(run_next_test);
319 }
320 });
322 add_test(function test_disabledRemotely() {
323 _("Test: Engine is enabled locally and disabled on a remote client");
324 Service.syncID = "abcdefghij";
325 let engine = Service.engineManager.get("steam");
326 let metaWBO = new ServerWBO("global", {syncID: Service.syncID,
327 storageVersion: STORAGE_VERSION,
328 engines: {}});
329 let server = sync_httpd_setup({
330 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
331 "/1.1/johndoe/storage/steam": new ServerWBO("steam", {}).handler()
332 });
333 setUp(server);
335 try {
336 _("Enable engine locally.");
337 Service._ignorePrefObserver = true;
338 engine.enabled = true;
339 Service._ignorePrefObserver = false;
341 _("Sync.");
342 Service.sync();
344 _("Engine is not disabled: only one client.");
345 do_check_true(engine.enabled);
347 } finally {
348 Service.startOver();
349 server.stop(run_next_test);
350 }
351 });
353 add_test(function test_dependentEnginesEnabledLocally() {
354 _("Test: Engine is disabled on remote clients and enabled locally");
355 Service.syncID = "abcdefghij";
356 let steamEngine = Service.engineManager.get("steam");
357 let stirlingEngine = Service.engineManager.get("stirling");
358 let metaWBO = new ServerWBO("global", {syncID: Service.syncID,
359 storageVersion: STORAGE_VERSION,
360 engines: {}});
361 let server = sync_httpd_setup({
362 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
363 "/1.1/johndoe/storage/steam": new ServerWBO("steam", {}).handler(),
364 "/1.1/johndoe/storage/stirling": new ServerWBO("stirling", {}).handler()
365 });
366 setUp(server);
368 try {
369 _("Enable engine locally. Doing it on one is enough.");
370 steamEngine.enabled = true;
372 _("Sync.");
373 Service.sync();
375 _("Meta record now contains the new engines.");
376 do_check_true(!!metaWBO.data.engines.steam);
377 do_check_true(!!metaWBO.data.engines.stirling);
379 _("Engines continue to be enabled.");
380 do_check_true(steamEngine.enabled);
381 do_check_true(stirlingEngine.enabled);
382 } finally {
383 Service.startOver();
384 server.stop(run_next_test);
385 }
386 });
388 add_test(function test_dependentEnginesDisabledLocally() {
389 _("Test: Two dependent engines are enabled on remote clients and disabled locally");
390 Service.syncID = "abcdefghij";
391 let steamEngine = Service.engineManager.get("steam");
392 let stirlingEngine = Service.engineManager.get("stirling");
393 let metaWBO = new ServerWBO("global", {
394 syncID: Service.syncID,
395 storageVersion: STORAGE_VERSION,
396 engines: {steam: {syncID: steamEngine.syncID,
397 version: steamEngine.version},
398 stirling: {syncID: stirlingEngine.syncID,
399 version: stirlingEngine.version}}
400 });
402 let steamCollection = new ServerWBO("steam", PAYLOAD);
403 let stirlingCollection = new ServerWBO("stirling", PAYLOAD);
405 let server = sync_httpd_setup({
406 "/1.1/johndoe/storage/meta/global": metaWBO.handler(),
407 "/1.1/johndoe/storage/steam": steamCollection.handler(),
408 "/1.1/johndoe/storage/stirling": stirlingCollection.handler()
409 });
410 setUp(server);
412 try {
413 _("Disable engines locally. Doing it on one is enough.");
414 Service._ignorePrefObserver = true;
415 steamEngine.enabled = true;
416 do_check_true(stirlingEngine.enabled);
417 Service._ignorePrefObserver = false;
418 steamEngine.enabled = false;
419 do_check_false(stirlingEngine.enabled);
421 _("Sync.");
422 Service.sync();
424 _("Meta record no longer contains engines.");
425 do_check_false(!!metaWBO.data.engines.steam);
426 do_check_false(!!metaWBO.data.engines.stirling);
428 _("Server records are wiped.");
429 do_check_eq(steamCollection.payload, undefined);
430 do_check_eq(stirlingCollection.payload, undefined);
432 _("Engines continue to be disabled.");
433 do_check_false(steamEngine.enabled);
434 do_check_false(stirlingEngine.enabled);
435 } finally {
436 Service.startOver();
437 server.stop(run_next_test);
438 }
439 });