|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
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"); |
|
11 |
|
12 initTestLogging(); |
|
13 Service.engineManager.clear(); |
|
14 |
|
15 function QuietStore() { |
|
16 Store.call("Quiet"); |
|
17 } |
|
18 QuietStore.prototype = { |
|
19 getAllIDs: function getAllIDs() { |
|
20 return []; |
|
21 } |
|
22 } |
|
23 |
|
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, |
|
31 |
|
32 _sync: function _sync() { |
|
33 this._syncStartup(); |
|
34 } |
|
35 }; |
|
36 Service.engineManager.register(SteamEngine); |
|
37 |
|
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); |
|
47 |
|
48 // Tracking info/collections. |
|
49 let collectionsHelper = track_collections_helper(); |
|
50 let upd = collectionsHelper.with_updated_collection; |
|
51 |
|
52 function sync_httpd_setup(handlers) { |
|
53 |
|
54 handlers["/1.1/johndoe/info/collections"] = collectionsHelper.handler; |
|
55 delete collectionsHelper.collections.crypto; |
|
56 delete collectionsHelper.collections.meta; |
|
57 |
|
58 let cr = new ServerWBO("keys"); |
|
59 handlers["/1.1/johndoe/storage/crypto/keys"] = |
|
60 upd("crypto", cr.handler()); |
|
61 |
|
62 let cl = new ServerCollection(); |
|
63 handlers["/1.1/johndoe/storage/clients"] = |
|
64 upd("clients", cl.handler()); |
|
65 |
|
66 return httpd_setup(handlers); |
|
67 } |
|
68 |
|
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 } |
|
79 |
|
80 const PAYLOAD = 42; |
|
81 |
|
82 |
|
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; |
|
87 |
|
88 run_next_test(); |
|
89 } |
|
90 |
|
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); |
|
99 |
|
100 try { |
|
101 _("Engine is enabled from the beginning."); |
|
102 Service._ignorePrefObserver = true; |
|
103 engine.enabled = true; |
|
104 Service._ignorePrefObserver = false; |
|
105 |
|
106 _("Sync."); |
|
107 Service.sync(); |
|
108 |
|
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 }); |
|
116 |
|
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); |
|
129 |
|
130 try { |
|
131 _("Enable engine locally."); |
|
132 engine.enabled = true; |
|
133 |
|
134 _("Sync."); |
|
135 Service.sync(); |
|
136 |
|
137 _("Meta record now contains the new engine."); |
|
138 do_check_true(!!metaWBO.data.engines.steam); |
|
139 |
|
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 }); |
|
147 |
|
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); |
|
159 |
|
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); |
|
165 |
|
166 try { |
|
167 _("Disable engine locally."); |
|
168 Service._ignorePrefObserver = true; |
|
169 engine.enabled = true; |
|
170 Service._ignorePrefObserver = false; |
|
171 engine.enabled = false; |
|
172 |
|
173 _("Sync."); |
|
174 Service.sync(); |
|
175 |
|
176 _("Meta record no longer contains engine."); |
|
177 do_check_false(!!metaWBO.data.engines.steam); |
|
178 |
|
179 _("Server records are wiped."); |
|
180 do_check_eq(steamCollection.payload, undefined); |
|
181 |
|
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 }); |
|
189 |
|
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); |
|
201 |
|
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 } |
|
208 |
|
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); |
|
214 |
|
215 _("Disable engine locally."); |
|
216 Service._ignorePrefObserver = true; |
|
217 engine.enabled = true; |
|
218 Service._ignorePrefObserver = false; |
|
219 engine.enabled = false; |
|
220 |
|
221 Svc.Obs.add("weave:ui:sync:error", function onSyncError() { |
|
222 Svc.Obs.remove("weave:ui:sync:error", onSyncError); |
|
223 |
|
224 do_check_eq(Service.status.sync, SERVER_MAINTENANCE); |
|
225 |
|
226 Service.startOver(); |
|
227 server.stop(run_next_test); |
|
228 }); |
|
229 |
|
230 _("Sync."); |
|
231 Service.errorHandler.syncAndReportErrors(); |
|
232 }); |
|
233 |
|
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()), |
|
247 |
|
248 "/1.1/johndoe/storage/steam": |
|
249 upd("steam", new ServerWBO("steam", {}).handler()) |
|
250 }); |
|
251 setUp(server); |
|
252 |
|
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); |
|
260 |
|
261 _("Engine is disabled."); |
|
262 do_check_false(engine.enabled); |
|
263 |
|
264 _("Sync."); |
|
265 Service.sync(); |
|
266 |
|
267 _("Engine is enabled."); |
|
268 do_check_true(engine.enabled); |
|
269 |
|
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 }); |
|
277 |
|
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()), |
|
288 |
|
289 "/1.1/johndoe/storage/steam": |
|
290 upd("steam", new ServerWBO("steam", {}).handler()) |
|
291 }); |
|
292 setUp(server); |
|
293 |
|
294 try { |
|
295 _("Enable engine locally."); |
|
296 Service._ignorePrefObserver = true; |
|
297 engine.enabled = true; |
|
298 Service._ignorePrefObserver = false; |
|
299 |
|
300 _("Sync."); |
|
301 Service.sync(); |
|
302 |
|
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; |
|
308 |
|
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(); |
|
312 |
|
313 _("Engine is disabled."); |
|
314 do_check_false(engine.enabled); |
|
315 |
|
316 } finally { |
|
317 Service.startOver(); |
|
318 server.stop(run_next_test); |
|
319 } |
|
320 }); |
|
321 |
|
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); |
|
334 |
|
335 try { |
|
336 _("Enable engine locally."); |
|
337 Service._ignorePrefObserver = true; |
|
338 engine.enabled = true; |
|
339 Service._ignorePrefObserver = false; |
|
340 |
|
341 _("Sync."); |
|
342 Service.sync(); |
|
343 |
|
344 _("Engine is not disabled: only one client."); |
|
345 do_check_true(engine.enabled); |
|
346 |
|
347 } finally { |
|
348 Service.startOver(); |
|
349 server.stop(run_next_test); |
|
350 } |
|
351 }); |
|
352 |
|
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); |
|
367 |
|
368 try { |
|
369 _("Enable engine locally. Doing it on one is enough."); |
|
370 steamEngine.enabled = true; |
|
371 |
|
372 _("Sync."); |
|
373 Service.sync(); |
|
374 |
|
375 _("Meta record now contains the new engines."); |
|
376 do_check_true(!!metaWBO.data.engines.steam); |
|
377 do_check_true(!!metaWBO.data.engines.stirling); |
|
378 |
|
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 }); |
|
387 |
|
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 }); |
|
401 |
|
402 let steamCollection = new ServerWBO("steam", PAYLOAD); |
|
403 let stirlingCollection = new ServerWBO("stirling", PAYLOAD); |
|
404 |
|
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); |
|
411 |
|
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); |
|
420 |
|
421 _("Sync."); |
|
422 Service.sync(); |
|
423 |
|
424 _("Meta record no longer contains engines."); |
|
425 do_check_false(!!metaWBO.data.engines.steam); |
|
426 do_check_false(!!metaWBO.data.engines.stirling); |
|
427 |
|
428 _("Server records are wiped."); |
|
429 do_check_eq(steamCollection.payload, undefined); |
|
430 do_check_eq(stirlingCollection.payload, undefined); |
|
431 |
|
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 }); |