Bug 1439777 p2 - Remove weave:ui:* related code. r=markh,tcsc

MozReview-Commit-ID: D1H36YeiJCS

--HG--
extra : rebase_source : e90de5b437cc7fa8afcbe174c7bfb7bdce5b4c90
This commit is contained in:
Edouard Oger 2018-02-22 16:30:39 +08:00
parent b351304538
commit e68b9239b3
11 changed files with 79 additions and 1231 deletions

View File

@ -565,7 +565,7 @@ var gSync = {
const state = UIState.get();
if (state.status == UIState.STATUS_SIGNED_IN) {
this.updateSyncStatus({ syncing: true });
setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0);
Services.tm.dispatchToMainThread(() => Weave.Service.sync());
}
},

View File

@ -106,7 +106,6 @@ CREDENTIALS_CHANGED: "error.sync.reason.credentials_changed",
ABORT_SYNC_COMMAND: "aborting sync, process commands said so",
NO_SYNC_NODE_FOUND: "error.sync.reason.no_node_found",
OVER_QUOTA: "error.sync.reason.over_quota",
PROLONGED_SYNC_FAILURE: "error.sync.prolonged_failure",
SERVER_MAINTENANCE: "error.sync.reason.serverMaintenance",
RESPONSE_OVER_QUOTA: "14",

View File

