/services/sync/tests/unit/test_errorhandler.js

http://github.com/zpao/v8monkey · JavaScript · 1692 lines · 1210 code · 347 blank · 135 comment · 1 complexity · 6ce6f8be26ca8a9993f3ce7d38cd95a0 MD5 · raw file

Large files are truncated click here to view the full file

  1. /* Any copyright is dedicated to the Public Domain.
  2. http://creativecommons.org/publicdomain/zero/1.0/ */
  3. Cu.import("resource://services-sync/engines/clients.js");
  4. Cu.import("resource://services-sync/constants.js");
  5. Cu.import("resource://services-sync/policies.js");
  6. Cu.import("resource://services-sync/status.js");
  7. Svc.DefaultPrefs.set("registerEngines", "");
  8. Cu.import("resource://services-sync/service.js");
  9. const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
  10. const LOG_PREFIX_SUCCESS = "success-";
  11. const LOG_PREFIX_ERROR = "error-";
  12. const PROLONGED_ERROR_DURATION =
  13. (Svc.Prefs.get('errorhandler.networkFailureReportTimeout') * 2) * 1000;
  14. const NON_PROLONGED_ERROR_DURATION =
  15. (Svc.Prefs.get('errorhandler.networkFailureReportTimeout') / 2) * 1000;
  16. function setLastSync(lastSyncValue) {
  17. Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString());
  18. }
  19. function CatapultEngine() {
  20. SyncEngine.call(this, "Catapult");
  21. }
  22. CatapultEngine.prototype = {
  23. __proto__: SyncEngine.prototype,
  24. exception: null, // tests fill this in
  25. _sync: function _sync() {
  26. if (this.exception) {
  27. throw this.exception;
  28. }
  29. }
  30. };
  31. Engines.register(CatapultEngine);
  32. function run_test() {
  33. initTestLogging("Trace");
  34. Log4Moz.repository.getLogger("Sync.Service").level = Log4Moz.Level.Trace;
  35. Log4Moz.repository.getLogger("Sync.SyncScheduler").level = Log4Moz.Level.Trace;
  36. Log4Moz.repository.getLogger("Sync.ErrorHandler").level = Log4Moz.Level.Trace;
  37. run_next_test();
  38. }
  39. function generateCredentialsChangedFailure() {
  40. // Make sync fail due to changed credentials. We simply re-encrypt
  41. // the keys with a different Sync Key, without changing the local one.
  42. let newSyncKeyBundle = new SyncKeyBundle(PWDMGR_PASSPHRASE_REALM, Service.username);
  43. newSyncKeyBundle.keyStr = "23456234562345623456234562";
  44. let keys = CollectionKeys.asWBO();
  45. keys.encrypt(newSyncKeyBundle);
  46. keys.upload(Service.cryptoKeysURL);
  47. }
  48. function service_unavailable(request, response) {
  49. let body = "Service Unavailable";
  50. response.setStatusLine(request.httpVersion, 503, "Service Unavailable");
  51. response.setHeader("Retry-After", "42");
  52. response.bodyOutputStream.write(body, body.length);
  53. }
  54. function sync_httpd_setup() {
  55. let global = new ServerWBO("global", {
  56. syncID: Service.syncID,
  57. storageVersion: STORAGE_VERSION,
  58. engines: {clients: {version: Clients.version,
  59. syncID: Clients.syncID},
  60. catapult: {version: Engines.get("catapult").version,
  61. syncID: Engines.get("catapult").syncID}}
  62. });
  63. let clientsColl = new ServerCollection({}, true);
  64. // Tracking info/collections.
  65. let collectionsHelper = track_collections_helper();
  66. let upd = collectionsHelper.with_updated_collection;
  67. let handler_401 = httpd_handler(401, "Unauthorized");
  68. return httpd_setup({
  69. // Normal server behaviour.
  70. "/1.1/johndoe/storage/meta/global": upd("meta", global.handler()),
  71. "/1.1/johndoe/info/collections": collectionsHelper.handler,
  72. "/1.1/johndoe/storage/crypto/keys":
  73. upd("crypto", (new ServerWBO("keys")).handler()),
  74. "/1.1/johndoe/storage/clients": upd("clients", clientsColl.handler()),
  75. // Credentials are wrong or node reallocated.
  76. "/1.1/janedoe/storage/meta/global": handler_401,
  77. "/1.1/janedoe/info/collections": handler_401,
  78. // Maintenance or overloaded (503 + Retry-After) at info/collections.
  79. "/maintenance/1.1/broken.info/info/collections": service_unavailable,
  80. // Maintenance or overloaded (503 + Retry-After) at meta/global.
  81. "/maintenance/1.1/broken.meta/storage/meta/global": service_unavailable,
  82. "/maintenance/1.1/broken.meta/info/collections": collectionsHelper.handler,
  83. // Maintenance or overloaded (503 + Retry-After) at crypto/keys.
  84. "/maintenance/1.1/broken.keys/storage/meta/global": upd("meta", global.handler()),
  85. "/maintenance/1.1/broken.keys/info/collections": collectionsHelper.handler,
  86. "/maintenance/1.1/broken.keys/storage/crypto/keys": service_unavailable,
  87. // Maintenance or overloaded (503 + Retry-After) at wiping collection.
  88. "/maintenance/1.1/broken.wipe/info/collections": collectionsHelper.handler,
  89. "/maintenance/1.1/broken.wipe/storage/meta/global": upd("meta", global.handler()),
  90. "/maintenance/1.1/broken.wipe/storage/crypto/keys":
  91. upd("crypto", (new ServerWBO("keys")).handler()),
  92. "/maintenance/1.1/broken.wipe/storage": service_unavailable,
  93. "/maintenance/1.1/broken.wipe/storage/clients": upd("clients", clientsColl.handler()),
  94. "/maintenance/1.1/broken.wipe/storage/catapult": service_unavailable
  95. });
  96. }
  97. function setUp() {
  98. Service.username = "johndoe";
  99. Service.password = "ilovejane";
  100. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  101. Service.serverURL = "http://localhost:8080/";
  102. Service.clusterURL = "http://localhost:8080/";
  103. return generateAndUploadKeys();
  104. }
  105. function generateAndUploadKeys() {
  106. generateNewKeys();
  107. let serverKeys = CollectionKeys.asWBO("crypto", "keys");
  108. serverKeys.encrypt(Service.syncKeyBundle);
  109. return serverKeys.upload(Service.cryptoKeysURL).success;
  110. }
  111. function clean() {
  112. Service.startOver();
  113. Status.resetSync();
  114. Status.resetBackoff();
  115. }
  116. add_test(function test_401_logout() {
  117. let server = sync_httpd_setup();
  118. setUp();
  119. // By calling sync, we ensure we're logged in.
  120. Service.sync();
  121. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  122. do_check_true(Service.isLoggedIn);
  123. Svc.Obs.add("weave:service:sync:error", onSyncError);
  124. function onSyncError() {
  125. _("Got weave:service:sync:error in first sync.");
  126. Svc.Obs.remove("weave:service:sync:error", onSyncError);
  127. // Wait for the automatic next sync.
  128. function onLoginError() {
  129. _("Got weave:service:login:error in second sync.");
  130. Svc.Obs.remove("weave:service:login:error", onLoginError);
  131. do_check_eq(Status.login, LOGIN_FAILED_LOGIN_REJECTED);
  132. do_check_false(Service.isLoggedIn);
  133. // Clean up.
  134. Utils.nextTick(function () {
  135. Service.startOver();
  136. server.stop(run_next_test);
  137. });
  138. }
  139. Svc.Obs.add("weave:service:login:error", onLoginError);
  140. }
  141. // Make sync fail due to login rejected.
  142. Service.username = "janedoe";
  143. _("Starting first sync.");
  144. Service.sync();
  145. _("First sync done.");
  146. });
  147. add_test(function test_credentials_changed_logout() {
  148. let server = sync_httpd_setup();
  149. setUp();
  150. // By calling sync, we ensure we're logged in.
  151. Service.sync();
  152. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  153. do_check_true(Service.isLoggedIn);
  154. generateCredentialsChangedFailure();
  155. Service.sync();
  156. do_check_eq(Status.sync, CREDENTIALS_CHANGED);
  157. do_check_false(Service.isLoggedIn);
  158. // Clean up.
  159. Service.startOver();
  160. server.stop(run_next_test);
  161. });
  162. add_test(function test_no_lastSync_pref() {
  163. // Test reported error.
  164. Status.resetSync();
  165. ErrorHandler.dontIgnoreErrors = true;
  166. Status.sync = CREDENTIALS_CHANGED;
  167. do_check_true(ErrorHandler.shouldReportError());
  168. // Test unreported error.
  169. Status.resetSync();
  170. ErrorHandler.dontIgnoreErrors = true;
  171. Status.login = LOGIN_FAILED_NETWORK_ERROR;
  172. do_check_true(ErrorHandler.shouldReportError());
  173. run_next_test();
  174. });
  175. add_test(function test_shouldReportError() {
  176. Status.login = MASTER_PASSWORD_LOCKED;
  177. do_check_false(ErrorHandler.shouldReportError());
  178. // Give ourselves a clusterURL so that the temporary 401 no-error situation
  179. // doesn't come into play.
  180. Service.clusterURL = "http://localhost:8080/";
  181. // Test dontIgnoreErrors, non-network, non-prolonged, login error reported
  182. Status.resetSync();
  183. setLastSync(NON_PROLONGED_ERROR_DURATION);
  184. ErrorHandler.dontIgnoreErrors = true;
  185. Status.login = LOGIN_FAILED_NO_PASSWORD;
  186. do_check_true(ErrorHandler.shouldReportError());
  187. // Test dontIgnoreErrors, non-network, non-prolonged, sync error reported
  188. Status.resetSync();
  189. setLastSync(NON_PROLONGED_ERROR_DURATION);
  190. ErrorHandler.dontIgnoreErrors = true;
  191. Status.sync = CREDENTIALS_CHANGED;
  192. do_check_true(ErrorHandler.shouldReportError());
  193. // Test dontIgnoreErrors, non-network, prolonged, login error reported
  194. Status.resetSync();
  195. setLastSync(PROLONGED_ERROR_DURATION);
  196. ErrorHandler.dontIgnoreErrors = true;
  197. Status.login = LOGIN_FAILED_NO_PASSWORD;
  198. do_check_true(ErrorHandler.shouldReportError());
  199. // Test dontIgnoreErrors, non-network, prolonged, sync error reported
  200. Status.resetSync();
  201. setLastSync(PROLONGED_ERROR_DURATION);
  202. ErrorHandler.dontIgnoreErrors = true;
  203. Status.sync = CREDENTIALS_CHANGED;
  204. do_check_true(ErrorHandler.shouldReportError());
  205. // Test dontIgnoreErrors, network, non-prolonged, login error reported
  206. Status.resetSync();
  207. setLastSync(NON_PROLONGED_ERROR_DURATION);
  208. ErrorHandler.dontIgnoreErrors = true;
  209. Status.login = LOGIN_FAILED_NETWORK_ERROR;
  210. do_check_true(ErrorHandler.shouldReportError());
  211. // Test dontIgnoreErrors, network, non-prolonged, sync error reported
  212. Status.resetSync();
  213. setLastSync(NON_PROLONGED_ERROR_DURATION);
  214. ErrorHandler.dontIgnoreErrors = true;
  215. Status.sync = LOGIN_FAILED_NETWORK_ERROR;
  216. do_check_true(ErrorHandler.shouldReportError());
  217. // Test dontIgnoreErrors, network, prolonged, login error reported
  218. Status.resetSync();
  219. setLastSync(PROLONGED_ERROR_DURATION);
  220. ErrorHandler.dontIgnoreErrors = true;
  221. Status.login = LOGIN_FAILED_NETWORK_ERROR;
  222. do_check_true(ErrorHandler.shouldReportError());
  223. // Test dontIgnoreErrors, network, prolonged, sync error reported
  224. Status.resetSync();
  225. setLastSync(PROLONGED_ERROR_DURATION);
  226. ErrorHandler.dontIgnoreErrors = true;
  227. Status.sync = LOGIN_FAILED_NETWORK_ERROR;
  228. do_check_true(ErrorHandler.shouldReportError());
  229. // Test non-network, prolonged, login error reported
  230. Status.resetSync();
  231. setLastSync(PROLONGED_ERROR_DURATION);
  232. ErrorHandler.dontIgnoreErrors = false;
  233. Status.login = LOGIN_FAILED_NO_PASSWORD;
  234. do_check_true(ErrorHandler.shouldReportError());
  235. // Test non-network, prolonged, sync error reported
  236. Status.resetSync();
  237. setLastSync(PROLONGED_ERROR_DURATION);
  238. ErrorHandler.dontIgnoreErrors = false;
  239. Status.sync = CREDENTIALS_CHANGED;
  240. do_check_true(ErrorHandler.shouldReportError());
  241. // Test network, prolonged, login error reported
  242. Status.resetSync();
  243. setLastSync(PROLONGED_ERROR_DURATION);
  244. ErrorHandler.dontIgnoreErrors = false;
  245. Status.login = LOGIN_FAILED_NETWORK_ERROR;
  246. do_check_true(ErrorHandler.shouldReportError());
  247. // Test network, prolonged, sync error reported
  248. Status.resetSync();
  249. setLastSync(PROLONGED_ERROR_DURATION);
  250. ErrorHandler.dontIgnoreErrors = false;
  251. Status.sync = LOGIN_FAILED_NETWORK_ERROR;
  252. do_check_true(ErrorHandler.shouldReportError());
  253. // Test non-network, non-prolonged, login error reported
  254. Status.resetSync();
  255. setLastSync(NON_PROLONGED_ERROR_DURATION);
  256. ErrorHandler.dontIgnoreErrors = false;
  257. Status.login = LOGIN_FAILED_NO_PASSWORD;
  258. do_check_true(ErrorHandler.shouldReportError());
  259. // Test non-network, non-prolonged, sync error reported
  260. Status.resetSync();
  261. setLastSync(NON_PROLONGED_ERROR_DURATION);
  262. ErrorHandler.dontIgnoreErrors = false;
  263. Status.sync = CREDENTIALS_CHANGED;
  264. do_check_true(ErrorHandler.shouldReportError());
  265. // Test network, non-prolonged, login error reported
  266. Status.resetSync();
  267. setLastSync(NON_PROLONGED_ERROR_DURATION);
  268. ErrorHandler.dontIgnoreErrors = false;
  269. Status.login = LOGIN_FAILED_NETWORK_ERROR;
  270. do_check_false(ErrorHandler.shouldReportError());
  271. // Test network, non-prolonged, sync error reported
  272. Status.resetSync();
  273. setLastSync(NON_PROLONGED_ERROR_DURATION);
  274. ErrorHandler.dontIgnoreErrors = false;
  275. Status.sync = LOGIN_FAILED_NETWORK_ERROR;
  276. do_check_false(ErrorHandler.shouldReportError());
  277. // Test server maintenance, sync errors are not reported
  278. Status.resetSync();
  279. setLastSync(NON_PROLONGED_ERROR_DURATION);
  280. ErrorHandler.dontIgnoreErrors = false;
  281. Status.sync = SERVER_MAINTENANCE;
  282. do_check_false(ErrorHandler.shouldReportError());
  283. // Test server maintenance, login errors are not reported
  284. Status.resetSync();
  285. setLastSync(NON_PROLONGED_ERROR_DURATION);
  286. ErrorHandler.dontIgnoreErrors = false;
  287. Status.login = SERVER_MAINTENANCE;
  288. do_check_false(ErrorHandler.shouldReportError());
  289. // Test prolonged, server maintenance, sync errors are reported
  290. Status.resetSync();
  291. setLastSync(PROLONGED_ERROR_DURATION);
  292. ErrorHandler.dontIgnoreErrors = false;
  293. Status.sync = SERVER_MAINTENANCE;
  294. do_check_true(ErrorHandler.shouldReportError());
  295. // Test prolonged, server maintenance, login errors are reported
  296. Status.resetSync();
  297. setLastSync(PROLONGED_ERROR_DURATION);
  298. ErrorHandler.dontIgnoreErrors = false;
  299. Status.login = SERVER_MAINTENANCE;
  300. do_check_true(ErrorHandler.shouldReportError());
  301. // Test dontIgnoreErrors, server maintenance, sync errors are reported
  302. Status.resetSync();
  303. setLastSync(NON_PROLONGED_ERROR_DURATION);
  304. ErrorHandler.dontIgnoreErrors = true;
  305. Status.sync = SERVER_MAINTENANCE;
  306. do_check_true(ErrorHandler.shouldReportError());
  307. // Test dontIgnoreErrors, server maintenance, login errors are reported
  308. Status.resetSync();
  309. setLastSync(NON_PROLONGED_ERROR_DURATION);
  310. ErrorHandler.dontIgnoreErrors = true;
  311. Status.login = SERVER_MAINTENANCE;
  312. do_check_true(ErrorHandler.shouldReportError());
  313. // Test dontIgnoreErrors, prolonged, server maintenance,
  314. // sync errors are reported
  315. Status.resetSync();
  316. setLastSync(PROLONGED_ERROR_DURATION);
  317. ErrorHandler.dontIgnoreErrors = true;
  318. Status.sync = SERVER_MAINTENANCE;
  319. do_check_true(ErrorHandler.shouldReportError());
  320. // Test dontIgnoreErrors, prolonged, server maintenance,
  321. // login errors are reported
  322. Status.resetSync();
  323. setLastSync(PROLONGED_ERROR_DURATION);
  324. ErrorHandler.dontIgnoreErrors = true;
  325. Status.login = SERVER_MAINTENANCE;
  326. do_check_true(ErrorHandler.shouldReportError());
  327. run_next_test();
  328. });
  329. add_test(function test_shouldReportError_master_password() {
  330. _("Test error ignored due to locked master password");
  331. let server = sync_httpd_setup();
  332. setUp();
  333. // Monkey patch Service.verifyLogin to imitate
  334. // master password being locked.
  335. Service._verifyLogin = Service.verifyLogin;
  336. Service.verifyLogin = function () {
  337. Status.login = MASTER_PASSWORD_LOCKED;
  338. return false;
  339. };
  340. setLastSync(NON_PROLONGED_ERROR_DURATION);
  341. Service.sync();
  342. do_check_false(ErrorHandler.shouldReportError());
  343. // Clean up.
  344. Service.verifyLogin = Service._verifyLogin;
  345. clean();
  346. server.stop(run_next_test);
  347. });
  348. add_test(function test_login_syncAndReportErrors_non_network_error() {
  349. // Test non-network errors are reported
  350. // when calling syncAndReportErrors
  351. let server = sync_httpd_setup();
  352. setUp();
  353. Service.password = "";
  354. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  355. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  356. do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD);
  357. clean();
  358. server.stop(run_next_test);
  359. });
  360. setLastSync(NON_PROLONGED_ERROR_DURATION);
  361. ErrorHandler.syncAndReportErrors();
  362. });
  363. add_test(function test_sync_syncAndReportErrors_non_network_error() {
  364. // Test non-network errors are reported
  365. // when calling syncAndReportErrors
  366. let server = sync_httpd_setup();
  367. setUp();
  368. // By calling sync, we ensure we're logged in.
  369. Service.sync();
  370. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  371. do_check_true(Service.isLoggedIn);
  372. generateCredentialsChangedFailure();
  373. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  374. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  375. do_check_eq(Status.sync, CREDENTIALS_CHANGED);
  376. clean();
  377. server.stop(run_next_test);
  378. });
  379. setLastSync(NON_PROLONGED_ERROR_DURATION);
  380. ErrorHandler.syncAndReportErrors();
  381. });
  382. add_test(function test_login_syncAndReportErrors_prolonged_non_network_error() {
  383. // Test prolonged, non-network errors are
  384. // reported when calling syncAndReportErrors.
  385. let server = sync_httpd_setup();
  386. setUp();
  387. Service.password = "";
  388. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  389. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  390. do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD);
  391. clean();
  392. server.stop(run_next_test);
  393. });
  394. setLastSync(PROLONGED_ERROR_DURATION);
  395. ErrorHandler.syncAndReportErrors();
  396. });
  397. add_test(function test_sync_syncAndReportErrors_prolonged_non_network_error() {
  398. // Test prolonged, non-network errors are
  399. // reported when calling syncAndReportErrors.
  400. let server = sync_httpd_setup();
  401. setUp();
  402. // By calling sync, we ensure we're logged in.
  403. Service.sync();
  404. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  405. do_check_true(Service.isLoggedIn);
  406. generateCredentialsChangedFailure();
  407. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  408. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  409. do_check_eq(Status.sync, CREDENTIALS_CHANGED);
  410. clean();
  411. server.stop(run_next_test);
  412. });
  413. setLastSync(PROLONGED_ERROR_DURATION);
  414. ErrorHandler.syncAndReportErrors();
  415. });
  416. add_test(function test_login_syncAndReportErrors_network_error() {
  417. // Test network errors are reported when calling syncAndReportErrors.
  418. Service.username = "johndoe";
  419. Service.password = "ilovejane";
  420. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  421. Service.clusterURL = "http://localhost:8080/";
  422. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  423. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  424. do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR);
  425. clean();
  426. run_next_test();
  427. });
  428. setLastSync(NON_PROLONGED_ERROR_DURATION);
  429. ErrorHandler.syncAndReportErrors();
  430. });
  431. add_test(function test_sync_syncAndReportErrors_network_error() {
  432. // Test network errors are reported when calling syncAndReportErrors.
  433. Services.io.offline = true;
  434. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  435. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  436. do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
  437. Services.io.offline = false;
  438. clean();
  439. run_next_test();
  440. });
  441. setLastSync(NON_PROLONGED_ERROR_DURATION);
  442. ErrorHandler.syncAndReportErrors();
  443. });
  444. add_test(function test_login_syncAndReportErrors_prolonged_network_error() {
  445. // Test prolonged, network errors are reported
  446. // when calling syncAndReportErrors.
  447. Service.username = "johndoe";
  448. Service.password = "ilovejane";
  449. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  450. Service.clusterURL = "http://localhost:8080/";
  451. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  452. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  453. do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR);
  454. clean();
  455. run_next_test();
  456. });
  457. setLastSync(PROLONGED_ERROR_DURATION);
  458. ErrorHandler.syncAndReportErrors();
  459. });
  460. add_test(function test_sync_syncAndReportErrors_prolonged_network_error() {
  461. // Test prolonged, network errors are reported
  462. // when calling syncAndReportErrors.
  463. Services.io.offline = true;
  464. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  465. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  466. do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
  467. Services.io.offline = false;
  468. clean();
  469. run_next_test();
  470. });
  471. setLastSync(PROLONGED_ERROR_DURATION);
  472. ErrorHandler.syncAndReportErrors();
  473. });
  474. add_test(function test_login_prolonged_non_network_error() {
  475. // Test prolonged, non-network errors are reported
  476. let server = sync_httpd_setup();
  477. setUp();
  478. Service.password = "";
  479. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  480. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  481. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  482. clean();
  483. server.stop(run_next_test);
  484. });
  485. setLastSync(PROLONGED_ERROR_DURATION);
  486. Service.sync();
  487. });
  488. add_test(function test_sync_prolonged_non_network_error() {
  489. // Test prolonged, non-network errors are reported
  490. let server = sync_httpd_setup();
  491. setUp();
  492. // By calling sync, we ensure we're logged in.
  493. Service.sync();
  494. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  495. do_check_true(Service.isLoggedIn);
  496. generateCredentialsChangedFailure();
  497. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  498. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  499. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  500. clean();
  501. server.stop(run_next_test);
  502. });
  503. setLastSync(PROLONGED_ERROR_DURATION);
  504. Service.sync();
  505. });
  506. add_test(function test_login_prolonged_network_error() {
  507. // Test prolonged, network errors are reported
  508. Service.username = "johndoe";
  509. Service.password = "ilovejane";
  510. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  511. Service.clusterURL = "http://localhost:8080/";
  512. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  513. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  514. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  515. clean();
  516. run_next_test();
  517. });
  518. setLastSync(PROLONGED_ERROR_DURATION);
  519. Service.sync();
  520. });
  521. add_test(function test_sync_prolonged_network_error() {
  522. // Test prolonged, network errors are reported
  523. Services.io.offline = true;
  524. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  525. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  526. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  527. Services.io.offline = false;
  528. clean();
  529. run_next_test();
  530. });
  531. setLastSync(PROLONGED_ERROR_DURATION);
  532. Service.sync();
  533. });
  534. add_test(function test_login_non_network_error() {
  535. // Test non-network errors are reported
  536. let server = sync_httpd_setup();
  537. setUp();
  538. Service.password = "";
  539. Svc.Obs.add("weave:ui:login:error", function onSyncError() {
  540. Svc.Obs.remove("weave:ui:login:error", onSyncError);
  541. do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD);
  542. clean();
  543. server.stop(run_next_test);
  544. });
  545. setLastSync(NON_PROLONGED_ERROR_DURATION);
  546. Service.sync();
  547. });
  548. add_test(function test_sync_non_network_error() {
  549. // Test non-network errors are reported
  550. let server = sync_httpd_setup();
  551. setUp();
  552. // By calling sync, we ensure we're logged in.
  553. Service.sync();
  554. do_check_eq(Status.sync, SYNC_SUCCEEDED);
  555. do_check_true(Service.isLoggedIn);
  556. generateCredentialsChangedFailure();
  557. Svc.Obs.add("weave:ui:sync:error", function onSyncError() {
  558. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  559. do_check_eq(Status.sync, CREDENTIALS_CHANGED);
  560. clean();
  561. server.stop(run_next_test);
  562. });
  563. setLastSync(NON_PROLONGED_ERROR_DURATION);
  564. Service.sync();
  565. });
  566. add_test(function test_login_network_error() {
  567. Service.username = "johndoe";
  568. Service.password = "ilovejane";
  569. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  570. Service.clusterURL = "http://localhost:8080/";
  571. // Test network errors are not reported.
  572. Svc.Obs.add("weave:ui:clear-error", function onClearError() {
  573. Svc.Obs.remove("weave:ui:clear-error", onClearError);
  574. do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR);
  575. Services.io.offline = false;
  576. clean();
  577. run_next_test();
  578. });
  579. setLastSync(NON_PROLONGED_ERROR_DURATION);
  580. Service.sync();
  581. });
  582. add_test(function test_sync_network_error() {
  583. // Test network errors are not reported.
  584. Services.io.offline = true;
  585. Svc.Obs.add("weave:ui:sync:finish", function onUIUpdate() {
  586. Svc.Obs.remove("weave:ui:sync:finish", onUIUpdate);
  587. do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
  588. Services.io.offline = false;
  589. clean();
  590. run_next_test();
  591. });
  592. setLastSync(NON_PROLONGED_ERROR_DURATION);
  593. Service.sync();
  594. });
  595. add_test(function test_sync_server_maintenance_error() {
  596. // Test server maintenance errors are not reported.
  597. let server = sync_httpd_setup();
  598. setUp();
  599. const BACKOFF = 42;
  600. let engine = Engines.get("catapult");
  601. engine.enabled = true;
  602. engine.exception = {status: 503,
  603. headers: {"retry-after": BACKOFF}};
  604. function onSyncError() {
  605. do_throw("Shouldn't get here!");
  606. }
  607. Svc.Obs.add("weave:ui:sync:error", onSyncError);
  608. do_check_eq(Status.service, STATUS_OK);
  609. Svc.Obs.add("weave:ui:sync:finish", function onSyncFinish() {
  610. Svc.Obs.remove("weave:ui:sync:finish", onSyncFinish);
  611. do_check_eq(Status.service, SYNC_FAILED_PARTIAL);
  612. do_check_eq(Status.sync, SERVER_MAINTENANCE);
  613. Svc.Obs.remove("weave:ui:sync:error", onSyncError);
  614. clean();
  615. server.stop(run_next_test);
  616. });
  617. setLastSync(NON_PROLONGED_ERROR_DURATION);
  618. Service.sync();
  619. });
  620. add_test(function test_info_collections_login_server_maintenance_error() {
  621. // Test info/collections server maintenance errors are not reported.
  622. let server = sync_httpd_setup();
  623. setUp();
  624. Service.username = "broken.info";
  625. Service.clusterURL = "http://localhost:8080/maintenance/";
  626. let backoffInterval;
  627. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  628. Svc.Obs.remove("weave:service:backoff:interval", observe);
  629. backoffInterval = subject;
  630. });
  631. function onUIUpdate() {
  632. do_throw("Shouldn't get here!");
  633. }
  634. Svc.Obs.add("weave:ui:login:error", onUIUpdate);
  635. do_check_false(Status.enforceBackoff);
  636. do_check_eq(Status.service, STATUS_OK);
  637. Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() {
  638. Svc.Obs.remove("weave:ui:clear-error", onLoginFinish);
  639. do_check_true(Status.enforceBackoff);
  640. do_check_eq(backoffInterval, 42);
  641. do_check_eq(Status.service, LOGIN_FAILED);
  642. do_check_eq(Status.login, SERVER_MAINTENANCE);
  643. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  644. clean();
  645. server.stop(run_next_test);
  646. });
  647. setLastSync(NON_PROLONGED_ERROR_DURATION);
  648. Service.sync();
  649. });
  650. add_test(function test_meta_global_login_server_maintenance_error() {
  651. // Test meta/global server maintenance errors are not reported.
  652. let server = sync_httpd_setup();
  653. setUp();
  654. Service.username = "broken.meta";
  655. Service.clusterURL = "http://localhost:8080/maintenance/";
  656. let backoffInterval;
  657. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  658. Svc.Obs.remove("weave:service:backoff:interval", observe);
  659. backoffInterval = subject;
  660. });
  661. function onUIUpdate() {
  662. do_throw("Shouldn't get here!");
  663. }
  664. Svc.Obs.add("weave:ui:login:error", onUIUpdate);
  665. do_check_false(Status.enforceBackoff);
  666. do_check_eq(Status.service, STATUS_OK);
  667. Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() {
  668. Svc.Obs.remove("weave:ui:clear-error", onLoginFinish);
  669. do_check_true(Status.enforceBackoff);
  670. do_check_eq(backoffInterval, 42);
  671. do_check_eq(Status.service, LOGIN_FAILED);
  672. do_check_eq(Status.login, SERVER_MAINTENANCE);
  673. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  674. clean();
  675. server.stop(run_next_test);
  676. });
  677. setLastSync(NON_PROLONGED_ERROR_DURATION);
  678. Service.sync();
  679. });
  680. add_test(function test_crypto_keys_login_server_maintenance_error() {
  681. // Test crypto/keys server maintenance errors are not reported.
  682. let server = sync_httpd_setup();
  683. setUp();
  684. Service.username = "broken.keys";
  685. Service.clusterURL = "http://localhost:8080/maintenance/";
  686. // Force re-download of keys
  687. CollectionKeys.clear();
  688. let backoffInterval;
  689. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  690. Svc.Obs.remove("weave:service:backoff:interval", observe);
  691. backoffInterval = subject;
  692. });
  693. function onUIUpdate() {
  694. do_throw("Shouldn't get here!");
  695. }
  696. Svc.Obs.add("weave:ui:login:error", onUIUpdate);
  697. do_check_false(Status.enforceBackoff);
  698. do_check_eq(Status.service, STATUS_OK);
  699. Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() {
  700. Svc.Obs.remove("weave:ui:clear-error", onLoginFinish);
  701. do_check_true(Status.enforceBackoff);
  702. do_check_eq(backoffInterval, 42);
  703. do_check_eq(Status.service, LOGIN_FAILED);
  704. do_check_eq(Status.login, SERVER_MAINTENANCE);
  705. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  706. clean();
  707. server.stop(run_next_test);
  708. });
  709. setLastSync(NON_PROLONGED_ERROR_DURATION);
  710. Service.sync();
  711. });
  712. add_test(function test_sync_prolonged_server_maintenance_error() {
  713. // Test prolonged server maintenance errors are reported.
  714. let server = sync_httpd_setup();
  715. setUp();
  716. const BACKOFF = 42;
  717. let engine = Engines.get("catapult");
  718. engine.enabled = true;
  719. engine.exception = {status: 503,
  720. headers: {"retry-after": BACKOFF}};
  721. Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() {
  722. Svc.Obs.remove("weave:ui:sync:error", onUIUpdate);
  723. do_check_eq(Status.service, SYNC_FAILED);
  724. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  725. clean();
  726. server.stop(run_next_test);
  727. });
  728. do_check_eq(Status.service, STATUS_OK);
  729. setLastSync(PROLONGED_ERROR_DURATION);
  730. Service.sync();
  731. });
  732. add_test(function test_info_collections_login_prolonged_server_maintenance_error(){
  733. // Test info/collections prolonged server maintenance errors are reported.
  734. let server = sync_httpd_setup();
  735. setUp();
  736. Service.username = "broken.info";
  737. Service.clusterURL = "http://localhost:8080/maintenance/";
  738. let backoffInterval;
  739. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  740. Svc.Obs.remove("weave:service:backoff:interval", observe);
  741. backoffInterval = subject;
  742. });
  743. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  744. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  745. do_check_true(Status.enforceBackoff);
  746. do_check_eq(backoffInterval, 42);
  747. do_check_eq(Status.service, SYNC_FAILED);
  748. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  749. clean();
  750. server.stop(run_next_test);
  751. });
  752. do_check_false(Status.enforceBackoff);
  753. do_check_eq(Status.service, STATUS_OK);
  754. setLastSync(PROLONGED_ERROR_DURATION);
  755. Service.sync();
  756. });
  757. add_test(function test_meta_global_login_prolonged_server_maintenance_error(){
  758. // Test meta/global prolonged server maintenance errors are reported.
  759. let server = sync_httpd_setup();
  760. setUp();
  761. Service.username = "broken.meta";
  762. Service.clusterURL = "http://localhost:8080/maintenance/";
  763. let backoffInterval;
  764. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  765. Svc.Obs.remove("weave:service:backoff:interval", observe);
  766. backoffInterval = subject;
  767. });
  768. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  769. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  770. do_check_true(Status.enforceBackoff);
  771. do_check_eq(backoffInterval, 42);
  772. do_check_eq(Status.service, SYNC_FAILED);
  773. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  774. clean();
  775. server.stop(run_next_test);
  776. });
  777. do_check_false(Status.enforceBackoff);
  778. do_check_eq(Status.service, STATUS_OK);
  779. setLastSync(PROLONGED_ERROR_DURATION);
  780. Service.sync();
  781. });
  782. add_test(function test_download_crypto_keys_login_prolonged_server_maintenance_error(){
  783. // Test crypto/keys prolonged server maintenance errors are reported.
  784. let server = sync_httpd_setup();
  785. setUp();
  786. Service.username = "broken.keys";
  787. Service.clusterURL = "http://localhost:8080/maintenance/";
  788. // Force re-download of keys
  789. CollectionKeys.clear();
  790. let backoffInterval;
  791. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  792. Svc.Obs.remove("weave:service:backoff:interval", observe);
  793. backoffInterval = subject;
  794. });
  795. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  796. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  797. do_check_true(Status.enforceBackoff);
  798. do_check_eq(backoffInterval, 42);
  799. do_check_eq(Status.service, SYNC_FAILED);
  800. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  801. clean();
  802. server.stop(run_next_test);
  803. });
  804. do_check_false(Status.enforceBackoff);
  805. do_check_eq(Status.service, STATUS_OK);
  806. setLastSync(PROLONGED_ERROR_DURATION);
  807. Service.sync();
  808. });
  809. add_test(function test_upload_crypto_keys_login_prolonged_server_maintenance_error(){
  810. // Test crypto/keys prolonged server maintenance errors are reported.
  811. let server = sync_httpd_setup();
  812. // Start off with an empty account, do not upload a key.
  813. Service.username = "broken.keys";
  814. Service.password = "ilovejane";
  815. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  816. Service.clusterURL = "http://localhost:8080/maintenance/";
  817. let backoffInterval;
  818. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  819. Svc.Obs.remove("weave:service:backoff:interval", observe);
  820. backoffInterval = subject;
  821. });
  822. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  823. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  824. do_check_true(Status.enforceBackoff);
  825. do_check_eq(backoffInterval, 42);
  826. do_check_eq(Status.service, SYNC_FAILED);
  827. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  828. clean();
  829. server.stop(run_next_test);
  830. });
  831. do_check_false(Status.enforceBackoff);
  832. do_check_eq(Status.service, STATUS_OK);
  833. setLastSync(PROLONGED_ERROR_DURATION);
  834. Service.sync();
  835. });
  836. add_test(function test_wipeServer_login_prolonged_server_maintenance_error(){
  837. // Test that we report prolonged server maintenance errors that occur whilst
  838. // wiping the server.
  839. let server = sync_httpd_setup();
  840. // Start off with an empty account, do not upload a key.
  841. Service.username = "broken.wipe";
  842. Service.password = "ilovejane";
  843. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  844. Service.clusterURL = "http://localhost:8080/maintenance/";
  845. let backoffInterval;
  846. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  847. Svc.Obs.remove("weave:service:backoff:interval", observe);
  848. backoffInterval = subject;
  849. });
  850. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  851. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  852. do_check_true(Status.enforceBackoff);
  853. do_check_eq(backoffInterval, 42);
  854. do_check_eq(Status.service, SYNC_FAILED);
  855. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  856. clean();
  857. server.stop(run_next_test);
  858. });
  859. do_check_false(Status.enforceBackoff);
  860. do_check_eq(Status.service, STATUS_OK);
  861. setLastSync(PROLONGED_ERROR_DURATION);
  862. Service.sync();
  863. });
  864. add_test(function test_wipeRemote_prolonged_server_maintenance_error(){
  865. // Test that we report prolonged server maintenance errors that occur whilst
  866. // wiping all remote devices.
  867. let server = sync_httpd_setup();
  868. Service.username = "broken.wipe";
  869. Service.password = "ilovejane";
  870. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  871. Service.clusterURL = "http://localhost:8080/maintenance/";
  872. generateAndUploadKeys();
  873. let engine = Engines.get("catapult");
  874. engine.exception = null;
  875. engine.enabled = true;
  876. let backoffInterval;
  877. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  878. Svc.Obs.remove("weave:service:backoff:interval", observe);
  879. backoffInterval = subject;
  880. });
  881. Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() {
  882. Svc.Obs.remove("weave:ui:sync:error", onUIUpdate);
  883. do_check_true(Status.enforceBackoff);
  884. do_check_eq(backoffInterval, 42);
  885. do_check_eq(Status.service, SYNC_FAILED);
  886. do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE);
  887. do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote");
  888. clean();
  889. server.stop(run_next_test);
  890. });
  891. do_check_false(Status.enforceBackoff);
  892. do_check_eq(Status.service, STATUS_OK);
  893. Svc.Prefs.set("firstSync", "wipeRemote");
  894. setLastSync(PROLONGED_ERROR_DURATION);
  895. Service.sync();
  896. });
  897. add_test(function test_sync_syncAndReportErrors_server_maintenance_error() {
  898. // Test server maintenance errors are reported
  899. // when calling syncAndReportErrors.
  900. let server = sync_httpd_setup();
  901. setUp();
  902. const BACKOFF = 42;
  903. let engine = Engines.get("catapult");
  904. engine.enabled = true;
  905. engine.exception = {status: 503,
  906. headers: {"retry-after": BACKOFF}};
  907. Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() {
  908. Svc.Obs.remove("weave:ui:sync:error", onUIUpdate);
  909. do_check_eq(Status.service, SYNC_FAILED_PARTIAL);
  910. do_check_eq(Status.sync, SERVER_MAINTENANCE);
  911. clean();
  912. server.stop(run_next_test);
  913. });
  914. do_check_eq(Status.service, STATUS_OK);
  915. setLastSync(NON_PROLONGED_ERROR_DURATION);
  916. ErrorHandler.syncAndReportErrors();
  917. });
  918. add_test(function test_info_collections_login_syncAndReportErrors_server_maintenance_error() {
  919. // Test info/collections server maintenance errors are reported
  920. // when calling syncAndReportErrors.
  921. let server = sync_httpd_setup();
  922. setUp();
  923. Service.username = "broken.info";
  924. Service.clusterURL = "http://localhost:8080/maintenance/";
  925. let backoffInterval;
  926. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  927. Svc.Obs.remove("weave:service:backoff:interval", observe);
  928. backoffInterval = subject;
  929. });
  930. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  931. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  932. do_check_true(Status.enforceBackoff);
  933. do_check_eq(backoffInterval, 42);
  934. do_check_eq(Status.service, LOGIN_FAILED);
  935. do_check_eq(Status.login, SERVER_MAINTENANCE);
  936. clean();
  937. server.stop(run_next_test);
  938. });
  939. do_check_false(Status.enforceBackoff);
  940. do_check_eq(Status.service, STATUS_OK);
  941. setLastSync(NON_PROLONGED_ERROR_DURATION);
  942. ErrorHandler.syncAndReportErrors();
  943. });
  944. add_test(function test_meta_global_login_syncAndReportErrors_server_maintenance_error() {
  945. // Test meta/global server maintenance errors are reported
  946. // when calling syncAndReportErrors.
  947. let server = sync_httpd_setup();
  948. setUp();
  949. Service.username = "broken.meta";
  950. Service.clusterURL = "http://localhost:8080/maintenance/";
  951. let backoffInterval;
  952. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  953. Svc.Obs.remove("weave:service:backoff:interval", observe);
  954. backoffInterval = subject;
  955. });
  956. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  957. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  958. do_check_true(Status.enforceBackoff);
  959. do_check_eq(backoffInterval, 42);
  960. do_check_eq(Status.service, LOGIN_FAILED);
  961. do_check_eq(Status.login, SERVER_MAINTENANCE);
  962. clean();
  963. server.stop(run_next_test);
  964. });
  965. do_check_false(Status.enforceBackoff);
  966. do_check_eq(Status.service, STATUS_OK);
  967. setLastSync(NON_PROLONGED_ERROR_DURATION);
  968. ErrorHandler.syncAndReportErrors();
  969. });
  970. add_test(function test_download_crypto_keys_login_syncAndReportErrors_server_maintenance_error() {
  971. // Test crypto/keys server maintenance errors are reported
  972. // when calling syncAndReportErrors.
  973. let server = sync_httpd_setup();
  974. setUp();
  975. Service.username = "broken.keys";
  976. Service.clusterURL = "http://localhost:8080/maintenance/";
  977. // Force re-download of keys
  978. CollectionKeys.clear();
  979. let backoffInterval;
  980. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  981. Svc.Obs.remove("weave:service:backoff:interval", observe);
  982. backoffInterval = subject;
  983. });
  984. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  985. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  986. do_check_true(Status.enforceBackoff);
  987. do_check_eq(backoffInterval, 42);
  988. do_check_eq(Status.service, LOGIN_FAILED);
  989. do_check_eq(Status.login, SERVER_MAINTENANCE);
  990. clean();
  991. server.stop(run_next_test);
  992. });
  993. do_check_false(Status.enforceBackoff);
  994. do_check_eq(Status.service, STATUS_OK);
  995. setLastSync(NON_PROLONGED_ERROR_DURATION);
  996. ErrorHandler.syncAndReportErrors();
  997. });
  998. add_test(function test_upload_crypto_keys_login_syncAndReportErrors_server_maintenance_error() {
  999. // Test crypto/keys server maintenance errors are reported
  1000. // when calling syncAndReportErrors.
  1001. let server = sync_httpd_setup();
  1002. // Start off with an empty account, do not upload a key.
  1003. Service.username = "broken.keys";
  1004. Service.password = "ilovejane";
  1005. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  1006. Service.clusterURL = "http://localhost:8080/maintenance/";
  1007. let backoffInterval;
  1008. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1009. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1010. backoffInterval = subject;
  1011. });
  1012. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1013. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1014. do_check_true(Status.enforceBackoff);
  1015. do_check_eq(backoffInterval, 42);
  1016. do_check_eq(Status.service, LOGIN_FAILED);
  1017. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1018. clean();
  1019. server.stop(run_next_test);
  1020. });
  1021. do_check_false(Status.enforceBackoff);
  1022. do_check_eq(Status.service, STATUS_OK);
  1023. setLastSync(NON_PROLONGED_ERROR_DURATION);
  1024. ErrorHandler.syncAndReportErrors();
  1025. });
  1026. add_test(function test_wipeServer_login_syncAndReportErrors_server_maintenance_error() {
  1027. // Test crypto/keys server maintenance errors are reported
  1028. // when calling syncAndReportErrors.
  1029. let server = sync_httpd_setup();
  1030. // Start off with an empty account, do not upload a key.
  1031. Service.username = "broken.wipe";
  1032. Service.password = "ilovejane";
  1033. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  1034. Service.clusterURL = "http://localhost:8080/maintenance/";
  1035. let backoffInterval;
  1036. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1037. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1038. backoffInterval = subject;
  1039. });
  1040. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1041. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1042. do_check_true(Status.enforceBackoff);
  1043. do_check_eq(backoffInterval, 42);
  1044. do_check_eq(Status.service, LOGIN_FAILED);
  1045. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1046. clean();
  1047. server.stop(run_next_test);
  1048. });
  1049. do_check_false(Status.enforceBackoff);
  1050. do_check_eq(Status.service, STATUS_OK);
  1051. setLastSync(NON_PROLONGED_ERROR_DURATION);
  1052. ErrorHandler.syncAndReportErrors();
  1053. });
  1054. add_test(function test_wipeRemote_syncAndReportErrors_server_maintenance_error(){
  1055. // Test that we report prolonged server maintenance errors that occur whilst
  1056. // wiping all remote devices.
  1057. let server = sync_httpd_setup();
  1058. Service.username = "broken.wipe";
  1059. Service.password = "ilovejane";
  1060. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  1061. Service.clusterURL = "http://localhost:8080/maintenance/";
  1062. generateAndUploadKeys();
  1063. let engine = Engines.get("catapult");
  1064. engine.exception = null;
  1065. engine.enabled = true;
  1066. let backoffInterval;
  1067. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1068. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1069. backoffInterval = subject;
  1070. });
  1071. Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() {
  1072. Svc.Obs.remove("weave:ui:sync:error", onUIUpdate);
  1073. do_check_true(Status.enforceBackoff);
  1074. do_check_eq(backoffInterval, 42);
  1075. do_check_eq(Status.service, SYNC_FAILED);
  1076. do_check_eq(Status.sync, SERVER_MAINTENANCE);
  1077. do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote");
  1078. clean();
  1079. server.stop(run_next_test);
  1080. });
  1081. do_check_false(Status.enforceBackoff);
  1082. do_check_eq(Status.service, STATUS_OK);
  1083. Svc.Prefs.set("firstSync", "wipeRemote");
  1084. setLastSync(NON_PROLONGED_ERROR_DURATION);
  1085. ErrorHandler.syncAndReportErrors();
  1086. });
  1087. add_test(function test_sync_syncAndReportErrors_prolonged_server_maintenance_error() {
  1088. // Test prolonged server maintenance errors are
  1089. // reported when calling syncAndReportErrors.
  1090. let server = sync_httpd_setup();
  1091. setUp();
  1092. const BACKOFF = 42;
  1093. let engine = Engines.get("catapult");
  1094. engine.enabled = true;
  1095. engine.exception = {status: 503,
  1096. headers: {"retry-after": BACKOFF}};
  1097. Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() {
  1098. Svc.Obs.remove("weave:ui:sync:error", onUIUpdate);
  1099. do_check_eq(Status.service, SYNC_FAILED_PARTIAL);
  1100. do_check_eq(Status.sync, SERVER_MAINTENANCE);
  1101. clean();
  1102. server.stop(run_next_test);
  1103. });
  1104. do_check_eq(Status.service, STATUS_OK);
  1105. setLastSync(PROLONGED_ERROR_DURATION);
  1106. ErrorHandler.syncAndReportErrors();
  1107. });
  1108. add_test(function test_info_collections_login_syncAndReportErrors_prolonged_server_maintenance_error() {
  1109. // Test info/collections server maintenance errors are reported
  1110. // when calling syncAndReportErrors.
  1111. let server = sync_httpd_setup();
  1112. setUp();
  1113. Service.username = "broken.info";
  1114. Service.clusterURL = "http://localhost:8080/maintenance/";
  1115. let backoffInterval;
  1116. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1117. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1118. backoffInterval = subject;
  1119. });
  1120. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1121. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1122. do_check_true(Status.enforceBackoff);
  1123. do_check_eq(backoffInterval, 42);
  1124. do_check_eq(Status.service, LOGIN_FAILED);
  1125. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1126. clean();
  1127. server.stop(run_next_test);
  1128. });
  1129. do_check_false(Status.enforceBackoff);
  1130. do_check_eq(Status.service, STATUS_OK);
  1131. setLastSync(PROLONGED_ERROR_DURATION);
  1132. ErrorHandler.syncAndReportErrors();
  1133. });
  1134. add_test(function test_meta_global_login_syncAndReportErrors_prolonged_server_maintenance_error() {
  1135. // Test meta/global server maintenance errors are reported
  1136. // when calling syncAndReportErrors.
  1137. let server = sync_httpd_setup();
  1138. setUp();
  1139. Service.username = "broken.meta";
  1140. Service.clusterURL = "http://localhost:8080/maintenance/";
  1141. let backoffInterval;
  1142. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1143. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1144. backoffInterval = subject;
  1145. });
  1146. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1147. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1148. do_check_true(Status.enforceBackoff);
  1149. do_check_eq(backoffInterval, 42);
  1150. do_check_eq(Status.service, LOGIN_FAILED);
  1151. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1152. clean();
  1153. server.stop(run_next_test);
  1154. });
  1155. do_check_false(Status.enforceBackoff);
  1156. do_check_eq(Status.service, STATUS_OK);
  1157. setLastSync(PROLONGED_ERROR_DURATION);
  1158. ErrorHandler.syncAndReportErrors();
  1159. });
  1160. add_test(function test_download_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() {
  1161. // Test crypto/keys server maintenance errors are reported
  1162. // when calling syncAndReportErrors.
  1163. let server = sync_httpd_setup();
  1164. setUp();
  1165. Service.username = "broken.keys";
  1166. Service.clusterURL = "http://localhost:8080/maintenance/";
  1167. // Force re-download of keys
  1168. CollectionKeys.clear();
  1169. let backoffInterval;
  1170. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1171. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1172. backoffInterval = subject;
  1173. });
  1174. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1175. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1176. do_check_true(Status.enforceBackoff);
  1177. do_check_eq(backoffInterval, 42);
  1178. do_check_eq(Status.service, LOGIN_FAILED);
  1179. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1180. clean();
  1181. server.stop(run_next_test);
  1182. });
  1183. do_check_false(Status.enforceBackoff);
  1184. do_check_eq(Status.service, STATUS_OK);
  1185. setLastSync(PROLONGED_ERROR_DURATION);
  1186. ErrorHandler.syncAndReportErrors();
  1187. });
  1188. add_test(function test_upload_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() {
  1189. // Test crypto/keys server maintenance errors are reported
  1190. // when calling syncAndReportErrors.
  1191. let server = sync_httpd_setup();
  1192. // Start off with an empty account, do not upload a key.
  1193. Service.username = "broken.keys";
  1194. Service.password = "ilovejane";
  1195. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  1196. Service.clusterURL = "http://localhost:8080/maintenance/";
  1197. let backoffInterval;
  1198. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1199. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1200. backoffInterval = subject;
  1201. });
  1202. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1203. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1204. do_check_true(Status.enforceBackoff);
  1205. do_check_eq(backoffInterval, 42);
  1206. do_check_eq(Status.service, LOGIN_FAILED);
  1207. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1208. clean();
  1209. server.stop(run_next_test);
  1210. });
  1211. do_check_false(Status.enforceBackoff);
  1212. do_check_eq(Status.service, STATUS_OK);
  1213. setLastSync(PROLONGED_ERROR_DURATION);
  1214. ErrorHandler.syncAndReportErrors();
  1215. });
  1216. add_test(function test_wipeServer_login_syncAndReportErrors_prolonged_server_maintenance_error() {
  1217. // Test crypto/keys server maintenance errors are reported
  1218. // when calling syncAndReportErrors.
  1219. let server = sync_httpd_setup();
  1220. // Start off with an empty account, do not upload a key.
  1221. Service.username = "broken.wipe";
  1222. Service.password = "ilovejane";
  1223. Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
  1224. Service.clusterURL = "http://localhost:8080/maintenance/";
  1225. let backoffInterval;
  1226. Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
  1227. Svc.Obs.remove("weave:service:backoff:interval", observe);
  1228. backoffInterval = subject;
  1229. });
  1230. Svc.Obs.add("weave:ui:login:error", function onUIUpdate() {
  1231. Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
  1232. do_check_true(Status.enforceBackoff);
  1233. do_check_eq(backoffInterval, 42);
  1234. do_check_eq(Status.service, LOGIN_FAILED);
  1235. do_check_eq(Status.login, SERVER_MAINTENANCE);
  1236. clean();
  1237. server.stop(run_next_test);
  1238. });
  1239. do_check_false(Status.enforceBackoff);
  1240. do_check_eq(Status.service, STATUS_OK);
  1241. setLastSync(PROLONGED_ERROR_DURATION);
  1242. ErrorHandler.syncAndReportErrors();
  1243. });
  1244. add_test(function test_sync_engine_generic_fail() {
  1245. let server = sync_httpd_setup();
  1246. let engine = Engines.get("catapult");
  1247. engine.enabled = true;
  1248. engine.sync = function sync() {
  1249. Svc.Obs.notify("…