1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/services/sync/tests/unit/test_errorhandler.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1881 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +Cu.import("resource://services-sync/engines/clients.js"); 1.8 +Cu.import("resource://services-sync/constants.js"); 1.9 +Cu.import("resource://services-sync/engines.js"); 1.10 +Cu.import("resource://services-sync/keys.js"); 1.11 +Cu.import("resource://services-sync/policies.js"); 1.12 +Cu.import("resource://services-sync/service.js"); 1.13 +Cu.import("resource://services-sync/status.js"); 1.14 +Cu.import("resource://services-sync/util.js"); 1.15 +Cu.import("resource://testing-common/services/sync/utils.js"); 1.16 +Cu.import("resource://gre/modules/FileUtils.jsm"); 1.17 + 1.18 +const FAKE_SERVER_URL = "http://dummy:9000/"; 1.19 +const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true); 1.20 +const LOG_PREFIX_SUCCESS = "success-"; 1.21 +const LOG_PREFIX_ERROR = "error-"; 1.22 + 1.23 +const PROLONGED_ERROR_DURATION = 1.24 + (Svc.Prefs.get('errorhandler.networkFailureReportTimeout') * 2) * 1000; 1.25 + 1.26 +const NON_PROLONGED_ERROR_DURATION = 1.27 + (Svc.Prefs.get('errorhandler.networkFailureReportTimeout') / 2) * 1000; 1.28 + 1.29 +Service.engineManager.clear(); 1.30 + 1.31 +function setLastSync(lastSyncValue) { 1.32 + Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString()); 1.33 +} 1.34 + 1.35 +function CatapultEngine() { 1.36 + SyncEngine.call(this, "Catapult", Service); 1.37 +} 1.38 +CatapultEngine.prototype = { 1.39 + __proto__: SyncEngine.prototype, 1.40 + exception: null, // tests fill this in 1.41 + _sync: function _sync() { 1.42 + if (this.exception) { 1.43 + throw this.exception; 1.44 + } 1.45 + } 1.46 +}; 1.47 + 1.48 +let engineManager = Service.engineManager; 1.49 +engineManager.register(CatapultEngine); 1.50 + 1.51 +// This relies on Service/ErrorHandler being a singleton. Fixing this will take 1.52 +// a lot of work. 1.53 +let errorHandler = Service.errorHandler; 1.54 + 1.55 +function run_test() { 1.56 + initTestLogging("Trace"); 1.57 + 1.58 + Log.repository.getLogger("Sync.Service").level = Log.Level.Trace; 1.59 + Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace; 1.60 + Log.repository.getLogger("Sync.ErrorHandler").level = Log.Level.Trace; 1.61 + 1.62 + ensureLegacyIdentityManager(); 1.63 + 1.64 + run_next_test(); 1.65 +} 1.66 + 1.67 +function generateCredentialsChangedFailure() { 1.68 + // Make sync fail due to changed credentials. We simply re-encrypt 1.69 + // the keys with a different Sync Key, without changing the local one. 1.70 + let newSyncKeyBundle = new SyncKeyBundle("johndoe", "23456234562345623456234562"); 1.71 + let keys = Service.collectionKeys.asWBO(); 1.72 + keys.encrypt(newSyncKeyBundle); 1.73 + keys.upload(Service.resource(Service.cryptoKeysURL)); 1.74 +} 1.75 + 1.76 +function service_unavailable(request, response) { 1.77 + let body = "Service Unavailable"; 1.78 + response.setStatusLine(request.httpVersion, 503, "Service Unavailable"); 1.79 + response.setHeader("Retry-After", "42"); 1.80 + response.bodyOutputStream.write(body, body.length); 1.81 +} 1.82 + 1.83 +function sync_httpd_setup() { 1.84 + let global = new ServerWBO("global", { 1.85 + syncID: Service.syncID, 1.86 + storageVersion: STORAGE_VERSION, 1.87 + engines: {clients: {version: Service.clientsEngine.version, 1.88 + syncID: Service.clientsEngine.syncID}, 1.89 + catapult: {version: engineManager.get("catapult").version, 1.90 + syncID: engineManager.get("catapult").syncID}} 1.91 + }); 1.92 + let clientsColl = new ServerCollection({}, true); 1.93 + 1.94 + // Tracking info/collections. 1.95 + let collectionsHelper = track_collections_helper(); 1.96 + let upd = collectionsHelper.with_updated_collection; 1.97 + 1.98 + let handler_401 = httpd_handler(401, "Unauthorized"); 1.99 + return httpd_setup({ 1.100 + // Normal server behaviour. 1.101 + "/1.1/johndoe/storage/meta/global": upd("meta", global.handler()), 1.102 + "/1.1/johndoe/info/collections": collectionsHelper.handler, 1.103 + "/1.1/johndoe/storage/crypto/keys": 1.104 + upd("crypto", (new ServerWBO("keys")).handler()), 1.105 + "/1.1/johndoe/storage/clients": upd("clients", clientsColl.handler()), 1.106 + 1.107 + // Credentials are wrong or node reallocated. 1.108 + "/1.1/janedoe/storage/meta/global": handler_401, 1.109 + "/1.1/janedoe/info/collections": handler_401, 1.110 + 1.111 + // Maintenance or overloaded (503 + Retry-After) at info/collections. 1.112 + "/maintenance/1.1/broken.info/info/collections": service_unavailable, 1.113 + 1.114 + // Maintenance or overloaded (503 + Retry-After) at meta/global. 1.115 + "/maintenance/1.1/broken.meta/storage/meta/global": service_unavailable, 1.116 + "/maintenance/1.1/broken.meta/info/collections": collectionsHelper.handler, 1.117 + 1.118 + // Maintenance or overloaded (503 + Retry-After) at crypto/keys. 1.119 + "/maintenance/1.1/broken.keys/storage/meta/global": upd("meta", global.handler()), 1.120 + "/maintenance/1.1/broken.keys/info/collections": collectionsHelper.handler, 1.121 + "/maintenance/1.1/broken.keys/storage/crypto/keys": service_unavailable, 1.122 + 1.123 + // Maintenance or overloaded (503 + Retry-After) at wiping collection. 1.124 + "/maintenance/1.1/broken.wipe/info/collections": collectionsHelper.handler, 1.125 + "/maintenance/1.1/broken.wipe/storage/meta/global": upd("meta", global.handler()), 1.126 + "/maintenance/1.1/broken.wipe/storage/crypto/keys": 1.127 + upd("crypto", (new ServerWBO("keys")).handler()), 1.128 + "/maintenance/1.1/broken.wipe/storage": service_unavailable, 1.129 + "/maintenance/1.1/broken.wipe/storage/clients": upd("clients", clientsColl.handler()), 1.130 + "/maintenance/1.1/broken.wipe/storage/catapult": service_unavailable 1.131 + }); 1.132 +} 1.133 + 1.134 +function setUp(server) { 1.135 + return configureIdentity({username: "johndoe"}).then( 1.136 + () => { 1.137 + Service.serverURL = server.baseURI + "/"; 1.138 + Service.clusterURL = server.baseURI + "/"; 1.139 + } 1.140 + ).then( 1.141 + () => generateAndUploadKeys() 1.142 + ); 1.143 +} 1.144 + 1.145 +function generateAndUploadKeys() { 1.146 + generateNewKeys(Service.collectionKeys); 1.147 + let serverKeys = Service.collectionKeys.asWBO("crypto", "keys"); 1.148 + serverKeys.encrypt(Service.identity.syncKeyBundle); 1.149 + return serverKeys.upload(Service.resource(Service.cryptoKeysURL)).success; 1.150 +} 1.151 + 1.152 +function clean() { 1.153 + Service.startOver(); 1.154 + Status.resetSync(); 1.155 + Status.resetBackoff(); 1.156 + errorHandler.didReportProlongedError = false; 1.157 +} 1.158 + 1.159 +add_identity_test(this, function test_401_logout() { 1.160 + let server = sync_httpd_setup(); 1.161 + yield setUp(server); 1.162 + 1.163 + // By calling sync, we ensure we're logged in. 1.164 + Service.sync(); 1.165 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.166 + do_check_true(Service.isLoggedIn); 1.167 + 1.168 + let deferred = Promise.defer(); 1.169 + Svc.Obs.add("weave:service:sync:error", onSyncError); 1.170 + function onSyncError() { 1.171 + _("Got weave:service:sync:error in first sync."); 1.172 + Svc.Obs.remove("weave:service:sync:error", onSyncError); 1.173 + 1.174 + // Wait for the automatic next sync. 1.175 + function onLoginError() { 1.176 + _("Got weave:service:login:error in second sync."); 1.177 + Svc.Obs.remove("weave:service:login:error", onLoginError); 1.178 + 1.179 + do_check_eq(Status.login, LOGIN_FAILED_LOGIN_REJECTED); 1.180 + do_check_false(Service.isLoggedIn); 1.181 + 1.182 + // Clean up. 1.183 + Utils.nextTick(function () { 1.184 + Service.startOver(); 1.185 + server.stop(deferred.resolve); 1.186 + }); 1.187 + } 1.188 + Svc.Obs.add("weave:service:login:error", onLoginError); 1.189 + } 1.190 + 1.191 + // Make sync fail due to login rejected. 1.192 + yield configureIdentity({username: "janedoe"}); 1.193 + Service._updateCachedURLs(); 1.194 + 1.195 + _("Starting first sync."); 1.196 + Service.sync(); 1.197 + _("First sync done."); 1.198 + yield deferred.promise; 1.199 +}); 1.200 + 1.201 +add_identity_test(this, function test_credentials_changed_logout() { 1.202 + let server = sync_httpd_setup(); 1.203 + yield setUp(server); 1.204 + 1.205 + // By calling sync, we ensure we're logged in. 1.206 + Service.sync(); 1.207 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.208 + do_check_true(Service.isLoggedIn); 1.209 + 1.210 + generateCredentialsChangedFailure(); 1.211 + Service.sync(); 1.212 + 1.213 + do_check_eq(Status.sync, CREDENTIALS_CHANGED); 1.214 + do_check_false(Service.isLoggedIn); 1.215 + 1.216 + // Clean up. 1.217 + Service.startOver(); 1.218 + let deferred = Promise.defer(); 1.219 + server.stop(deferred.resolve); 1.220 + yield deferred.promise; 1.221 +}); 1.222 + 1.223 +add_identity_test(this, function test_no_lastSync_pref() { 1.224 + // Test reported error. 1.225 + Status.resetSync(); 1.226 + errorHandler.dontIgnoreErrors = true; 1.227 + Status.sync = CREDENTIALS_CHANGED; 1.228 + do_check_true(errorHandler.shouldReportError()); 1.229 + 1.230 + // Test unreported error. 1.231 + Status.resetSync(); 1.232 + errorHandler.dontIgnoreErrors = true; 1.233 + Status.login = LOGIN_FAILED_NETWORK_ERROR; 1.234 + do_check_true(errorHandler.shouldReportError()); 1.235 + 1.236 +}); 1.237 + 1.238 +add_identity_test(this, function test_shouldReportError() { 1.239 + Status.login = MASTER_PASSWORD_LOCKED; 1.240 + do_check_false(errorHandler.shouldReportError()); 1.241 + 1.242 + // Give ourselves a clusterURL so that the temporary 401 no-error situation 1.243 + // doesn't come into play. 1.244 + Service.serverURL = FAKE_SERVER_URL; 1.245 + Service.clusterURL = FAKE_SERVER_URL; 1.246 + 1.247 + // Test dontIgnoreErrors, non-network, non-prolonged, login error reported 1.248 + Status.resetSync(); 1.249 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.250 + errorHandler.dontIgnoreErrors = true; 1.251 + Status.login = LOGIN_FAILED_NO_PASSWORD; 1.252 + do_check_true(errorHandler.shouldReportError()); 1.253 + 1.254 + // Test dontIgnoreErrors, non-network, non-prolonged, sync error reported 1.255 + Status.resetSync(); 1.256 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.257 + errorHandler.dontIgnoreErrors = true; 1.258 + Status.sync = CREDENTIALS_CHANGED; 1.259 + do_check_true(errorHandler.shouldReportError()); 1.260 + 1.261 + // Test dontIgnoreErrors, non-network, prolonged, login error reported 1.262 + Status.resetSync(); 1.263 + setLastSync(PROLONGED_ERROR_DURATION); 1.264 + errorHandler.dontIgnoreErrors = true; 1.265 + Status.login = LOGIN_FAILED_NO_PASSWORD; 1.266 + do_check_true(errorHandler.shouldReportError()); 1.267 + 1.268 + // Test dontIgnoreErrors, non-network, prolonged, sync error reported 1.269 + Status.resetSync(); 1.270 + setLastSync(PROLONGED_ERROR_DURATION); 1.271 + errorHandler.dontIgnoreErrors = true; 1.272 + Status.sync = CREDENTIALS_CHANGED; 1.273 + do_check_true(errorHandler.shouldReportError()); 1.274 + 1.275 + // Test dontIgnoreErrors, network, non-prolonged, login error reported 1.276 + Status.resetSync(); 1.277 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.278 + errorHandler.dontIgnoreErrors = true; 1.279 + Status.login = LOGIN_FAILED_NETWORK_ERROR; 1.280 + do_check_true(errorHandler.shouldReportError()); 1.281 + 1.282 + // Test dontIgnoreErrors, network, non-prolonged, sync error reported 1.283 + Status.resetSync(); 1.284 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.285 + errorHandler.dontIgnoreErrors = true; 1.286 + Status.sync = LOGIN_FAILED_NETWORK_ERROR; 1.287 + do_check_true(errorHandler.shouldReportError()); 1.288 + 1.289 + // Test dontIgnoreErrors, network, prolonged, login error reported 1.290 + Status.resetSync(); 1.291 + setLastSync(PROLONGED_ERROR_DURATION); 1.292 + errorHandler.dontIgnoreErrors = true; 1.293 + Status.login = LOGIN_FAILED_NETWORK_ERROR; 1.294 + do_check_true(errorHandler.shouldReportError()); 1.295 + 1.296 + // Test dontIgnoreErrors, network, prolonged, sync error reported 1.297 + Status.resetSync(); 1.298 + setLastSync(PROLONGED_ERROR_DURATION); 1.299 + errorHandler.dontIgnoreErrors = true; 1.300 + Status.sync = LOGIN_FAILED_NETWORK_ERROR; 1.301 + do_check_true(errorHandler.shouldReportError()); 1.302 + 1.303 + // Test non-network, prolonged, login error reported 1.304 + do_check_false(errorHandler.didReportProlongedError); 1.305 + Status.resetSync(); 1.306 + setLastSync(PROLONGED_ERROR_DURATION); 1.307 + errorHandler.dontIgnoreErrors = false; 1.308 + Status.login = LOGIN_FAILED_NO_PASSWORD; 1.309 + do_check_true(errorHandler.shouldReportError()); 1.310 + do_check_true(errorHandler.didReportProlongedError); 1.311 + 1.312 + // Second time with prolonged error and without resetting 1.313 + // didReportProlongedError, sync error should not be reported. 1.314 + Status.resetSync(); 1.315 + setLastSync(PROLONGED_ERROR_DURATION); 1.316 + errorHandler.dontIgnoreErrors = false; 1.317 + Status.login = LOGIN_FAILED_NO_PASSWORD; 1.318 + do_check_false(errorHandler.shouldReportError()); 1.319 + do_check_true(errorHandler.didReportProlongedError); 1.320 + 1.321 + // Test non-network, prolonged, sync error reported 1.322 + Status.resetSync(); 1.323 + setLastSync(PROLONGED_ERROR_DURATION); 1.324 + errorHandler.dontIgnoreErrors = false; 1.325 + errorHandler.didReportProlongedError = false; 1.326 + Status.sync = CREDENTIALS_CHANGED; 1.327 + do_check_true(errorHandler.shouldReportError()); 1.328 + do_check_true(errorHandler.didReportProlongedError); 1.329 + errorHandler.didReportProlongedError = false; 1.330 + 1.331 + // Test network, prolonged, login error reported 1.332 + Status.resetSync(); 1.333 + setLastSync(PROLONGED_ERROR_DURATION); 1.334 + errorHandler.dontIgnoreErrors = false; 1.335 + Status.login = LOGIN_FAILED_NETWORK_ERROR; 1.336 + do_check_true(errorHandler.shouldReportError()); 1.337 + do_check_true(errorHandler.didReportProlongedError); 1.338 + errorHandler.didReportProlongedError = false; 1.339 + 1.340 + // Test network, prolonged, sync error reported 1.341 + Status.resetSync(); 1.342 + setLastSync(PROLONGED_ERROR_DURATION); 1.343 + errorHandler.dontIgnoreErrors = false; 1.344 + Status.sync = LOGIN_FAILED_NETWORK_ERROR; 1.345 + do_check_true(errorHandler.shouldReportError()); 1.346 + do_check_true(errorHandler.didReportProlongedError); 1.347 + errorHandler.didReportProlongedError = false; 1.348 + 1.349 + // Test non-network, non-prolonged, login error reported 1.350 + Status.resetSync(); 1.351 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.352 + errorHandler.dontIgnoreErrors = false; 1.353 + Status.login = LOGIN_FAILED_NO_PASSWORD; 1.354 + do_check_true(errorHandler.shouldReportError()); 1.355 + do_check_false(errorHandler.didReportProlongedError); 1.356 + 1.357 + // Test non-network, non-prolonged, sync error reported 1.358 + Status.resetSync(); 1.359 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.360 + errorHandler.dontIgnoreErrors = false; 1.361 + Status.sync = CREDENTIALS_CHANGED; 1.362 + do_check_true(errorHandler.shouldReportError()); 1.363 + do_check_false(errorHandler.didReportProlongedError); 1.364 + 1.365 + // Test network, non-prolonged, login error reported 1.366 + Status.resetSync(); 1.367 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.368 + errorHandler.dontIgnoreErrors = false; 1.369 + Status.login = LOGIN_FAILED_NETWORK_ERROR; 1.370 + do_check_false(errorHandler.shouldReportError()); 1.371 + do_check_false(errorHandler.didReportProlongedError); 1.372 + 1.373 + // Test network, non-prolonged, sync error reported 1.374 + Status.resetSync(); 1.375 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.376 + errorHandler.dontIgnoreErrors = false; 1.377 + Status.sync = LOGIN_FAILED_NETWORK_ERROR; 1.378 + do_check_false(errorHandler.shouldReportError()); 1.379 + do_check_false(errorHandler.didReportProlongedError); 1.380 + 1.381 + // Test server maintenance, sync errors are not reported 1.382 + Status.resetSync(); 1.383 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.384 + errorHandler.dontIgnoreErrors = false; 1.385 + Status.sync = SERVER_MAINTENANCE; 1.386 + do_check_false(errorHandler.shouldReportError()); 1.387 + do_check_false(errorHandler.didReportProlongedError); 1.388 + 1.389 + // Test server maintenance, login errors are not reported 1.390 + Status.resetSync(); 1.391 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.392 + errorHandler.dontIgnoreErrors = false; 1.393 + Status.login = SERVER_MAINTENANCE; 1.394 + do_check_false(errorHandler.shouldReportError()); 1.395 + do_check_false(errorHandler.didReportProlongedError); 1.396 + 1.397 + // Test prolonged, server maintenance, sync errors are reported 1.398 + Status.resetSync(); 1.399 + setLastSync(PROLONGED_ERROR_DURATION); 1.400 + errorHandler.dontIgnoreErrors = false; 1.401 + Status.sync = SERVER_MAINTENANCE; 1.402 + do_check_true(errorHandler.shouldReportError()); 1.403 + do_check_true(errorHandler.didReportProlongedError); 1.404 + errorHandler.didReportProlongedError = false; 1.405 + 1.406 + // Test prolonged, server maintenance, login errors are reported 1.407 + Status.resetSync(); 1.408 + setLastSync(PROLONGED_ERROR_DURATION); 1.409 + errorHandler.dontIgnoreErrors = false; 1.410 + Status.login = SERVER_MAINTENANCE; 1.411 + do_check_true(errorHandler.shouldReportError()); 1.412 + do_check_true(errorHandler.didReportProlongedError); 1.413 + errorHandler.didReportProlongedError = false; 1.414 + 1.415 + // Test dontIgnoreErrors, server maintenance, sync errors are reported 1.416 + Status.resetSync(); 1.417 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.418 + errorHandler.dontIgnoreErrors = true; 1.419 + Status.sync = SERVER_MAINTENANCE; 1.420 + do_check_true(errorHandler.shouldReportError()); 1.421 + // dontIgnoreErrors means we don't set didReportProlongedError 1.422 + do_check_false(errorHandler.didReportProlongedError); 1.423 + 1.424 + // Test dontIgnoreErrors, server maintenance, login errors are reported 1.425 + Status.resetSync(); 1.426 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.427 + errorHandler.dontIgnoreErrors = true; 1.428 + Status.login = SERVER_MAINTENANCE; 1.429 + do_check_true(errorHandler.shouldReportError()); 1.430 + do_check_false(errorHandler.didReportProlongedError); 1.431 + 1.432 + // Test dontIgnoreErrors, prolonged, server maintenance, 1.433 + // sync errors are reported 1.434 + Status.resetSync(); 1.435 + setLastSync(PROLONGED_ERROR_DURATION); 1.436 + errorHandler.dontIgnoreErrors = true; 1.437 + Status.sync = SERVER_MAINTENANCE; 1.438 + do_check_true(errorHandler.shouldReportError()); 1.439 + do_check_false(errorHandler.didReportProlongedError); 1.440 + 1.441 + // Test dontIgnoreErrors, prolonged, server maintenance, 1.442 + // login errors are reported 1.443 + Status.resetSync(); 1.444 + setLastSync(PROLONGED_ERROR_DURATION); 1.445 + errorHandler.dontIgnoreErrors = true; 1.446 + Status.login = SERVER_MAINTENANCE; 1.447 + do_check_true(errorHandler.shouldReportError()); 1.448 + do_check_false(errorHandler.didReportProlongedError); 1.449 +}); 1.450 + 1.451 +add_identity_test(this, function test_shouldReportError_master_password() { 1.452 + _("Test error ignored due to locked master password"); 1.453 + let server = sync_httpd_setup(); 1.454 + yield setUp(server); 1.455 + 1.456 + // Monkey patch Service.verifyLogin to imitate 1.457 + // master password being locked. 1.458 + Service._verifyLogin = Service.verifyLogin; 1.459 + Service.verifyLogin = function () { 1.460 + Status.login = MASTER_PASSWORD_LOCKED; 1.461 + return false; 1.462 + }; 1.463 + 1.464 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.465 + Service.sync(); 1.466 + do_check_false(errorHandler.shouldReportError()); 1.467 + 1.468 + // Clean up. 1.469 + Service.verifyLogin = Service._verifyLogin; 1.470 + clean(); 1.471 + let deferred = Promise.defer(); 1.472 + server.stop(deferred.resolve); 1.473 + yield deferred.promise; 1.474 +}); 1.475 + 1.476 +// XXX - how to arrange for 'Service.identity.basicPassword = null;' in 1.477 +// an fxaccounts environment? 1.478 +add_task(function test_login_syncAndReportErrors_non_network_error() { 1.479 + // Test non-network errors are reported 1.480 + // when calling syncAndReportErrors 1.481 + let server = sync_httpd_setup(); 1.482 + yield setUp(server); 1.483 + Service.identity.basicPassword = null; 1.484 + 1.485 + let deferred = Promise.defer(); 1.486 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.487 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.488 + do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD); 1.489 + 1.490 + clean(); 1.491 + server.stop(deferred.resolve); 1.492 + }); 1.493 + 1.494 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.495 + errorHandler.syncAndReportErrors(); 1.496 + yield deferred.promise; 1.497 +}); 1.498 + 1.499 +add_identity_test(this, function test_sync_syncAndReportErrors_non_network_error() { 1.500 + // Test non-network errors are reported 1.501 + // when calling syncAndReportErrors 1.502 + let server = sync_httpd_setup(); 1.503 + yield setUp(server); 1.504 + 1.505 + // By calling sync, we ensure we're logged in. 1.506 + Service.sync(); 1.507 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.508 + do_check_true(Service.isLoggedIn); 1.509 + 1.510 + generateCredentialsChangedFailure(); 1.511 + 1.512 + let deferred = Promise.defer(); 1.513 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.514 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.515 + do_check_eq(Status.sync, CREDENTIALS_CHANGED); 1.516 + 1.517 + clean(); 1.518 + server.stop(deferred.resolve); 1.519 + }); 1.520 + 1.521 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.522 + errorHandler.syncAndReportErrors(); 1.523 + yield deferred.promise; 1.524 +}); 1.525 + 1.526 +// XXX - how to arrange for 'Service.identity.basicPassword = null;' in 1.527 +// an fxaccounts environment? 1.528 +add_task(function test_login_syncAndReportErrors_prolonged_non_network_error() { 1.529 + // Test prolonged, non-network errors are 1.530 + // reported when calling syncAndReportErrors. 1.531 + let server = sync_httpd_setup(); 1.532 + yield setUp(server); 1.533 + Service.identity.basicPassword = null; 1.534 + 1.535 + let deferred = Promise.defer(); 1.536 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.537 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.538 + do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD); 1.539 + 1.540 + clean(); 1.541 + server.stop(deferred.resolve); 1.542 + }); 1.543 + 1.544 + setLastSync(PROLONGED_ERROR_DURATION); 1.545 + errorHandler.syncAndReportErrors(); 1.546 + yield deferred.promise; 1.547 +}); 1.548 + 1.549 +add_identity_test(this, function test_sync_syncAndReportErrors_prolonged_non_network_error() { 1.550 + // Test prolonged, non-network errors are 1.551 + // reported when calling syncAndReportErrors. 1.552 + let server = sync_httpd_setup(); 1.553 + yield setUp(server); 1.554 + 1.555 + // By calling sync, we ensure we're logged in. 1.556 + Service.sync(); 1.557 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.558 + do_check_true(Service.isLoggedIn); 1.559 + 1.560 + generateCredentialsChangedFailure(); 1.561 + 1.562 + let deferred = Promise.defer(); 1.563 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.564 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.565 + do_check_eq(Status.sync, CREDENTIALS_CHANGED); 1.566 + 1.567 + clean(); 1.568 + server.stop(deferred.resolve); 1.569 + }); 1.570 + 1.571 + setLastSync(PROLONGED_ERROR_DURATION); 1.572 + errorHandler.syncAndReportErrors(); 1.573 + yield deferred.promise; 1.574 +}); 1.575 + 1.576 +add_identity_test(this, function test_login_syncAndReportErrors_network_error() { 1.577 + // Test network errors are reported when calling syncAndReportErrors. 1.578 + yield configureIdentity({username: "broken.wipe"}); 1.579 + Service.serverURL = FAKE_SERVER_URL; 1.580 + Service.clusterURL = FAKE_SERVER_URL; 1.581 + 1.582 + let deferred = Promise.defer(); 1.583 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.584 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.585 + do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR); 1.586 + 1.587 + clean(); 1.588 + deferred.resolve(); 1.589 + }); 1.590 + 1.591 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.592 + errorHandler.syncAndReportErrors(); 1.593 + yield deferred.promise; 1.594 +}); 1.595 + 1.596 + 1.597 +add_test(function test_sync_syncAndReportErrors_network_error() { 1.598 + // Test network errors are reported when calling syncAndReportErrors. 1.599 + Services.io.offline = true; 1.600 + 1.601 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.602 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.603 + do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR); 1.604 + 1.605 + Services.io.offline = false; 1.606 + clean(); 1.607 + run_next_test(); 1.608 + }); 1.609 + 1.610 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.611 + errorHandler.syncAndReportErrors(); 1.612 +}); 1.613 + 1.614 +add_identity_test(this, function test_login_syncAndReportErrors_prolonged_network_error() { 1.615 + // Test prolonged, network errors are reported 1.616 + // when calling syncAndReportErrors. 1.617 + yield configureIdentity({username: "johndoe"}); 1.618 + 1.619 + Service.serverURL = FAKE_SERVER_URL; 1.620 + Service.clusterURL = FAKE_SERVER_URL; 1.621 + 1.622 + let deferred = Promise.defer(); 1.623 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.624 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.625 + do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR); 1.626 + 1.627 + clean(); 1.628 + deferred.resolve(); 1.629 + }); 1.630 + 1.631 + setLastSync(PROLONGED_ERROR_DURATION); 1.632 + errorHandler.syncAndReportErrors(); 1.633 + yield deferred.promise; 1.634 +}); 1.635 + 1.636 +add_test(function test_sync_syncAndReportErrors_prolonged_network_error() { 1.637 + // Test prolonged, network errors are reported 1.638 + // when calling syncAndReportErrors. 1.639 + Services.io.offline = true; 1.640 + 1.641 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.642 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.643 + do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR); 1.644 + 1.645 + Services.io.offline = false; 1.646 + clean(); 1.647 + run_next_test(); 1.648 + }); 1.649 + 1.650 + setLastSync(PROLONGED_ERROR_DURATION); 1.651 + errorHandler.syncAndReportErrors(); 1.652 +}); 1.653 + 1.654 +add_task(function test_login_prolonged_non_network_error() { 1.655 + // Test prolonged, non-network errors are reported 1.656 + let server = sync_httpd_setup(); 1.657 + yield setUp(server); 1.658 + Service.identity.basicPassword = null; 1.659 + 1.660 + let deferred = Promise.defer(); 1.661 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.662 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.663 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.664 + do_check_true(errorHandler.didReportProlongedError); 1.665 + 1.666 + clean(); 1.667 + server.stop(deferred.resolve); 1.668 + }); 1.669 + 1.670 + setLastSync(PROLONGED_ERROR_DURATION); 1.671 + Service.sync(); 1.672 + yield deferred.promise; 1.673 +}); 1.674 + 1.675 +add_task(function test_sync_prolonged_non_network_error() { 1.676 + // Test prolonged, non-network errors are reported 1.677 + let server = sync_httpd_setup(); 1.678 + yield setUp(server); 1.679 + 1.680 + // By calling sync, we ensure we're logged in. 1.681 + Service.sync(); 1.682 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.683 + do_check_true(Service.isLoggedIn); 1.684 + 1.685 + generateCredentialsChangedFailure(); 1.686 + 1.687 + let deferred = Promise.defer(); 1.688 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.689 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.690 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.691 + do_check_true(errorHandler.didReportProlongedError); 1.692 + 1.693 + clean(); 1.694 + server.stop(deferred.resolve); 1.695 + }); 1.696 + 1.697 + setLastSync(PROLONGED_ERROR_DURATION); 1.698 + Service.sync(); 1.699 + yield deferred.promise; 1.700 +}); 1.701 + 1.702 +add_identity_test(this, function test_login_prolonged_network_error() { 1.703 + // Test prolonged, network errors are reported 1.704 + yield configureIdentity({username: "johndoe"}); 1.705 + Service.serverURL = FAKE_SERVER_URL; 1.706 + Service.clusterURL = FAKE_SERVER_URL; 1.707 + 1.708 + let deferred = Promise.defer(); 1.709 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.710 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.711 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.712 + do_check_true(errorHandler.didReportProlongedError); 1.713 + 1.714 + clean(); 1.715 + deferred.resolve(); 1.716 + }); 1.717 + 1.718 + setLastSync(PROLONGED_ERROR_DURATION); 1.719 + Service.sync(); 1.720 + yield deferred.promise; 1.721 +}); 1.722 + 1.723 +add_test(function test_sync_prolonged_network_error() { 1.724 + // Test prolonged, network errors are reported 1.725 + Services.io.offline = true; 1.726 + 1.727 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.728 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.729 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.730 + do_check_true(errorHandler.didReportProlongedError); 1.731 + 1.732 + Services.io.offline = false; 1.733 + clean(); 1.734 + run_next_test(); 1.735 + }); 1.736 + 1.737 + setLastSync(PROLONGED_ERROR_DURATION); 1.738 + Service.sync(); 1.739 +}); 1.740 + 1.741 +add_task(function test_login_non_network_error() { 1.742 + // Test non-network errors are reported 1.743 + let server = sync_httpd_setup(); 1.744 + yield setUp(server); 1.745 + Service.identity.basicPassword = null; 1.746 + 1.747 + let deferred = Promise.defer(); 1.748 + Svc.Obs.add("weave:ui:login:error", function onSyncError() { 1.749 + Svc.Obs.remove("weave:ui:login:error", onSyncError); 1.750 + do_check_eq(Status.login, LOGIN_FAILED_NO_PASSWORD); 1.751 + do_check_false(errorHandler.didReportProlongedError); 1.752 + 1.753 + clean(); 1.754 + server.stop(deferred.resolve); 1.755 + }); 1.756 + 1.757 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.758 + Service.sync(); 1.759 + yield deferred.promise; 1.760 +}); 1.761 + 1.762 +add_task(function test_sync_non_network_error() { 1.763 + // Test non-network errors are reported 1.764 + let server = sync_httpd_setup(); 1.765 + yield setUp(server); 1.766 + 1.767 + // By calling sync, we ensure we're logged in. 1.768 + Service.sync(); 1.769 + do_check_eq(Status.sync, SYNC_SUCCEEDED); 1.770 + do_check_true(Service.isLoggedIn); 1.771 + 1.772 + generateCredentialsChangedFailure(); 1.773 + 1.774 + let deferred = Promise.defer(); 1.775 + Svc.Obs.add("weave:ui:sync:error", function onSyncError() { 1.776 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.777 + do_check_eq(Status.sync, CREDENTIALS_CHANGED); 1.778 + do_check_false(errorHandler.didReportProlongedError); 1.779 + 1.780 + clean(); 1.781 + server.stop(deferred.resolve); 1.782 + }); 1.783 + 1.784 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.785 + Service.sync(); 1.786 + yield deferred.promise; 1.787 +}); 1.788 + 1.789 +add_identity_test(this, function test_login_network_error() { 1.790 + yield configureIdentity({username: "johndoe"}); 1.791 + Service.serverURL = FAKE_SERVER_URL; 1.792 + Service.clusterURL = FAKE_SERVER_URL; 1.793 + 1.794 + let deferred = Promise.defer(); 1.795 + // Test network errors are not reported. 1.796 + Svc.Obs.add("weave:ui:clear-error", function onClearError() { 1.797 + Svc.Obs.remove("weave:ui:clear-error", onClearError); 1.798 + 1.799 + do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR); 1.800 + do_check_false(errorHandler.didReportProlongedError); 1.801 + 1.802 + Services.io.offline = false; 1.803 + clean(); 1.804 + deferred.resolve() 1.805 + }); 1.806 + 1.807 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.808 + Service.sync(); 1.809 + yield deferred.promise; 1.810 +}); 1.811 + 1.812 +add_test(function test_sync_network_error() { 1.813 + // Test network errors are not reported. 1.814 + Services.io.offline = true; 1.815 + 1.816 + Svc.Obs.add("weave:ui:sync:finish", function onUIUpdate() { 1.817 + Svc.Obs.remove("weave:ui:sync:finish", onUIUpdate); 1.818 + do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR); 1.819 + do_check_false(errorHandler.didReportProlongedError); 1.820 + 1.821 + Services.io.offline = false; 1.822 + clean(); 1.823 + run_next_test(); 1.824 + }); 1.825 + 1.826 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.827 + Service.sync(); 1.828 +}); 1.829 + 1.830 +add_identity_test(this, function test_sync_server_maintenance_error() { 1.831 + // Test server maintenance errors are not reported. 1.832 + let server = sync_httpd_setup(); 1.833 + yield setUp(server); 1.834 + 1.835 + const BACKOFF = 42; 1.836 + let engine = engineManager.get("catapult"); 1.837 + engine.enabled = true; 1.838 + engine.exception = {status: 503, 1.839 + headers: {"retry-after": BACKOFF}}; 1.840 + 1.841 + function onSyncError() { 1.842 + do_throw("Shouldn't get here!"); 1.843 + } 1.844 + Svc.Obs.add("weave:ui:sync:error", onSyncError); 1.845 + 1.846 + do_check_eq(Status.service, STATUS_OK); 1.847 + 1.848 + let deferred = Promise.defer(); 1.849 + Svc.Obs.add("weave:ui:sync:finish", function onSyncFinish() { 1.850 + Svc.Obs.remove("weave:ui:sync:finish", onSyncFinish); 1.851 + 1.852 + do_check_eq(Status.service, SYNC_FAILED_PARTIAL); 1.853 + do_check_eq(Status.sync, SERVER_MAINTENANCE); 1.854 + do_check_false(errorHandler.didReportProlongedError); 1.855 + 1.856 + Svc.Obs.remove("weave:ui:sync:error", onSyncError); 1.857 + clean(); 1.858 + server.stop(deferred.resolve); 1.859 + }); 1.860 + 1.861 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.862 + Service.sync(); 1.863 + yield deferred.promise; 1.864 +}); 1.865 + 1.866 +add_identity_test(this, function test_info_collections_login_server_maintenance_error() { 1.867 + // Test info/collections server maintenance errors are not reported. 1.868 + let server = sync_httpd_setup(); 1.869 + yield setUp(server); 1.870 + 1.871 + Service.username = "broken.info"; 1.872 + yield configureIdentity({username: "broken.info"}); 1.873 + Service.serverURL = server.baseURI + "/maintenance/"; 1.874 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.875 + 1.876 + let backoffInterval; 1.877 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.878 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.879 + backoffInterval = subject; 1.880 + }); 1.881 + 1.882 + function onUIUpdate() { 1.883 + do_throw("Shouldn't experience UI update!"); 1.884 + } 1.885 + Svc.Obs.add("weave:ui:login:error", onUIUpdate); 1.886 + 1.887 + do_check_false(Status.enforceBackoff); 1.888 + do_check_eq(Status.service, STATUS_OK); 1.889 + 1.890 + let deferred = Promise.defer(); 1.891 + Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() { 1.892 + Svc.Obs.remove("weave:ui:clear-error", onLoginFinish); 1.893 + 1.894 + do_check_true(Status.enforceBackoff); 1.895 + do_check_eq(backoffInterval, 42); 1.896 + do_check_eq(Status.service, LOGIN_FAILED); 1.897 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.898 + do_check_false(errorHandler.didReportProlongedError); 1.899 + 1.900 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.901 + clean(); 1.902 + server.stop(deferred.resolve); 1.903 + }); 1.904 + 1.905 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.906 + Service.sync(); 1.907 + yield deferred.promise; 1.908 +}); 1.909 + 1.910 +add_identity_test(this, function test_meta_global_login_server_maintenance_error() { 1.911 + // Test meta/global server maintenance errors are not reported. 1.912 + let server = sync_httpd_setup(); 1.913 + yield setUp(server); 1.914 + 1.915 + yield configureIdentity({username: "broken.meta"}); 1.916 + Service.serverURL = server.baseURI + "/maintenance/"; 1.917 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.918 + 1.919 + let backoffInterval; 1.920 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.921 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.922 + backoffInterval = subject; 1.923 + }); 1.924 + 1.925 + function onUIUpdate() { 1.926 + do_throw("Shouldn't get here!"); 1.927 + } 1.928 + Svc.Obs.add("weave:ui:login:error", onUIUpdate); 1.929 + 1.930 + do_check_false(Status.enforceBackoff); 1.931 + do_check_eq(Status.service, STATUS_OK); 1.932 + 1.933 + let deferred = Promise.defer(); 1.934 + Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() { 1.935 + Svc.Obs.remove("weave:ui:clear-error", onLoginFinish); 1.936 + 1.937 + do_check_true(Status.enforceBackoff); 1.938 + do_check_eq(backoffInterval, 42); 1.939 + do_check_eq(Status.service, LOGIN_FAILED); 1.940 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.941 + do_check_false(errorHandler.didReportProlongedError); 1.942 + 1.943 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.944 + clean(); 1.945 + server.stop(deferred.resolve); 1.946 + }); 1.947 + 1.948 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.949 + Service.sync(); 1.950 + yield deferred.promise; 1.951 +}); 1.952 + 1.953 +add_identity_test(this, function test_crypto_keys_login_server_maintenance_error() { 1.954 + // Test crypto/keys server maintenance errors are not reported. 1.955 + let server = sync_httpd_setup(); 1.956 + yield setUp(server); 1.957 + 1.958 + yield configureIdentity({username: "broken.keys"}); 1.959 + Service.serverURL = server.baseURI + "/maintenance/"; 1.960 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.961 + 1.962 + // Force re-download of keys 1.963 + Service.collectionKeys.clear(); 1.964 + 1.965 + let backoffInterval; 1.966 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.967 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.968 + backoffInterval = subject; 1.969 + }); 1.970 + 1.971 + function onUIUpdate() { 1.972 + do_throw("Shouldn't get here!"); 1.973 + } 1.974 + Svc.Obs.add("weave:ui:login:error", onUIUpdate); 1.975 + 1.976 + do_check_false(Status.enforceBackoff); 1.977 + do_check_eq(Status.service, STATUS_OK); 1.978 + 1.979 + let deferred = Promise.defer(); 1.980 + Svc.Obs.add("weave:ui:clear-error", function onLoginFinish() { 1.981 + Svc.Obs.remove("weave:ui:clear-error", onLoginFinish); 1.982 + 1.983 + do_check_true(Status.enforceBackoff); 1.984 + do_check_eq(backoffInterval, 42); 1.985 + do_check_eq(Status.service, LOGIN_FAILED); 1.986 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.987 + do_check_false(errorHandler.didReportProlongedError); 1.988 + 1.989 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.990 + clean(); 1.991 + server.stop(deferred.resolve); 1.992 + }); 1.993 + 1.994 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.995 + Service.sync(); 1.996 + yield deferred.promise; 1.997 +}); 1.998 + 1.999 +add_task(function test_sync_prolonged_server_maintenance_error() { 1.1000 + // Test prolonged server maintenance errors are reported. 1.1001 + let server = sync_httpd_setup(); 1.1002 + yield setUp(server); 1.1003 + 1.1004 + const BACKOFF = 42; 1.1005 + let engine = engineManager.get("catapult"); 1.1006 + engine.enabled = true; 1.1007 + engine.exception = {status: 503, 1.1008 + headers: {"retry-after": BACKOFF}}; 1.1009 + 1.1010 + let deferred = Promise.defer(); 1.1011 + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { 1.1012 + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); 1.1013 + do_check_eq(Status.service, SYNC_FAILED); 1.1014 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1015 + do_check_true(errorHandler.didReportProlongedError); 1.1016 + 1.1017 + clean(); 1.1018 + server.stop(deferred.resolve); 1.1019 + }); 1.1020 + 1.1021 + do_check_eq(Status.service, STATUS_OK); 1.1022 + 1.1023 + setLastSync(PROLONGED_ERROR_DURATION); 1.1024 + Service.sync(); 1.1025 + yield deferred.promise; 1.1026 +}); 1.1027 + 1.1028 +add_identity_test(this, function test_info_collections_login_prolonged_server_maintenance_error(){ 1.1029 + // Test info/collections prolonged server maintenance errors are reported. 1.1030 + let server = sync_httpd_setup(); 1.1031 + yield setUp(server); 1.1032 + 1.1033 + yield configureIdentity({username: "broken.info"}); 1.1034 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1035 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1036 + 1.1037 + let backoffInterval; 1.1038 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1039 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1040 + backoffInterval = subject; 1.1041 + }); 1.1042 + 1.1043 + let deferred = Promise.defer(); 1.1044 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1045 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1046 + do_check_true(Status.enforceBackoff); 1.1047 + do_check_eq(backoffInterval, 42); 1.1048 + do_check_eq(Status.service, SYNC_FAILED); 1.1049 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1050 + do_check_true(errorHandler.didReportProlongedError); 1.1051 + 1.1052 + clean(); 1.1053 + server.stop(deferred.resolve); 1.1054 + }); 1.1055 + 1.1056 + do_check_false(Status.enforceBackoff); 1.1057 + do_check_eq(Status.service, STATUS_OK); 1.1058 + 1.1059 + setLastSync(PROLONGED_ERROR_DURATION); 1.1060 + Service.sync(); 1.1061 + yield deferred.promise; 1.1062 +}); 1.1063 + 1.1064 +add_identity_test(this, function test_meta_global_login_prolonged_server_maintenance_error(){ 1.1065 + // Test meta/global prolonged server maintenance errors are reported. 1.1066 + let server = sync_httpd_setup(); 1.1067 + yield setUp(server); 1.1068 + 1.1069 + yield configureIdentity({username: "broken.meta"}); 1.1070 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1071 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1072 + 1.1073 + let backoffInterval; 1.1074 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1075 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1076 + backoffInterval = subject; 1.1077 + }); 1.1078 + 1.1079 + let deferred = Promise.defer(); 1.1080 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1081 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1082 + do_check_true(Status.enforceBackoff); 1.1083 + do_check_eq(backoffInterval, 42); 1.1084 + do_check_eq(Status.service, SYNC_FAILED); 1.1085 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1086 + do_check_true(errorHandler.didReportProlongedError); 1.1087 + 1.1088 + clean(); 1.1089 + server.stop(deferred.resolve); 1.1090 + }); 1.1091 + 1.1092 + do_check_false(Status.enforceBackoff); 1.1093 + do_check_eq(Status.service, STATUS_OK); 1.1094 + 1.1095 + setLastSync(PROLONGED_ERROR_DURATION); 1.1096 + Service.sync(); 1.1097 + yield deferred.promise; 1.1098 +}); 1.1099 + 1.1100 +add_identity_test(this, function test_download_crypto_keys_login_prolonged_server_maintenance_error(){ 1.1101 + // Test crypto/keys prolonged server maintenance errors are reported. 1.1102 + let server = sync_httpd_setup(); 1.1103 + yield setUp(server); 1.1104 + 1.1105 + yield configureIdentity({username: "broken.keys"}); 1.1106 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1107 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1108 + // Force re-download of keys 1.1109 + Service.collectionKeys.clear(); 1.1110 + 1.1111 + let backoffInterval; 1.1112 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1113 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1114 + backoffInterval = subject; 1.1115 + }); 1.1116 + 1.1117 + let deferred = Promise.defer(); 1.1118 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1119 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1120 + do_check_true(Status.enforceBackoff); 1.1121 + do_check_eq(backoffInterval, 42); 1.1122 + do_check_eq(Status.service, SYNC_FAILED); 1.1123 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1124 + do_check_true(errorHandler.didReportProlongedError); 1.1125 + 1.1126 + clean(); 1.1127 + server.stop(deferred.resolve); 1.1128 + }); 1.1129 + 1.1130 + do_check_false(Status.enforceBackoff); 1.1131 + do_check_eq(Status.service, STATUS_OK); 1.1132 + 1.1133 + setLastSync(PROLONGED_ERROR_DURATION); 1.1134 + Service.sync(); 1.1135 + yield deferred.promise; 1.1136 +}); 1.1137 + 1.1138 +add_identity_test(this, function test_upload_crypto_keys_login_prolonged_server_maintenance_error(){ 1.1139 + // Test crypto/keys prolonged server maintenance errors are reported. 1.1140 + let server = sync_httpd_setup(); 1.1141 + 1.1142 + // Start off with an empty account, do not upload a key. 1.1143 + yield configureIdentity({username: "broken.keys"}); 1.1144 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1145 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1146 + 1.1147 + let backoffInterval; 1.1148 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1149 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1150 + backoffInterval = subject; 1.1151 + }); 1.1152 + 1.1153 + let deferred = Promise.defer(); 1.1154 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1155 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1156 + do_check_true(Status.enforceBackoff); 1.1157 + do_check_eq(backoffInterval, 42); 1.1158 + do_check_eq(Status.service, SYNC_FAILED); 1.1159 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1160 + do_check_true(errorHandler.didReportProlongedError); 1.1161 + 1.1162 + clean(); 1.1163 + server.stop(deferred.resolve); 1.1164 + }); 1.1165 + 1.1166 + do_check_false(Status.enforceBackoff); 1.1167 + do_check_eq(Status.service, STATUS_OK); 1.1168 + 1.1169 + setLastSync(PROLONGED_ERROR_DURATION); 1.1170 + Service.sync(); 1.1171 + yield deferred.promise; 1.1172 +}); 1.1173 + 1.1174 +add_identity_test(this, function test_wipeServer_login_prolonged_server_maintenance_error(){ 1.1175 + // Test that we report prolonged server maintenance errors that occur whilst 1.1176 + // wiping the server. 1.1177 + let server = sync_httpd_setup(); 1.1178 + 1.1179 + // Start off with an empty account, do not upload a key. 1.1180 + yield configureIdentity({username: "broken.wipe"}); 1.1181 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1182 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1183 + 1.1184 + let backoffInterval; 1.1185 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1186 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1187 + backoffInterval = subject; 1.1188 + }); 1.1189 + 1.1190 + let deferred = Promise.defer(); 1.1191 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1192 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1193 + do_check_true(Status.enforceBackoff); 1.1194 + do_check_eq(backoffInterval, 42); 1.1195 + do_check_eq(Status.service, SYNC_FAILED); 1.1196 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1197 + do_check_true(errorHandler.didReportProlongedError); 1.1198 + 1.1199 + clean(); 1.1200 + server.stop(deferred.resolve); 1.1201 + }); 1.1202 + 1.1203 + do_check_false(Status.enforceBackoff); 1.1204 + do_check_eq(Status.service, STATUS_OK); 1.1205 + 1.1206 + setLastSync(PROLONGED_ERROR_DURATION); 1.1207 + Service.sync(); 1.1208 + yield deferred.promise; 1.1209 +}); 1.1210 + 1.1211 +add_identity_test(this, function test_wipeRemote_prolonged_server_maintenance_error(){ 1.1212 + // Test that we report prolonged server maintenance errors that occur whilst 1.1213 + // wiping all remote devices. 1.1214 + let server = sync_httpd_setup(); 1.1215 + 1.1216 + server.registerPathHandler("/1.1/broken.wipe/storage/catapult", service_unavailable); 1.1217 + yield configureIdentity({username: "broken.wipe"}); 1.1218 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1219 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1220 + generateAndUploadKeys(); 1.1221 + 1.1222 + let engine = engineManager.get("catapult"); 1.1223 + engine.exception = null; 1.1224 + engine.enabled = true; 1.1225 + 1.1226 + let backoffInterval; 1.1227 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1228 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1229 + backoffInterval = subject; 1.1230 + }); 1.1231 + 1.1232 + let deferred = Promise.defer(); 1.1233 + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { 1.1234 + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); 1.1235 + do_check_true(Status.enforceBackoff); 1.1236 + do_check_eq(backoffInterval, 42); 1.1237 + do_check_eq(Status.service, SYNC_FAILED); 1.1238 + do_check_eq(Status.sync, PROLONGED_SYNC_FAILURE); 1.1239 + do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote"); 1.1240 + do_check_true(errorHandler.didReportProlongedError); 1.1241 + 1.1242 + clean(); 1.1243 + server.stop(deferred.resolve); 1.1244 + }); 1.1245 + 1.1246 + do_check_false(Status.enforceBackoff); 1.1247 + do_check_eq(Status.service, STATUS_OK); 1.1248 + 1.1249 + Svc.Prefs.set("firstSync", "wipeRemote"); 1.1250 + setLastSync(PROLONGED_ERROR_DURATION); 1.1251 + Service.sync(); 1.1252 + yield deferred.promise; 1.1253 +}); 1.1254 + 1.1255 +add_task(function test_sync_syncAndReportErrors_server_maintenance_error() { 1.1256 + // Test server maintenance errors are reported 1.1257 + // when calling syncAndReportErrors. 1.1258 + let server = sync_httpd_setup(); 1.1259 + yield setUp(server); 1.1260 + 1.1261 + const BACKOFF = 42; 1.1262 + let engine = engineManager.get("catapult"); 1.1263 + engine.enabled = true; 1.1264 + engine.exception = {status: 503, 1.1265 + headers: {"retry-after": BACKOFF}}; 1.1266 + 1.1267 + let deferred = Promise.defer(); 1.1268 + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { 1.1269 + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); 1.1270 + do_check_eq(Status.service, SYNC_FAILED_PARTIAL); 1.1271 + do_check_eq(Status.sync, SERVER_MAINTENANCE); 1.1272 + do_check_false(errorHandler.didReportProlongedError); 1.1273 + 1.1274 + clean(); 1.1275 + server.stop(deferred.resolve); 1.1276 + }); 1.1277 + 1.1278 + do_check_eq(Status.service, STATUS_OK); 1.1279 + 1.1280 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1281 + errorHandler.syncAndReportErrors(); 1.1282 + yield deferred.promise; 1.1283 +}); 1.1284 + 1.1285 +add_identity_test(this, function test_info_collections_login_syncAndReportErrors_server_maintenance_error() { 1.1286 + // Test info/collections server maintenance errors are reported 1.1287 + // when calling syncAndReportErrors. 1.1288 + let server = sync_httpd_setup(); 1.1289 + yield setUp(server); 1.1290 + 1.1291 + yield configureIdentity({username: "broken.info"}); 1.1292 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1293 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1294 + 1.1295 + let backoffInterval; 1.1296 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1297 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1298 + backoffInterval = subject; 1.1299 + }); 1.1300 + 1.1301 + let deferred = Promise.defer(); 1.1302 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1303 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1304 + do_check_true(Status.enforceBackoff); 1.1305 + do_check_eq(backoffInterval, 42); 1.1306 + do_check_eq(Status.service, LOGIN_FAILED); 1.1307 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1308 + do_check_false(errorHandler.didReportProlongedError); 1.1309 + 1.1310 + clean(); 1.1311 + server.stop(deferred.resolve); 1.1312 + }); 1.1313 + 1.1314 + do_check_false(Status.enforceBackoff); 1.1315 + do_check_eq(Status.service, STATUS_OK); 1.1316 + 1.1317 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1318 + errorHandler.syncAndReportErrors(); 1.1319 + yield deferred.promise; 1.1320 +}); 1.1321 + 1.1322 +add_identity_test(this, function test_meta_global_login_syncAndReportErrors_server_maintenance_error() { 1.1323 + // Test meta/global server maintenance errors are reported 1.1324 + // when calling syncAndReportErrors. 1.1325 + let server = sync_httpd_setup(); 1.1326 + yield setUp(server); 1.1327 + 1.1328 + yield configureIdentity({username: "broken.meta"}); 1.1329 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1330 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1331 + 1.1332 + let backoffInterval; 1.1333 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1334 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1335 + backoffInterval = subject; 1.1336 + }); 1.1337 + 1.1338 + let deferred = Promise.defer(); 1.1339 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1340 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1341 + do_check_true(Status.enforceBackoff); 1.1342 + do_check_eq(backoffInterval, 42); 1.1343 + do_check_eq(Status.service, LOGIN_FAILED); 1.1344 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1345 + do_check_false(errorHandler.didReportProlongedError); 1.1346 + 1.1347 + clean(); 1.1348 + server.stop(deferred.resolve); 1.1349 + }); 1.1350 + 1.1351 + do_check_false(Status.enforceBackoff); 1.1352 + do_check_eq(Status.service, STATUS_OK); 1.1353 + 1.1354 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1355 + errorHandler.syncAndReportErrors(); 1.1356 + yield deferred.promise; 1.1357 +}); 1.1358 + 1.1359 +add_identity_test(this, function test_download_crypto_keys_login_syncAndReportErrors_server_maintenance_error() { 1.1360 + // Test crypto/keys server maintenance errors are reported 1.1361 + // when calling syncAndReportErrors. 1.1362 + let server = sync_httpd_setup(); 1.1363 + yield setUp(server); 1.1364 + 1.1365 + yield configureIdentity({username: "broken.keys"}); 1.1366 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1367 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1368 + // Force re-download of keys 1.1369 + Service.collectionKeys.clear(); 1.1370 + 1.1371 + let backoffInterval; 1.1372 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1373 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1374 + backoffInterval = subject; 1.1375 + }); 1.1376 + 1.1377 + let deferred = Promise.defer(); 1.1378 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1379 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1380 + do_check_true(Status.enforceBackoff); 1.1381 + do_check_eq(backoffInterval, 42); 1.1382 + do_check_eq(Status.service, LOGIN_FAILED); 1.1383 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1384 + do_check_false(errorHandler.didReportProlongedError); 1.1385 + 1.1386 + clean(); 1.1387 + server.stop(deferred.resolve); 1.1388 + }); 1.1389 + 1.1390 + do_check_false(Status.enforceBackoff); 1.1391 + do_check_eq(Status.service, STATUS_OK); 1.1392 + 1.1393 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1394 + errorHandler.syncAndReportErrors(); 1.1395 + yield deferred.promise; 1.1396 +}); 1.1397 + 1.1398 +add_identity_test(this, function test_upload_crypto_keys_login_syncAndReportErrors_server_maintenance_error() { 1.1399 + // Test crypto/keys server maintenance errors are reported 1.1400 + // when calling syncAndReportErrors. 1.1401 + let server = sync_httpd_setup(); 1.1402 + 1.1403 + // Start off with an empty account, do not upload a key. 1.1404 + yield configureIdentity({username: "broken.keys"}); 1.1405 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1406 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1407 + 1.1408 + let backoffInterval; 1.1409 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1410 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1411 + backoffInterval = subject; 1.1412 + }); 1.1413 + 1.1414 + let deferred = Promise.defer(); 1.1415 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1416 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1417 + do_check_true(Status.enforceBackoff); 1.1418 + do_check_eq(backoffInterval, 42); 1.1419 + do_check_eq(Status.service, LOGIN_FAILED); 1.1420 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1421 + do_check_false(errorHandler.didReportProlongedError); 1.1422 + 1.1423 + clean(); 1.1424 + server.stop(deferred.resolve); 1.1425 + }); 1.1426 + 1.1427 + do_check_false(Status.enforceBackoff); 1.1428 + do_check_eq(Status.service, STATUS_OK); 1.1429 + 1.1430 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1431 + errorHandler.syncAndReportErrors(); 1.1432 + yield deferred.promise; 1.1433 +}); 1.1434 + 1.1435 +add_identity_test(this, function test_wipeServer_login_syncAndReportErrors_server_maintenance_error() { 1.1436 + // Test crypto/keys server maintenance errors are reported 1.1437 + // when calling syncAndReportErrors. 1.1438 + let server = sync_httpd_setup(); 1.1439 + 1.1440 + // Start off with an empty account, do not upload a key. 1.1441 + yield configureIdentity({username: "broken.wipe"}); 1.1442 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1443 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1444 + 1.1445 + let backoffInterval; 1.1446 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1447 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1448 + backoffInterval = subject; 1.1449 + }); 1.1450 + 1.1451 + let deferred = Promise.defer(); 1.1452 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1453 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1454 + do_check_true(Status.enforceBackoff); 1.1455 + do_check_eq(backoffInterval, 42); 1.1456 + do_check_eq(Status.service, LOGIN_FAILED); 1.1457 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1458 + do_check_false(errorHandler.didReportProlongedError); 1.1459 + 1.1460 + clean(); 1.1461 + server.stop(deferred.resolve); 1.1462 + }); 1.1463 + 1.1464 + do_check_false(Status.enforceBackoff); 1.1465 + do_check_eq(Status.service, STATUS_OK); 1.1466 + 1.1467 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1468 + errorHandler.syncAndReportErrors(); 1.1469 + yield deferred.promise; 1.1470 +}); 1.1471 + 1.1472 +add_identity_test(this, function test_wipeRemote_syncAndReportErrors_server_maintenance_error(){ 1.1473 + // Test that we report prolonged server maintenance errors that occur whilst 1.1474 + // wiping all remote devices. 1.1475 + let server = sync_httpd_setup(); 1.1476 + 1.1477 + yield configureIdentity({username: "broken.wipe"}); 1.1478 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1479 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1480 + generateAndUploadKeys(); 1.1481 + 1.1482 + let engine = engineManager.get("catapult"); 1.1483 + engine.exception = null; 1.1484 + engine.enabled = true; 1.1485 + 1.1486 + let backoffInterval; 1.1487 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1488 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1489 + backoffInterval = subject; 1.1490 + }); 1.1491 + 1.1492 + let deferred = Promise.defer(); 1.1493 + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { 1.1494 + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); 1.1495 + do_check_true(Status.enforceBackoff); 1.1496 + do_check_eq(backoffInterval, 42); 1.1497 + do_check_eq(Status.service, SYNC_FAILED); 1.1498 + do_check_eq(Status.sync, SERVER_MAINTENANCE); 1.1499 + do_check_eq(Svc.Prefs.get("firstSync"), "wipeRemote"); 1.1500 + do_check_false(errorHandler.didReportProlongedError); 1.1501 + 1.1502 + clean(); 1.1503 + server.stop(deferred.resolve); 1.1504 + }); 1.1505 + 1.1506 + do_check_false(Status.enforceBackoff); 1.1507 + do_check_eq(Status.service, STATUS_OK); 1.1508 + 1.1509 + Svc.Prefs.set("firstSync", "wipeRemote"); 1.1510 + setLastSync(NON_PROLONGED_ERROR_DURATION); 1.1511 + errorHandler.syncAndReportErrors(); 1.1512 + yield deferred.promise; 1.1513 +}); 1.1514 + 1.1515 +add_task(function test_sync_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1516 + // Test prolonged server maintenance errors are 1.1517 + // reported when calling syncAndReportErrors. 1.1518 + let server = sync_httpd_setup(); 1.1519 + yield setUp(server); 1.1520 + 1.1521 + const BACKOFF = 42; 1.1522 + let engine = engineManager.get("catapult"); 1.1523 + engine.enabled = true; 1.1524 + engine.exception = {status: 503, 1.1525 + headers: {"retry-after": BACKOFF}}; 1.1526 + 1.1527 + let deferred = Promise.defer(); 1.1528 + Svc.Obs.add("weave:ui:sync:error", function onUIUpdate() { 1.1529 + Svc.Obs.remove("weave:ui:sync:error", onUIUpdate); 1.1530 + do_check_eq(Status.service, SYNC_FAILED_PARTIAL); 1.1531 + do_check_eq(Status.sync, SERVER_MAINTENANCE); 1.1532 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1533 + // didReportProlongedError not touched. 1.1534 + do_check_false(errorHandler.didReportProlongedError); 1.1535 + 1.1536 + clean(); 1.1537 + server.stop(deferred.resolve); 1.1538 + }); 1.1539 + 1.1540 + do_check_eq(Status.service, STATUS_OK); 1.1541 + 1.1542 + setLastSync(PROLONGED_ERROR_DURATION); 1.1543 + errorHandler.syncAndReportErrors(); 1.1544 + yield deferred.promise; 1.1545 +}); 1.1546 + 1.1547 +add_identity_test(this, function test_info_collections_login_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1548 + // Test info/collections server maintenance errors are reported 1.1549 + // when calling syncAndReportErrors. 1.1550 + let server = sync_httpd_setup(); 1.1551 + yield setUp(server); 1.1552 + 1.1553 + yield configureIdentity({username: "broken.info"}); 1.1554 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1555 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1556 + 1.1557 + let backoffInterval; 1.1558 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1559 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1560 + backoffInterval = subject; 1.1561 + }); 1.1562 + 1.1563 + let deferred = Promise.defer(); 1.1564 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1565 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1566 + do_check_true(Status.enforceBackoff); 1.1567 + do_check_eq(backoffInterval, 42); 1.1568 + do_check_eq(Status.service, LOGIN_FAILED); 1.1569 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1570 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1571 + // didReportProlongedError not touched. 1.1572 + do_check_false(errorHandler.didReportProlongedError); 1.1573 + 1.1574 + clean(); 1.1575 + server.stop(deferred.resolve); 1.1576 + }); 1.1577 + 1.1578 + do_check_false(Status.enforceBackoff); 1.1579 + do_check_eq(Status.service, STATUS_OK); 1.1580 + 1.1581 + setLastSync(PROLONGED_ERROR_DURATION); 1.1582 + errorHandler.syncAndReportErrors(); 1.1583 + yield deferred.promise; 1.1584 +}); 1.1585 + 1.1586 +add_identity_test(this, function test_meta_global_login_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1587 + // Test meta/global server maintenance errors are reported 1.1588 + // when calling syncAndReportErrors. 1.1589 + let server = sync_httpd_setup(); 1.1590 + yield setUp(server); 1.1591 + 1.1592 + yield configureIdentity({username: "broken.meta"}); 1.1593 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1594 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1595 + 1.1596 + let backoffInterval; 1.1597 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1598 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1599 + backoffInterval = subject; 1.1600 + }); 1.1601 + 1.1602 + let deferred = Promise.defer(); 1.1603 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1604 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1605 + do_check_true(Status.enforceBackoff); 1.1606 + do_check_eq(backoffInterval, 42); 1.1607 + do_check_eq(Status.service, LOGIN_FAILED); 1.1608 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1609 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1610 + // didReportProlongedError not touched. 1.1611 + do_check_false(errorHandler.didReportProlongedError); 1.1612 + 1.1613 + clean(); 1.1614 + server.stop(deferred.resolve); 1.1615 + }); 1.1616 + 1.1617 + do_check_false(Status.enforceBackoff); 1.1618 + do_check_eq(Status.service, STATUS_OK); 1.1619 + 1.1620 + setLastSync(PROLONGED_ERROR_DURATION); 1.1621 + errorHandler.syncAndReportErrors(); 1.1622 + yield deferred.promise; 1.1623 +}); 1.1624 + 1.1625 +add_identity_test(this, function test_download_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1626 + // Test crypto/keys server maintenance errors are reported 1.1627 + // when calling syncAndReportErrors. 1.1628 + let server = sync_httpd_setup(); 1.1629 + yield setUp(server); 1.1630 + 1.1631 + yield configureIdentity({username: "broken.keys"}); 1.1632 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1633 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1634 + // Force re-download of keys 1.1635 + Service.collectionKeys.clear(); 1.1636 + 1.1637 + let backoffInterval; 1.1638 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1639 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1640 + backoffInterval = subject; 1.1641 + }); 1.1642 + 1.1643 + let deferred = Promise.defer(); 1.1644 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1645 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1646 + do_check_true(Status.enforceBackoff); 1.1647 + do_check_eq(backoffInterval, 42); 1.1648 + do_check_eq(Status.service, LOGIN_FAILED); 1.1649 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1650 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1651 + // didReportProlongedError not touched. 1.1652 + do_check_false(errorHandler.didReportProlongedError); 1.1653 + 1.1654 + clean(); 1.1655 + server.stop(deferred.resolve); 1.1656 + }); 1.1657 + 1.1658 + do_check_false(Status.enforceBackoff); 1.1659 + do_check_eq(Status.service, STATUS_OK); 1.1660 + 1.1661 + setLastSync(PROLONGED_ERROR_DURATION); 1.1662 + errorHandler.syncAndReportErrors(); 1.1663 + yield deferred.promise; 1.1664 +}); 1.1665 + 1.1666 +add_identity_test(this, function test_upload_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1667 + // Test crypto/keys server maintenance errors are reported 1.1668 + // when calling syncAndReportErrors. 1.1669 + let server = sync_httpd_setup(); 1.1670 + 1.1671 + // Start off with an empty account, do not upload a key. 1.1672 + yield configureIdentity({username: "broken.keys"}); 1.1673 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1674 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1675 + 1.1676 + let backoffInterval; 1.1677 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1678 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1679 + backoffInterval = subject; 1.1680 + }); 1.1681 + 1.1682 + let deferred = Promise.defer(); 1.1683 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1684 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1685 + do_check_true(Status.enforceBackoff); 1.1686 + do_check_eq(backoffInterval, 42); 1.1687 + do_check_eq(Status.service, LOGIN_FAILED); 1.1688 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1689 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1690 + // didReportProlongedError not touched. 1.1691 + do_check_false(errorHandler.didReportProlongedError); 1.1692 + 1.1693 + clean(); 1.1694 + server.stop(deferred.resolve); 1.1695 + }); 1.1696 + 1.1697 + do_check_false(Status.enforceBackoff); 1.1698 + do_check_eq(Status.service, STATUS_OK); 1.1699 + 1.1700 + setLastSync(PROLONGED_ERROR_DURATION); 1.1701 + errorHandler.syncAndReportErrors(); 1.1702 + yield deferred.promise; 1.1703 +}); 1.1704 + 1.1705 +add_identity_test(this, function test_wipeServer_login_syncAndReportErrors_prolonged_server_maintenance_error() { 1.1706 + // Test crypto/keys server maintenance errors are reported 1.1707 + // when calling syncAndReportErrors. 1.1708 + let server = sync_httpd_setup(); 1.1709 + 1.1710 + // Start off with an empty account, do not upload a key. 1.1711 + yield configureIdentity({username: "broken.wipe"}); 1.1712 + Service.serverURL = server.baseURI + "/maintenance/"; 1.1713 + Service.clusterURL = server.baseURI + "/maintenance/"; 1.1714 + 1.1715 + let backoffInterval; 1.1716 + Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) { 1.1717 + Svc.Obs.remove("weave:service:backoff:interval", observe); 1.1718 + backoffInterval = subject; 1.1719 + }); 1.1720 + 1.1721 + let deferred = Promise.defer(); 1.1722 + Svc.Obs.add("weave:ui:login:error", function onUIUpdate() { 1.1723 + Svc.Obs.remove("weave:ui:login:error", onUIUpdate); 1.1724 + do_check_true(Status.enforceBackoff); 1.1725 + do_check_eq(backoffInterval, 42); 1.1726 + do_check_eq(Status.service, LOGIN_FAILED); 1.1727 + do_check_eq(Status.login, SERVER_MAINTENANCE); 1.1728 + // syncAndReportErrors means dontIgnoreErrors, which means 1.1729 + // didReportProlongedError not touched. 1.1730 + do_check_false(errorHandler.didReportProlongedError); 1.1731 + 1.1732 + clean(); 1.1733 + server.stop(deferred.resolve); 1.1734 + }); 1.1735 + 1.1736 + do_check_false(Status.enforceBackoff); 1.1737 + do_check_eq(Status.service, STATUS_OK); 1.1738 + 1.1739 + setLastSync(PROLONGED_ERROR_DURATION); 1.1740 + errorHandler.syncAndReportErrors(); 1.1741 + yield deferred.promise; 1.1742 +}); 1.1743 + 1.1744 +add_task(function test_sync_engine_generic_fail() { 1.1745 + let server = sync_httpd_setup(); 1.1746 + 1.1747 + let engine = engineManager.get("catapult"); 1.1748 + engine.enabled = true; 1.1749 + engine.sync = function sync() { 1.1750 + Svc.Obs.notify("weave:engine:sync:error", "", "catapult"); 1.1751 + }; 1.1752 + 1.1753 + let log = Log.repository.getLogger("Sync.ErrorHandler"); 1.1754 + Svc.Prefs.set("log.appender.file.logOnError", true); 1.1755 + 1.1756 + do_check_eq(Status.engines["catapult"], undefined); 1.1757 + 1.1758 + let deferred = Promise.defer(); 1.1759 + // Don't wait for reset-file-log until the sync is underway. 1.1760 + // This avoids us catching a delayed notification from an earlier test. 1.1761 + Svc.Obs.add("weave:engine:sync:finish", function onEngineFinish() { 1.1762 + Svc.Obs.remove("weave:engine:sync:finish", onEngineFinish); 1.1763 + 1.1764 + log.info("Adding reset-file-log observer."); 1.1765 + Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() { 1.1766 + Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog); 1.1767 + 1.1768 + // Put these checks here, not after sync(), so that we aren't racing the 1.1769 + // log handler... which resets everything just a few lines below! 1.1770 + _("Status.engines: " + JSON.stringify(Status.engines)); 1.1771 + do_check_eq(Status.engines["catapult"], ENGINE_UNKNOWN_FAIL); 1.1772 + do_check_eq(Status.service, SYNC_FAILED_PARTIAL); 1.1773 + 1.1774 + // Test Error log was written on SYNC_FAILED_PARTIAL. 1.1775 + let entries = logsdir.directoryEntries; 1.1776 + do_check_true(entries.hasMoreElements()); 1.1777 + let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile); 1.1778 + do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length), 1.1779 + LOG_PREFIX_ERROR); 1.1780 + 1.1781 + clean(); 1.1782 + server.stop(deferred.resolve); 1.1783 + }); 1.1784 + }); 1.1785 + 1.1786 + do_check_true(yield setUp(server)); 1.1787 + Service.sync(); 1.1788 + yield deferred.promise; 1.1789 +}); 1.1790 + 1.1791 +add_test(function test_logs_on_sync_error_despite_shouldReportError() { 1.1792 + _("Ensure that an error is still logged when weave:service:sync:error " + 1.1793 + "is notified, despite shouldReportError returning false."); 1.1794 + 1.1795 + let log = Log.repository.getLogger("Sync.ErrorHandler"); 1.1796 + Svc.Prefs.set("log.appender.file.logOnError", true); 1.1797 + log.info("TESTING"); 1.1798 + 1.1799 + // Ensure that we report no error. 1.1800 + Status.login = MASTER_PASSWORD_LOCKED; 1.1801 + do_check_false(errorHandler.shouldReportError()); 1.1802 + 1.1803 + Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() { 1.1804 + Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog); 1.1805 + 1.1806 + // Test that error log was written. 1.1807 + let entries = logsdir.directoryEntries; 1.1808 + do_check_true(entries.hasMoreElements()); 1.1809 + let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile); 1.1810 + do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length), 1.1811 + LOG_PREFIX_ERROR); 1.1812 + 1.1813 + clean(); 1.1814 + run_next_test(); 1.1815 + }); 1.1816 + Svc.Obs.notify("weave:service:sync:error", {}); 1.1817 +}); 1.1818 + 1.1819 +add_test(function test_logs_on_login_error_despite_shouldReportError() { 1.1820 + _("Ensure that an error is still logged when weave:service:login:error " + 1.1821 + "is notified, despite shouldReportError returning false."); 1.1822 + 1.1823 + let log = Log.repository.getLogger("Sync.ErrorHandler"); 1.1824 + Svc.Prefs.set("log.appender.file.logOnError", true); 1.1825 + log.info("TESTING"); 1.1826 + 1.1827 + // Ensure that we report no error. 1.1828 + Status.login = MASTER_PASSWORD_LOCKED; 1.1829 + do_check_false(errorHandler.shouldReportError()); 1.1830 + 1.1831 + Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() { 1.1832 + Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog); 1.1833 + 1.1834 + // Test that error log was written. 1.1835 + let entries = logsdir.directoryEntries; 1.1836 + do_check_true(entries.hasMoreElements()); 1.1837 + let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile); 1.1838 + do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length), 1.1839 + LOG_PREFIX_ERROR); 1.1840 + 1.1841 + clean(); 1.1842 + run_next_test(); 1.1843 + }); 1.1844 + Svc.Obs.notify("weave:service:login:error", {}); 1.1845 +}); 1.1846 + 1.1847 +// This test should be the last one since it monkeypatches the engine object 1.1848 +// and we should only have one engine object throughout the file (bug 629664). 1.1849 +add_task(function test_engine_applyFailed() { 1.1850 + let server = sync_httpd_setup(); 1.1851 + 1.1852 + let engine = engineManager.get("catapult"); 1.1853 + engine.enabled = true; 1.1854 + delete engine.exception; 1.1855 + engine.sync = function sync() { 1.1856 + Svc.Obs.notify("weave:engine:sync:applied", {newFailed:1}, "catapult"); 1.1857 + }; 1.1858 + 1.1859 + let log = Log.repository.getLogger("Sync.ErrorHandler"); 1.1860 + Svc.Prefs.set("log.appender.file.logOnError", true); 1.1861 + 1.1862 + let deferred = Promise.defer(); 1.1863 + Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() { 1.1864 + Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog); 1.1865 + 1.1866 + do_check_eq(Status.engines["catapult"], ENGINE_APPLY_FAIL); 1.1867 + do_check_eq(Status.service, SYNC_FAILED_PARTIAL); 1.1868 + 1.1869 + // Test Error log was written on SYNC_FAILED_PARTIAL. 1.1870 + let entries = logsdir.directoryEntries; 1.1871 + do_check_true(entries.hasMoreElements()); 1.1872 + let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile); 1.1873 + do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length), 1.1874 + LOG_PREFIX_ERROR); 1.1875 + 1.1876 + clean(); 1.1877 + server.stop(deferred.resolve); 1.1878 + }); 1.1879 + 1.1880 + do_check_eq(Status.engines["catapult"], undefined); 1.1881 + do_check_true(yield setUp(server)); 1.1882 + Service.sync(); 1.1883 + yield deferred.promise; 1.1884 +});