@ -654,19 +654,7 @@ function ErrorHandler(service) {
this.init();
}
ErrorHandler.prototype = {
/**
* Flag that turns on error reporting for all errors, incl. network errors.
*/
dontIgnoreErrors: false,
/**
* Flag that indicates if we have already reported a prolonged failure.
* Once set, we don't report it again, meaning this error is only reported
* one per run.
*/
didReportProlongedError: false,
init: function init() {
init() {
Svc.Obs.add("weave:engine:sync:applied", this);
Svc.Obs.add("weave:engine:sync:error", this);
Svc.Obs.add("weave:service:login:error", this);
@ -692,7 +680,7 @@ ErrorHandler.prototype = {
this._logManager = new LogManager(Svc.Prefs, logs, "sync");
},
observe: function observe(subject, topic, data) {
observe(subject, topic, data) {
this._log.trace("Handling " + topic);
switch (topic) {
case "weave:engine:sync:applied":
@ -723,14 +711,6 @@ ErrorHandler.prototype = {
case "weave:service:login:error":
this._log.error("Sync encountered a login error");
this.resetFileLog();
if (this.shouldReportError()) {
this.notifyOnNextTick("weave:ui:login:error");
} else {
this.notifyOnNextTick("weave:ui:clear-error");
}
this.dontIgnoreErrors = false;
break;
case "weave:service:sync:error": {
if (Status.sync == CREDENTIALS_CHANGED) {
@ -749,14 +729,6 @@ ErrorHandler.prototype = {
// Not a shutdown related exception...
this._log.error("Sync encountered an error", exception);
this.resetFileLog();
if (this.shouldReportError()) {
this.notifyOnNextTick("weave:ui:sync:error");
} else {
this.notifyOnNextTick("weave:ui:sync:finish");
}
this.dontIgnoreErrors = false;
break;
}
case "weave:service:sync:finish":
@ -775,18 +747,8 @@ ErrorHandler.prototype = {
if (Status.service == SYNC_FAILED_PARTIAL) {
this._log.error("Some engines did not sync correctly.");
this.resetFileLog();
if (this.shouldReportError()) {
this.dontIgnoreErrors = false;
this.notifyOnNextTick("weave:ui:sync:error");
break;
}
} else {
this.resetFileLog();
}
this.dontIgnoreErrors = false;
this.notifyOnNextTick("weave:ui:sync:finish");
this.resetFileLog();
break;
case "weave:service:start-over:finish":
// ensure we capture any logs between the last sync and the reset completing.
@ -795,27 +757,6 @@ ErrorHandler.prototype = {
}
},
notifyOnNextTick: function notifyOnNextTick(topic) {
CommonUtils.nextTick(function() {
this._log.trace("Notifying " + topic +
". Status.login is " + Status.login +
". Status.sync is " + Status.sync);
Svc.Obs.notify(topic);
}, this);
},
/**
* Trigger a sync and don't muffle any errors, particularly network errors.
*/
syncAndReportErrors: function syncAndReportErrors() {
this._log.debug("Beginning user-triggered sync.");
this.dontIgnoreErrors = true;
CommonUtils.nextTick(() => {
this.service.sync({why: "user"});
}, this);
},
async _dumpAddons() {
// Just dump the items that sync may be concerned with. Specifically,
// active extensions that are not hidden.
@ -837,108 +778,16 @@ ErrorHandler.prototype = {
* Generate a log file for the sync that just completed
* and refresh the input & output streams.
*/
resetFileLog: function resetFileLog() {
let onComplete = logType => {
Svc.Obs.notify("weave:service:reset-file-log");
this._log.trace("Notified: " + Date.now());
if (logType == this._logManager.ERROR_LOG_WRITTEN) {
Cu.reportError("Sync encountered an error - see about:sync-log for the log file.");
}
};
async resetFileLog() {
// If we're writing an error log, dump extensions that may be causing problems.
let beforeResetLog;
if (this._logManager.sawError) {
beforeResetLog = this._dumpAddons();
} else {
beforeResetLog = Promise.resolve();
await this._dumpAddons();
}
// Note we do not return the promise here - the caller doesn't need to wait
// for this to complete.
beforeResetLog
.then(() => this._logManager.resetFileLog())
.then(onComplete, onComplete);
},
/**
* Translates server error codes to meaningful strings.
*
* @param code
* server error code as an integer
*/
errorStr: function errorStr(code) {
switch (code.toString()) {
case "1":
return "illegal-method";
case "2":
return "invalid-captcha";
case "3":
return "invalid-username";
case "4":
return "cannot-overwrite-resource";
case "5":
return "userid-mismatch";
case "6":
return "json-parse-failure";
case "7":
return "invalid-password";
case "8":
return "invalid-record";
case "9":
return "weak-password";
default:
return "generic-server-error";
const logType = await this._logManager.resetFileLog();
if (logType == this._logManager.ERROR_LOG_WRITTEN) {
Cu.reportError("Sync encountered an error - see about:sync-log for the log file.");
}
},
// A function to indicate if Sync errors should be "reported" - which in this
// context really means "should be notify observers of an error" - but note
// that since bug 1180587, no one is going to surface an error to the user.
shouldReportError: function shouldReportError() {
if (Status.login == MASTER_PASSWORD_LOCKED) {
this._log.trace("shouldReportError: false (master password locked).");
return false;
}
if (this.dontIgnoreErrors) {
return true;
}
if (Status.login == LOGIN_FAILED_LOGIN_REJECTED) {
// An explicit LOGIN_REJECTED state is always reported (bug 1081158)
this._log.trace("shouldReportError: true (login was rejected)");
return true;
}
let lastSync = Svc.Prefs.get("lastSync");
if (lastSync && ((Date.now() - Date.parse(lastSync)) >
Svc.Prefs.get("errorhandler.networkFailureReportTimeout") * 1000)) {
Status.sync = PROLONGED_SYNC_FAILURE;
if (this.didReportProlongedError) {
this._log.trace("shouldReportError: false (prolonged sync failure, but" +
" we've already reported it).");
return false;
}
this._log.trace("shouldReportError: true (first prolonged sync failure).");
this.didReportProlongedError = true;
return true;
}
// We got a 401 mid-sync. Wait for the next sync before actually handling
// an error. This assumes that we'll get a 401 again on a login fetch in
// order to report the error.
if (!this.service.clusterURL) {
this._log.trace("shouldReportError: false (no cluster URL; " +
"possible node reassignment).");
return false;
}
let result = (![Status.login, Status.sync].includes(SERVER_MAINTENANCE) &&
![Status.login, Status.sync].includes(LOGIN_FAILED_NETWORK_ERROR));
this._log.trace("shouldReportError: ${result} due to login=${login}, sync=${sync}",
{result, login: Status.login, sync: Status.sync});
return result;
Svc.Obs.notify("weave:service:reset-file-log");
},
/**

View File

@ -14,8 +14,6 @@ pref("services.sync.scheduler.idleTime", 300); // 5 minutes
pref("services.sync.scheduler.fxa.singleDeviceInterval", 3600); // 1 hour
pref("services.sync.errorhandler.networkFailureReportTimeout", 1209600); // 2 weeks
// Note that new engines are typically added with a default of disabled, so
// when an existing sync user gets the Firefox upgrade that supports the engine
// it starts as disabled until the user has explicitly opted in.

View File

@ -12,8 +12,9 @@ ChromeUtils.import("resource://services-sync/util.js");
ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
var fakeServer = new SyncServer();
const fakeServer = new SyncServer();
fakeServer.start();
const fakeServerUrl = "http://localhost:" + fakeServer.port;
registerCleanupFunction(function() {
return promiseStopServer(fakeServer).finally(() => {
@ -21,25 +22,7 @@ registerCleanupFunction(function() {
});
});
var fakeServerUrl = "http://localhost:" + fakeServer.port;
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
const PROLONGED_ERROR_DURATION =
(Svc.Prefs.get("errorhandler.networkFailureReportTimeout") * 2) * 1000;
const NON_PROLONGED_ERROR_DURATION =
(Svc.Prefs.get("errorhandler.networkFailureReportTimeout") / 2) * 1000;
function setLastSync(lastSyncValue) {
Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString());
}
// This relies on Service/ErrorHandler being a singleton. Fixing this will take
// a lot of work.
let errorHandler = Service.errorHandler;
let engine;
add_task(async function setup() {
await Service.engineManager.clear();
await Service.engineManager.register(EHTestsCommon.CatapultEngine);
@ -52,7 +35,6 @@ async function clean() {
await promiseLogReset;
Status.resetSync();
Status.resetBackoff();
errorHandler.didReportProlongedError = false;
// Move log levels back to trace (startOver will have reversed this), sicne
syncTestLogging();
}
@ -130,259 +112,27 @@ add_task(async function test_credentials_changed_logout() {
await promiseStopServer(server);
});
add_task(function test_no_lastSync_pref() {
syncTestLogging();
// Test reported error.
Status.resetSync();
errorHandler.dontIgnoreErrors = true;
Status.sync = CREDENTIALS_CHANGED;
Assert.ok(errorHandler.shouldReportError());
// Test unreported error.
Status.resetSync();
errorHandler.dontIgnoreErrors = true;
Status.login = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
});
add_task(function test_shouldReportError() {
Status.login = MASTER_PASSWORD_LOCKED;
Assert.ok(!errorHandler.shouldReportError());
// Give ourselves a clusterURL so that the temporary 401 no-error situation
// doesn't come into play.
Service.clusterURL = fakeServerUrl;
// Test dontIgnoreErrors, non-network, non-prolonged, sync error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = CREDENTIALS_CHANGED;
Assert.ok(errorHandler.shouldReportError());
// Test dontIgnoreErrors, non-network, prolonged, sync error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = CREDENTIALS_CHANGED;
Assert.ok(errorHandler.shouldReportError());
// Test dontIgnoreErrors, network, non-prolonged, login error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.login = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
// Test dontIgnoreErrors, network, non-prolonged, sync error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
// Test dontIgnoreErrors, network, prolonged, login error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.login = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
// Test dontIgnoreErrors, network, prolonged, sync error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
// Test non-network, prolonged, sync error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
errorHandler.didReportProlongedError = false;
Status.sync = CREDENTIALS_CHANGED;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(errorHandler.didReportProlongedError);
errorHandler.didReportProlongedError = false;
// Test network, prolonged, login error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.login = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(errorHandler.didReportProlongedError);
errorHandler.didReportProlongedError = false;
// Test network, prolonged, sync error reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(errorHandler.didReportProlongedError);
errorHandler.didReportProlongedError = false;
// Test non-network, non-prolonged, sync error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.sync = CREDENTIALS_CHANGED;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test network, non-prolonged, login error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.login = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(!errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test network, non-prolonged, sync error reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
Assert.ok(!errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test server maintenance, sync errors are not reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.sync = SERVER_MAINTENANCE;
Assert.ok(!errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test server maintenance, login errors are not reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.login = SERVER_MAINTENANCE;
Assert.ok(!errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test prolonged, server maintenance, sync errors are reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.sync = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(errorHandler.didReportProlongedError);
errorHandler.didReportProlongedError = false;
// Test prolonged, server maintenance, login errors are reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = false;
Status.login = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(errorHandler.didReportProlongedError);
errorHandler.didReportProlongedError = false;
// Test dontIgnoreErrors, server maintenance, sync errors are reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
// dontIgnoreErrors means we don't set didReportProlongedError
Assert.ok(!errorHandler.didReportProlongedError);
// Test dontIgnoreErrors, server maintenance, login errors are reported
Status.resetSync();
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.login = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test dontIgnoreErrors, prolonged, server maintenance,
// sync errors are reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.sync = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
// Test dontIgnoreErrors, prolonged, server maintenance,
// login errors are reported
Status.resetSync();
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.dontIgnoreErrors = true;
Status.login = SERVER_MAINTENANCE;
Assert.ok(errorHandler.shouldReportError());
Assert.ok(!errorHandler.didReportProlongedError);
});
add_task(async function test_shouldReportError_master_password() {
_("Test error ignored due to locked master password");
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
// Monkey patch Service.verifyLogin to imitate
// master password being locked.
Service._verifyLogin = Service.verifyLogin;
Service.verifyLogin = async function() {
Status.login = MASTER_PASSWORD_LOCKED;
return false;
};
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
Assert.ok(!errorHandler.shouldReportError());
// Clean up.
Service.verifyLogin = Service._verifyLogin;
await clean();
await promiseStopServer(server);
});
// Test that even if we don't have a cluster URL, a login failure due to
// authentication errors is always reported.
add_task(function test_shouldReportLoginFailureWithNoCluster() {
// Ensure no clusterURL - any error not specific to login should not be reported.
Service.clusterURL = "";
// Test explicit "login rejected" state.
Status.resetSync();
// If we have a LOGIN_REJECTED state, we always report the error.
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
Assert.ok(errorHandler.shouldReportError());
// But any other status with a missing clusterURL is treated as a mid-sync
// 401 (ie, should be treated as a node reassignment)
Status.login = LOGIN_SUCCEEDED;
Assert.ok(!errorHandler.shouldReportError());
});
add_task(async function test_login_syncAndReportErrors_non_network_error() {
add_task(async function test_login_non_network_error() {
enableValidationPrefs();
// Test non-network errors are reported
// when calling syncAndReportErrors
// when calling sync
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
Service.identity._syncKeyBundle = null;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseObserved;
await Service.sync();
Assert.equal(Status.login, LOGIN_FAILED_NO_PASSPHRASE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_sync_syncAndReportErrors_non_network_error() {
add_task(async function test_sync_non_network_error() {
enableValidationPrefs();
// Test non-network errors are reported
// when calling syncAndReportErrors
// when calling sync
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
@ -393,16 +143,12 @@ add_task(async function test_sync_syncAndReportErrors_non_network_error() {
await EHTestsCommon.generateCredentialsChangedFailure();
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
let ping = await wait_for_ping(() => errorHandler.syncAndReportErrors(), true);
let ping = await sync_and_validate_telem(true);
equal(ping.status.sync, CREDENTIALS_CHANGED);
deepEqual(ping.failureReason, {
name: "unexpectederror",
error: "Error: Aborting sync, remote setup failed"
});
await promiseObserved;
Assert.equal(Status.sync, CREDENTIALS_CHANGED);
// If we clean this tick, telemetry won't get the right error
@ -411,219 +157,33 @@ add_task(async function test_sync_syncAndReportErrors_non_network_error() {
await promiseStopServer(server);
});
add_task(async function test_login_syncAndReportErrors_prolonged_non_network_error() {
add_task(async function test_login_sync_network_error() {
enableValidationPrefs();
// Test prolonged, non-network errors are
// reported when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
Service.identity._syncKeyBundle = null;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseObserved;
Assert.equal(Status.login, LOGIN_FAILED_NO_PASSPHRASE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_sync_syncAndReportErrors_prolonged_non_network_error() {
enableValidationPrefs();
// Test prolonged, non-network errors are
// reported when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
// By calling sync, we ensure we're logged in.
await Service.sync();
Assert.equal(Status.sync, SYNC_SUCCEEDED);
Assert.ok(Service.isLoggedIn);
await EHTestsCommon.generateCredentialsChangedFailure();
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
setLastSync(PROLONGED_ERROR_DURATION);
let ping = await wait_for_ping(() => errorHandler.syncAndReportErrors(), true);
equal(ping.status.sync, CREDENTIALS_CHANGED);
deepEqual(ping.failureReason, {
name: "unexpectederror",
error: "Error: Aborting sync, remote setup failed"
});
await promiseObserved;
Assert.equal(Status.sync, CREDENTIALS_CHANGED);
// If we clean this tick, telemetry won't get the right error
await Async.promiseYield();
await clean();
await promiseStopServer(server);
});
add_task(async function test_login_syncAndReportErrors_network_error() {
enableValidationPrefs();
// Test network errors are reported when calling syncAndReportErrors.
// Test network errors are reported when calling sync.
await configureIdentity({username: "broken.wipe"});
Service.clusterURL = fakeServerUrl;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseObserved;
await Service.sync();
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR);
await clean();
});
add_task(async function test_sync_syncAndReportErrors_network_error() {
add_task(async function test_sync_network_error() {
enableValidationPrefs();
// Test network errors are reported when calling syncAndReportErrors.
// Test network errors are reported when calling sync.
Services.io.offline = true;
let promiseUISyncError = promiseOneObserver("weave:ui:sync:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseUISyncError;
await Service.sync();
Assert.equal(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
Services.io.offline = false;
await clean();
});
add_task(async function test_login_syncAndReportErrors_prolonged_network_error() {
enableValidationPrefs();
// Test prolonged, network errors are reported
// when calling syncAndReportErrors.
await configureIdentity({username: "johndoe"});
Service.clusterURL = fakeServerUrl;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseObserved;
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR);
await clean();
});
add_task(async function test_sync_syncAndReportErrors_prolonged_network_error() {
enableValidationPrefs();
// Test prolonged, network errors are reported
// when calling syncAndReportErrors.
Services.io.offline = true;
let promiseUISyncError = promiseOneObserver("weave:ui:sync:error");
setLastSync(PROLONGED_ERROR_DURATION);
errorHandler.syncAndReportErrors();
await promiseUISyncError;
Assert.equal(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
Services.io.offline = false;
await clean();
});
add_task(async function test_login_prolonged_non_network_error() {
enableValidationPrefs();
// Test prolonged, non-network errors are reported
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
Service.identity._syncKeyBundle = null;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_sync_prolonged_non_network_error() {
enableValidationPrefs();
// Test prolonged, non-network errors are reported
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
// By calling sync, we ensure we're logged in.
await Service.sync();
Assert.equal(Status.sync, SYNC_SUCCEEDED);
Assert.ok(Service.isLoggedIn);
await EHTestsCommon.generateCredentialsChangedFailure();
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
setLastSync(PROLONGED_ERROR_DURATION);
let ping = await sync_and_validate_telem(true);
equal(ping.status.sync, PROLONGED_SYNC_FAILURE);
deepEqual(ping.failureReason, {
name: "unexpectederror",
error: "Error: Aborting sync, remote setup failed"
});
await promiseObserved;
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_login_prolonged_network_error() {
enableValidationPrefs();
// Test prolonged, network errors are reported
await configureIdentity({username: "johndoe"});
Service.clusterURL = fakeServerUrl;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
await clean();
});
add_task(async function test_sync_prolonged_network_error() {
enableValidationPrefs();
// Test prolonged, network errors are reported
Services.io.offline = true;
let promiseUISyncError = promiseOneObserver("weave:ui:sync:error");
setLastSync(PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseUISyncError;
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Services.io.offline = false;
await clean();
});
add_task(async function test_login_non_network_error() {
enableValidationPrefs();
@ -632,13 +192,8 @@ add_task(async function test_login_non_network_error() {
await EHTestsCommon.setUp(server);
Service.identity._syncKeyBundle = null;
let promiseObserved = promiseOneObserver("weave:ui:login:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.equal(Status.login, LOGIN_FAILED_NO_PASSPHRASE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
@ -658,13 +213,8 @@ add_task(async function test_sync_non_network_error() {
await EHTestsCommon.generateCredentialsChangedFailure();
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.equal(Status.sync, CREDENTIALS_CHANGED);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
@ -676,14 +226,10 @@ add_task(async function test_login_network_error() {
await configureIdentity({username: "johndoe"});
Service.clusterURL = fakeServerUrl;
let promiseObserved = promiseOneObserver("weave:ui:clear-error");
// Test network errors are not reported.
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.equal(Status.login, LOGIN_FAILED_NETWORK_ERROR);
Assert.ok(!errorHandler.didReportProlongedError);
Services.io.offline = false;
await clean();
@ -695,13 +241,8 @@ add_task(async function test_sync_network_error() {
// Test network errors are not reported.
Services.io.offline = true;
let promiseSyncFinished = promiseOneObserver("weave:ui:sync:finish");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseSyncFinished;
Assert.equal(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
Assert.ok(!errorHandler.didReportProlongedError);
Services.io.offline = false;
await clean();
@ -719,24 +260,14 @@ add_task(async function test_sync_server_maintenance_error() {
engine.exception = {status: 503,
headers: {"retry-after": BACKOFF}};
function onSyncError() {
do_throw("Shouldn't get here!");
}
Svc.Obs.add("weave:ui:sync:error", onSyncError);
Assert.equal(Status.service, STATUS_OK);
let promiseObserved = promiseOneObserver("weave:ui:sync:finish");
setLastSync(NON_PROLONGED_ERROR_DURATION);
let ping = await sync_and_validate_telem(true);
equal(ping.status.sync, SERVER_MAINTENANCE);
deepEqual(ping.engines.find(e => e.failureReason).failureReason, { name: "httperror", code: 503 });
await promiseObserved;
Assert.equal(Status.service, SYNC_FAILED_PARTIAL);
Assert.equal(Status.sync, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
@ -757,27 +288,16 @@ add_task(async function test_info_collections_login_server_maintenance_error() {
backoffInterval = subject;
});
function onUIUpdate() {
do_throw("Shouldn't experience UI update!");
}
Svc.Obs.add("weave:ui:login:error", onUIUpdate);
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
let promiseObserved = promiseOneObserver("weave:ui:clear-error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
await clean();
await promiseStopServer(server);
});
@ -797,27 +317,16 @@ add_task(async function test_meta_global_login_server_maintenance_error() {
backoffInterval = subject;
});
function onUIUpdate() {
do_throw("Shouldn't get here!");
}
Svc.Obs.add("weave:ui:login:error", onUIUpdate);
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
let promiseObserved = promiseOneObserver("weave:ui:clear-error");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await Service.sync();
await promiseObserved;
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
await clean();
await promiseStopServer(server);
});

View File

@ -12,15 +12,16 @@ ChromeUtils.import("resource://services-sync/util.js");
ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
var fakeServer = new SyncServer();
const fakeServer = new SyncServer();
fakeServer.start();
const fakeServerUrl = "http://localhost:" + fakeServer.port;
registerCleanupFunction(function() {
return promiseStopServer(fakeServer);
return promiseStopServer(fakeServer).finally(() => {
Svc.Prefs.resetBranch("");
});
});
var fakeServerUrl = "http://localhost:" + fakeServer.port;
const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
function removeLogFiles() {
@ -40,38 +41,7 @@ function getLogFiles() {
return result;
}
const PROLONGED_ERROR_DURATION =
(Svc.Prefs.get("errorhandler.networkFailureReportTimeout") * 2) * 1000;
const NON_PROLONGED_ERROR_DURATION =
(Svc.Prefs.get("errorhandler.networkFailureReportTimeout") / 2) * 1000;
function setLastSync(lastSyncValue) {
Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString());
}
// This relies on Service/ErrorHandler being a singleton. Fixing this will take
// a lot of work.
var errorHandler = Service.errorHandler;
let engine;
async function syncAndWait(topic) {
let promise1 = promiseOneObserver(topic);
// also wait for the log file to be written
let promise2 = promiseOneObserver("weave:service:reset-file-log");
await Service.sync();
await promise1;
await promise2;
}
async function syncAndReportErrorsAndWait(topic) {
let promise1 = promiseOneObserver(topic);
// also wait for the log file to be written
let promise2 = promiseOneObserver("weave:service:reset-file-log");
errorHandler.syncAndReportErrors();
await promise1;
await promise2;
}
add_task(async function setup() {
await Service.engineManager.clear();
await Service.engineManager.register(EHTestsCommon.CatapultEngine);
@ -84,7 +54,6 @@ async function clean() {
await promiseLogReset;
Status.resetSync();
Status.resetBackoff();
errorHandler.didReportProlongedError = false;
removeLogFiles();
// Move log levels back to trace (startOver will have reversed this), sicne
syncTestLogging();
@ -109,24 +78,34 @@ add_task(async function test_crypto_keys_login_server_maintenance_error() {
backoffInterval = subject;
});
function onUIUpdate() {
do_throw("Shouldn't get here!");
}
Svc.Obs.add("weave:ui:login:error", onUIUpdate);
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:clear-error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
Svc.Obs.remove("weave:ui:login:error", onUIUpdate);
await clean();
await promiseStopServer(server);
});
add_task(async function test_sync_server_maintenance_error() {
enableValidationPrefs();
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "johndoe"}, server);
Assert.equal(Status.service, STATUS_OK);
Assert.equal(Status.sync, SYNC_SUCCEEDED);
Assert.equal(Status.service, SYNC_FAILED_PARTIAL);
Assert.equal(Status.sync, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
@ -166,10 +145,9 @@ add_task(async function test_lastSync_not_updated_on_complete_failure() {
await promiseStopServer(server);
});
add_task(async function test_info_collections_login_prolonged_server_maintenance_error() {
add_task(async function test_info_collections_login_server_maintenance_error() {
enableValidationPrefs();
// Test info/collections prolonged server maintenance errors are reported.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
@ -184,23 +162,20 @@ add_task(async function test_info_collections_login_prolonged_server_maintenance
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:login:error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_meta_global_login_prolonged_server_maintenance_error() {
add_task(async function test_meta_global_login_server_maintenance_error() {
enableValidationPrefs();
// Test meta/global prolonged server maintenance errors are reported.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
@ -215,23 +190,20 @@ add_task(async function test_meta_global_login_prolonged_server_maintenance_erro
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:login:error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_download_crypto_keys_login_prolonged_server_maintenance_error() {
add_task(async function test_download_crypto_keys_login_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys prolonged server maintenance errors are reported.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
@ -248,22 +220,20 @@ add_task(async function test_download_crypto_keys_login_prolonged_server_mainten
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:login:error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_upload_crypto_keys_login_prolonged_server_maintenance_error() {
add_task(async function test_upload_crypto_keys_login_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys prolonged server maintenance errors are reported.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
@ -278,24 +248,20 @@ add_task(async function test_upload_crypto_keys_login_prolonged_server_maintenan
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:login:error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_wipeServer_login_prolonged_server_maintenance_error() {
add_task(async function test_wipeServer_login_server_maintenance_error() {
enableValidationPrefs();
// Test that we report prolonged server maintenance errors that occur whilst
// wiping the server.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
@ -310,27 +276,22 @@ add_task(async function test_wipeServer_login_prolonged_server_maintenance_error
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndWait("weave:ui:login:error");
await Service.sync();
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.ok(errorHandler.didReportProlongedError);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
await clean();
await promiseStopServer(server);
});
add_task(async function test_wipeRemote_prolonged_server_maintenance_error() {
add_task(async function test_wipeRemote_server_maintenance_error() {
enableValidationPrefs();
// Test that we report prolonged server maintenance errors that occur whilst
// wiping all remote devices.
let server = await EHTestsCommon.sync_httpd_setup();
server.registerPathHandler("/1.1/broken.wipe/storage/catapult", EHTestsCommon.service_unavailable);
await configureIdentity({username: "broken.wipe"}, server);
await EHTestsCommon.generateAndUploadKeys();
@ -343,447 +304,18 @@ add_task(async function test_wipeRemote_prolonged_server_maintenance_error() {
backoffInterval = subject;
});
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
Svc.Prefs.set("firstSync", "wipeRemote");
setLastSync(PROLONGED_ERROR_DURATION);
let ping = await sync_and_validate_telem(true);
deepEqual(ping.failureReason, { name: "httperror", code: 503 });
await promiseObserved;
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, PROLONGED_SYNC_FAILURE);
Assert.equal(Svc.Prefs.get("firstSync"), "wipeRemote");
Assert.ok(errorHandler.didReportProlongedError);
await promiseStopServer(server);
await clean();
});
add_task(async function test_sync_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
const BACKOFF = 42;
engine.enabled = true;
engine.exception = {status: 503,
headers: {"retry-after": BACKOFF}};
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:sync:error");
Assert.equal(Status.service, SYNC_FAILED_PARTIAL);
Assert.equal(Status.sync, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_info_collections_login_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test info/collections server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.info"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_meta_global_login_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test meta/global server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.meta"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_download_crypto_keys_login_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.keys"}, server);
// Force re-download of keys
Service.collectionKeys.clear();
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_upload_crypto_keys_login_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
await configureIdentity({username: "broken.keys"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_wipeServer_login_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
await configureIdentity({username: "broken.wipe"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_wipeRemote_syncAndReportErrors_server_maintenance_error() {
enableValidationPrefs();
// Test that we report prolonged server maintenance errors that occur whilst
// wiping all remote devices.
let server = await EHTestsCommon.sync_httpd_setup();
await configureIdentity({username: "broken.wipe"}, server);
await EHTestsCommon.generateAndUploadKeys();
engine.exception = null;
engine.enabled = true;
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
Svc.Prefs.set("firstSync", "wipeRemote");
setLastSync(NON_PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:sync:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, SYNC_FAILED);
Assert.equal(Status.sync, SERVER_MAINTENANCE);
Assert.equal(Svc.Prefs.get("firstSync"), "wipeRemote");
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_sync_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test prolonged server maintenance errors are
// reported when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
const BACKOFF = 42;
engine.enabled = true;
engine.exception = {status: 503,
headers: {"retry-after": BACKOFF}};
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:sync:error");
Assert.equal(Status.service, SYNC_FAILED_PARTIAL);
Assert.equal(Status.sync, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_info_collections_login_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test info/collections server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.info"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_meta_global_login_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test meta/global server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.meta"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_download_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
await EHTestsCommon.setUp(server);
await configureIdentity({username: "broken.keys"}, server);
// Force re-download of keys
Service.collectionKeys.clear();
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_upload_crypto_keys_login_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
await configureIdentity({username: "broken.keys"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
});
add_task(async function test_wipeServer_login_syncAndReportErrors_prolonged_server_maintenance_error() {
enableValidationPrefs();
// Test crypto/keys server maintenance errors are reported
// when calling syncAndReportErrors.
let server = await EHTestsCommon.sync_httpd_setup();
// Start off with an empty account, do not upload a key.
await configureIdentity({username: "broken.wipe"}, server);
let backoffInterval;
Svc.Obs.add("weave:service:backoff:interval", function observe(subject, data) {
Svc.Obs.remove("weave:service:backoff:interval", observe);
backoffInterval = subject;
});
Assert.ok(!Status.enforceBackoff);
Assert.equal(Status.service, STATUS_OK);
setLastSync(PROLONGED_ERROR_DURATION);
await syncAndReportErrorsAndWait("weave:ui:login:error");
Assert.ok(Status.enforceBackoff);
Assert.equal(backoffInterval, 42);
Assert.equal(Status.service, LOGIN_FAILED);
Assert.equal(Status.login, SERVER_MAINTENANCE);
// syncAndReportErrors means dontIgnoreErrors, which means
// didReportProlongedError not touched.
Assert.ok(!errorHandler.didReportProlongedError);
await clean();
await promiseStopServer(server);
@ -845,19 +377,14 @@ add_task(async function test_sync_engine_generic_fail() {
await promiseStopServer(server);
});
add_task(async function test_logs_on_sync_error_despite_shouldReportError() {
add_task(async function test_logs_on_sync_error() {
enableValidationPrefs();
_("Ensure that an error is still logged when weave:service:sync:error " +
"is notified, despite shouldReportError returning false.");
let log = Log.repository.getLogger("Sync.ErrorHandler");
Svc.Prefs.set("log.appender.file.logOnError", true);
log.info("TESTING");
// Ensure that we report no error.
Status.login = MASTER_PASSWORD_LOCKED;
Assert.ok(!errorHandler.shouldReportError());
let promiseObserved = promiseOneObserver("weave:service:reset-file-log");
Svc.Obs.notify("weave:service:sync:error", {});
@ -871,19 +398,14 @@ add_task(async function test_logs_on_sync_error_despite_shouldReportError() {
await clean();
});
add_task(async function test_logs_on_login_error_despite_shouldReportError() {
add_task(async function test_logs_on_login_error() {
enableValidationPrefs();
_("Ensure that an error is still logged when weave:service:login:error " +
"is notified, despite shouldReportError returning false.");
let log = Log.repository.getLogger("Sync.ErrorHandler");
Svc.Prefs.set("log.appender.file.logOnError", true);
log.info("TESTING");
// Ensure that we report no error.
Status.login = MASTER_PASSWORD_LOCKED;
Assert.ok(!errorHandler.shouldReportError());
let promiseObserved = promiseOneObserver("weave:service:reset-file-log");
Svc.Obs.notify("weave:service:login:error", {});

View File

@ -18,15 +18,8 @@ const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
const CLEANUP_DELAY = 2000;
const DELAY_BUFFER = 500; // Buffer for timers on different OS platforms.
const PROLONGED_ERROR_DURATION =
(Svc.Prefs.get("errorhandler.networkFailureReportTimeout") * 2) * 1000;
var errorHandler = Service.errorHandler;
function setLastSync(lastSyncValue) {
Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString());
}
function run_test() {
validate_all_future_pings();
run_next_test();
@ -142,8 +135,7 @@ add_test(function test_sync_error_logOnError_false() {
run_next_test();
});
// Fake an unsuccessful sync due to prolonged failure.
setLastSync(PROLONGED_ERROR_DURATION);
// Fake an unsuccessful sync.
Svc.Obs.notify("weave:service:sync:error");
});
@ -183,8 +175,7 @@ add_test(function test_sync_error_logOnError_true() {
});
});
// Fake an unsuccessful sync due to prolonged failure.
setLastSync(PROLONGED_ERROR_DURATION);
// Fake an unsuccessful sync.
Svc.Obs.notify("weave:service:sync:error");
});
@ -203,8 +194,7 @@ add_test(function test_login_error_logOnError_false() {
run_next_test();
});
// Fake an unsuccessful login due to prolonged failure.
setLastSync(PROLONGED_ERROR_DURATION);
// Fake an unsuccessful login.
Svc.Obs.notify("weave:service:login:error");
});
@ -244,8 +234,7 @@ add_test(function test_login_error_logOnError_true() {
});
});
// Fake an unsuccessful login due to prolonged failure.
setLastSync(PROLONGED_ERROR_DURATION);
// Fake an unsuccessful login.
Svc.Obs.notify("weave:service:login:error");
});
@ -353,8 +342,7 @@ add_test(function test_errorLog_dumpAddons() {
});
});
// Fake an unsuccessful sync due to prolonged failure.
setLastSync(PROLONGED_ERROR_DURATION);
// Fake an unsuccessful sync.
Svc.Obs.notify("weave:service:sync:error");
});

View File

@ -25,13 +25,6 @@ add_task(async function setup() {
// Setup the FxA identity manager and cluster manager.
Status.__authManager = Service.identity = new BrowserIDManager();
// None of the failures in this file should result in a UI error.
function onUIError() {
do_throw("Errors should not be presented in the UI.");
}
Svc.Obs.add("weave:ui:login:error", onUIError);
Svc.Obs.add("weave:ui:sync:error", onUIError);
});

View File

@ -16,13 +16,6 @@ ChromeUtils.import("resource://gre/modules/PromiseUtils.jsm");
add_task(async function setup() {
validate_all_future_pings();
// None of the failures in this file should result in a UI error.
function onUIError() {
do_throw("Errors should not be presented in the UI.");
}
Svc.Obs.add("weave:ui:login:error", onUIError);
Svc.Obs.add("weave:ui:sync:error", onUIError);
});
/**

View File

@ -220,11 +220,8 @@ add_task(async function test_disabledLocally_wipe503() {
Service._ignorePrefObserver = false;
engine.enabled = false;
let promiseObserved = promiseOneObserver("weave:ui:sync:error");
_("Sync.");
Service.errorHandler.syncAndReportErrors();
await promiseObserved;
await Service.sync();
Assert.equal(Service.status.sync, SERVER_MAINTENANCE);
await Service.startOver();

View File

@ -29,7 +29,7 @@
"collection_repair.js": ["getRepairRequestor", "getAllRepairRequestors", "CollectionRepairRequestor", "getRepairResponder", "CollectionRepairResponder"],
"collection_validator.js": ["CollectionValidator", "CollectionProblemData"],
"Console.jsm": ["console", "ConsoleAPI"],
"constants.js": ["WEAVE_VERSION", "SYNC_API_VERSION", "STORAGE_VERSION", "PREFS_BRANCH", "DEFAULT_KEYBUNDLE_NAME", "SYNC_KEY_ENCODED_LENGTH", "SYNC_KEY_DECODED_LENGTH", "NO_SYNC_NODE_INTERVAL", "MAX_ERROR_COUNT_BEFORE_BACKOFF", "MINIMUM_BACKOFF_INTERVAL", "MAXIMUM_BACKOFF_INTERVAL", "HMAC_EVENT_INTERVAL", "MASTER_PASSWORD_LOCKED_RETRY_INTERVAL", "DEFAULT_GUID_FETCH_BATCH_SIZE", "DEFAULT_DOWNLOAD_BATCH_SIZE", "SINGLE_USER_THRESHOLD", "MULTI_DEVICE_THRESHOLD", "SCORE_INCREMENT_SMALL", "SCORE_INCREMENT_MEDIUM", "SCORE_INCREMENT_XLARGE", "SCORE_UPDATE_DELAY", "IDLE_OBSERVER_BACK_DELAY", "URI_LENGTH_MAX", "MAX_HISTORY_UPLOAD", "MAX_HISTORY_DOWNLOAD", "STATUS_OK", "SYNC_FAILED", "LOGIN_FAILED", "SYNC_FAILED_PARTIAL", "CLIENT_NOT_CONFIGURED", "STATUS_DISABLED", "MASTER_PASSWORD_LOCKED", "LOGIN_SUCCEEDED", "SYNC_SUCCEEDED", "ENGINE_SUCCEEDED", "LOGIN_FAILED_NO_USERNAME", "LOGIN_FAILED_NO_PASSPHRASE", "LOGIN_FAILED_NETWORK_ERROR", "LOGIN_FAILED_SERVER_ERROR", "LOGIN_FAILED_INVALID_PASSPHRASE", "LOGIN_FAILED_LOGIN_REJECTED", "METARECORD_DOWNLOAD_FAIL", "VERSION_OUT_OF_DATE", "CREDENTIALS_CHANGED", "ABORT_SYNC_COMMAND", "NO_SYNC_NODE_FOUND", "OVER_QUOTA", "PROLONGED_SYNC_FAILURE", "SERVER_MAINTENANCE", "RESPONSE_OVER_QUOTA", "ENGINE_UPLOAD_FAIL", "ENGINE_DOWNLOAD_FAIL", "ENGINE_UNKNOWN_FAIL", "ENGINE_APPLY_FAIL", "ENGINE_BATCH_INTERRUPTED", "kSyncMasterPasswordLocked", "kSyncWeaveDisabled", "kSyncNetworkOffline", "kSyncBackoffNotMet", "kFirstSyncChoiceNotMade", "kSyncNotConfigured", "kFirefoxShuttingDown", "DEVICE_TYPE_DESKTOP", "DEVICE_TYPE_MOBILE", "SQLITE_MAX_VARIABLE_NUMBER"],
"constants.js": ["WEAVE_VERSION", "SYNC_API_VERSION", "STORAGE_VERSION", "PREFS_BRANCH", "DEFAULT_KEYBUNDLE_NAME", "SYNC_KEY_ENCODED_LENGTH", "SYNC_KEY_DECODED_LENGTH", "NO_SYNC_NODE_INTERVAL", "MAX_ERROR_COUNT_BEFORE_BACKOFF", "MINIMUM_BACKOFF_INTERVAL", "MAXIMUM_BACKOFF_INTERVAL", "HMAC_EVENT_INTERVAL", "MASTER_PASSWORD_LOCKED_RETRY_INTERVAL", "DEFAULT_GUID_FETCH_BATCH_SIZE", "DEFAULT_DOWNLOAD_BATCH_SIZE", "SINGLE_USER_THRESHOLD", "MULTI_DEVICE_THRESHOLD", "SCORE_INCREMENT_SMALL", "SCORE_INCREMENT_MEDIUM", "SCORE_INCREMENT_XLARGE", "SCORE_UPDATE_DELAY", "IDLE_OBSERVER_BACK_DELAY", "URI_LENGTH_MAX", "MAX_HISTORY_UPLOAD", "MAX_HISTORY_DOWNLOAD", "STATUS_OK", "SYNC_FAILED", "LOGIN_FAILED", "SYNC_FAILED_PARTIAL", "CLIENT_NOT_CONFIGURED", "STATUS_DISABLED", "MASTER_PASSWORD_LOCKED", "LOGIN_SUCCEEDED", "SYNC_SUCCEEDED", "ENGINE_SUCCEEDED", "LOGIN_FAILED_NO_USERNAME", "LOGIN_FAILED_NO_PASSPHRASE", "LOGIN_FAILED_NETWORK_ERROR", "LOGIN_FAILED_SERVER_ERROR", "LOGIN_FAILED_INVALID_PASSPHRASE", "LOGIN_FAILED_LOGIN_REJECTED", "METARECORD_DOWNLOAD_FAIL", "VERSION_OUT_OF_DATE", "CREDENTIALS_CHANGED", "ABORT_SYNC_COMMAND", "NO_SYNC_NODE_FOUND", "OVER_QUOTA", "SERVER_MAINTENANCE", "RESPONSE_OVER_QUOTA", "ENGINE_UPLOAD_FAIL", "ENGINE_DOWNLOAD_FAIL", "ENGINE_UNKNOWN_FAIL", "ENGINE_APPLY_FAIL", "ENGINE_BATCH_INTERRUPTED", "kSyncMasterPasswordLocked", "kSyncWeaveDisabled", "kSyncNetworkOffline", "kSyncBackoffNotMet", "kFirstSyncChoiceNotMade", "kSyncNotConfigured", "kFirefoxShuttingDown", "DEVICE_TYPE_DESKTOP", "DEVICE_TYPE_MOBILE", "SQLITE_MAX_VARIABLE_NUMBER"],
"Constants.jsm": ["Roles", "Events", "Relations", "Filters", "States", "Prefilters"],
"ContactDB.jsm": ["ContactDB", "DB_NAME", "STORE_NAME", "SAVED_GETALL_STORE_NAME", "REVISION_STORE", "DB_VERSION"],
"content-server.jsm": ["init"],