Bug 659067 - Part 1: Move error handling and logging from Service to ErrorHandler. r=philikon

--HG--
rename : services/sync/tests/unit/test_service_filelog.js => services/sync/tests/unit/test_errorhandler_filelog.js
rename : services/sync/tests/unit/test_service_sync_checkServerError.js => services/sync/tests/unit/test_errorhandler_sync_checkServerError.js
This commit is contained in:
Marina Samuel 2011-08-26 14:01:35 -07:00
parent 0fad58b24b
commit 304bad1663
9 changed files with 404 additions and 186 deletions

View File

@ -225,7 +225,7 @@ let gSyncUI = {
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup() || Weave.Service.shouldIgnoreError()) {
if (this._needsSetup() || Weave.ErrorHandler.shouldIgnoreError()) {
this.updateUI();
return;
}
@ -352,7 +352,7 @@ let gSyncUI = {
// Ignore network related errors unless we haven't been able to
// sync for a while.
if (Weave.Service.shouldIgnoreError()) {
if (Weave.ErrorHandler.shouldIgnoreError()) {
this.updateUI();
return;
}

View File

@ -52,7 +52,7 @@ let lazies = {
"identity.js": ["Identity", "ID"],
"jpakeclient.js": ["JPAKEClient"],
"notifications.js": ["Notifications", "Notification", "NotificationButton"],
"policies.js": ["SyncScheduler"],
"policies.js": ["SyncScheduler", "ErrorHandler"],
"resource.js": ["Resource", "AsyncResource", "Auth",
"BasicAuthenticator", "NoOpAuthenticator"],
"service.js": ["Service"],

View File

@ -37,9 +37,9 @@
* ***** END LICENSE BLOCK ***** */
const EXPORTED_SYMBOLS = ["SyncScheduler"];
const EXPORTED_SYMBOLS = ["SyncScheduler", "ErrorHandler"];
const Cu = Components.utils;
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/log4moz.js");
@ -413,3 +413,185 @@ let SyncScheduler = {
}
};
const LOG_PREFIX_SUCCESS = "success-";
const LOG_PREFIX_ERROR = "error-";
let ErrorHandler = {
init: function init() {
Svc.Obs.add("weave:service:login:error", this);
Svc.Obs.add("weave:service:sync:error", this);
Svc.Obs.add("weave:service:sync:finish", this);
this.initLogs();
},
initLogs: function initLogs() {
this._log = Log4Moz.repository.getLogger("Sync.ErrorHandler");
this._log.level = Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")];
let root = Log4Moz.repository.getLogger("Sync");
root.level = Log4Moz.Level[Svc.Prefs.get("log.rootLogger")];
let formatter = new Log4Moz.BasicFormatter();
let capp = new Log4Moz.ConsoleAppender(formatter);
capp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.console")];
root.addAppender(capp);
let dapp = new Log4Moz.DumpAppender(formatter);
dapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.dump")];
root.addAppender(dapp);
let fapp = this._logAppender = new Log4Moz.StorageStreamAppender(formatter);
fapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.file.level")];
root.addAppender(fapp);
},
observe: function observe(subject, topic, data) {
switch(topic) {
case "weave:service:login:error":
if (Status.login == LOGIN_FAILED_NETWORK_ERROR &&
!Services.io.offline) {
this._ignorableErrorCount += 1;
} else {
this.resetFileLog(Svc.Prefs.get("log.appender.file.logOnError"),
LOG_PREFIX_ERROR);
}
break;
case "weave:service:sync:error":
switch (Status.sync) {
case LOGIN_FAILED_NETWORK_ERROR:
if (!Services.io.offline) {
this._ignorableErrorCount += 1;
}
break;
case CREDENTIALS_CHANGED:
Weave.Service.logout();
break;
default:
this.resetFileLog(Svc.Prefs.get("log.appender.file.logOnError"),
LOG_PREFIX_ERROR);
break;
}
break;
case "weave:service:sync:finish":
this.resetFileLog(Svc.Prefs.get("log.appender.file.logOnSuccess"),
LOG_PREFIX_SUCCESS);
this._ignorableErrorCount = 0;
break;
}
},
/**
* Generate a log file for the sync that just completed
* and refresh the input & output streams.
*
* @param flushToFile
* the log file to be flushed/reset
*
* @param filenamePrefix
* a value of either LOG_PREFIX_SUCCESS or LOG_PREFIX_ERROR
* to be used as the log filename prefix
*/
resetFileLog: function resetFileLog(flushToFile, filenamePrefix) {
let inStream = this._logAppender.getInputStream();
this._logAppender.reset();
if (flushToFile && inStream) {
try {
let filename = filenamePrefix + Date.now() + ".txt";
let file = FileUtils.getFile("ProfD", ["weave", "logs", filename]);
let outStream = FileUtils.openFileOutputStream(file);
NetUtil.asyncCopy(inStream, outStream, function () {
Svc.Obs.notify("weave:service:reset-file-log");
});
} catch (ex) {
Svc.Obs.notify("weave:service:reset-file-log");
}
} else {
Svc.Obs.notify("weave:service:reset-file-log");
}
},
/**
* 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";
}
},
_ignorableErrorCount: 0,
shouldIgnoreError: function shouldIgnoreError() {
// Never show an error bar for a locked master password.
return (Status.login == MASTER_PASSWORD_LOCKED) ||
([Status.login, Status.sync].indexOf(LOGIN_FAILED_NETWORK_ERROR) != -1
&& this._ignorableErrorCount < MAX_IGNORE_ERROR_COUNT);
},
/**
* Handle HTTP response results or exceptions and set the appropriate
* Status.* bits.
*/
checkServerError: function checkServerError(resp) {
switch (resp.status) {
case 400:
if (resp == RESPONSE_OVER_QUOTA) {
Status.sync = OVER_QUOTA;
}
break;
case 401:
Weave.Service.logout();
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
break;
case 500:
case 502:
case 503:
case 504:
Status.enforceBackoff = true;
if (resp.status == 503 && resp.headers["retry-after"]) {
Svc.Obs.notify("weave:service:backoff:interval",
parseInt(resp.headers["retry-after"], 10));
}
break;
}
switch (resp.result) {
case Cr.NS_ERROR_UNKNOWN_HOST:
case Cr.NS_ERROR_CONNECTION_REFUSED:
case Cr.NS_ERROR_NET_TIMEOUT:
case Cr.NS_ERROR_NET_RESET:
case Cr.NS_ERROR_NET_INTERRUPT:
case Cr.NS_ERROR_PROXY_CONNECTION_REFUSED:
// The constant says it's about login, but in fact it just
// indicates general network error.
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
break;
}
},
};

View File

@ -58,9 +58,6 @@ const KEYS_WBO = "keys";
const LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S";
const LOG_PREFIX_SUCCESS = "success-";
const LOG_PREFIX_ERROR = "error-";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://services-sync/record.js");
Cu.import("resource://services-sync/constants.js");
@ -366,7 +363,12 @@ WeaveSvc.prototype = {
*/
onStartup: function onStartup() {
this._migratePrefs();
this._initLogs();
ErrorHandler.init();
this._log = Log4Moz.repository.getLogger("Sync.Service");
this._log.level =
Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")];
this._log.info("Loading Weave " + WEAVE_VERSION);
this.enabled = true;
@ -384,11 +386,7 @@ WeaveSvc.prototype = {
}
Svc.Obs.add("weave:service:setup-complete", this);
Svc.Obs.add("weave:service:sync:finish", this);
Svc.Obs.add("weave:service:login:error", this);
Svc.Obs.add("weave:service:sync:error", this);
Svc.Obs.add("weave:engine:sync:applied", this);
Svc.Obs.add("weave:resource:status:401", this);
Svc.Prefs.observe("engine.", this);
SyncScheduler.init();
@ -460,47 +458,6 @@ WeaveSvc.prototype = {
Svc.Prefs.set("migrated", true);
},
_initLogs: function WeaveSvc__initLogs() {
this._log = Log4Moz.repository.getLogger("Sync.Service");
this._log.level =
Log4Moz.Level[Svc.Prefs.get("log.logger.service.main")];
let root = Log4Moz.repository.getLogger("Sync");
root.level = Log4Moz.Level[Svc.Prefs.get("log.rootLogger")];
let formatter = new Log4Moz.BasicFormatter();
let capp = new Log4Moz.ConsoleAppender(formatter);
capp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.console")];
root.addAppender(capp);
let dapp = new Log4Moz.DumpAppender(formatter);
dapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.dump")];
root.addAppender(dapp);
let fapp = this._logAppender = new Log4Moz.StorageStreamAppender(formatter);
fapp.level = Log4Moz.Level[Svc.Prefs.get("log.appender.file.level")];
root.addAppender(fapp);
},
_resetFileLog: function _resetFileLog(flushToFile, filenamePrefix) {
let inStream = this._logAppender.getInputStream();
this._logAppender.reset();
if (flushToFile && inStream) {
try {
let filename = filenamePrefix + Date.now() + ".txt";
let file = FileUtils.getFile("ProfD", ["weave", "logs", filename]);
let outStream = FileUtils.openFileOutputStream(file);
NetUtil.asyncCopy(inStream, outStream, function () {
Svc.Obs.notify("weave:service:reset-file-log");
});
} catch (ex) {
Svc.Obs.notify("weave:service:reset-file-log");
}
} else {
Svc.Obs.notify("weave:service:reset-file-log");
}
},
/**
* Register the built-in engines for certain applications
*/
@ -529,36 +486,6 @@ WeaveSvc.prototype = {
if (status != STATUS_DISABLED && status != CLIENT_NOT_CONFIGURED)
Svc.Obs.notify("weave:engine:start-tracking");
break;
case "weave:service:login:error":
if (Status.login == LOGIN_FAILED_NETWORK_ERROR &&
!Services.io.offline) {
this._ignorableErrorCount += 1;
} else {
this._resetFileLog(Svc.Prefs.get("log.appender.file.logOnError"),
LOG_PREFIX_ERROR);
}
break;
case "weave:service:sync:error":
switch (Status.sync) {
case LOGIN_FAILED_NETWORK_ERROR:
if (!Services.io.offline) {
this._ignorableErrorCount += 1;
}
break;
case CREDENTIALS_CHANGED:
this.logout();
break;
default:
this._resetFileLog(Svc.Prefs.get("log.appender.file.logOnError"),
LOG_PREFIX_ERROR);
break;
}
break;
case "weave:service:sync:finish":
this._resetFileLog(Svc.Prefs.get("log.appender.file.logOnSuccess"),
LOG_PREFIX_SUCCESS);
this._ignorableErrorCount = 0;
break;
case "weave:engine:sync:applied":
if (subject.newFailed) {
// An engine isn't able to apply one or more incoming records.
@ -569,9 +496,6 @@ WeaveSvc.prototype = {
this._log.debug(data + " failed to apply some records.");
}
break;
case "weave:resource:status:401":
this._handleResource401(subject);
break;
case "nsPref:changed":
if (this._ignorePrefObserver)
return;
@ -603,7 +527,7 @@ WeaveSvc.prototype = {
switch (node.status) {
case 400:
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
fail = "Find cluster denied: " + this._errorStr(node);
fail = "Find cluster denied: " + ErrorHandler.errorStr(node);
break;
case 404:
this._log.debug("Using serverURL as data cluster (multi-cluster support disabled)");
@ -666,11 +590,11 @@ WeaveSvc.prototype = {
try {
info = new Resource(infoURL).get();
} catch (ex) {
this._checkServerError(ex);
ErrorHandler.checkServerError(ex);
throw ex;
}
if (!info.success) {
this._checkServerError(info);
ErrorHandler.checkServerError(info);
throw "aborting sync, failed to get collections";
}
return info;
@ -885,7 +809,7 @@ WeaveSvc.prototype = {
default:
// Server didn't respond with something that we expected
this._checkServerError(test);
ErrorHandler.checkServerError(test);
Status.login = LOGIN_FAILED_SERVER_ERROR;
return false;
}
@ -1099,31 +1023,6 @@ WeaveSvc.prototype = {
Svc.Obs.notify("weave:service:logout:finish");
},
_errorStr: function WeaveSvc__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";
}
},
checkAccount: function checkAccount(account) {
let username = this._usernameFromAccount(account);
let url = this.userAPI + username;
@ -1144,7 +1043,7 @@ WeaveSvc.prototype = {
catch(ex) {}
// Convert to the error string, or default to generic on exception.
return this._errorStr(data);
return ErrorHandler.errorStr(data);
},
createAccount: function createAccount(email, password,
@ -1176,7 +1075,7 @@ WeaveSvc.prototype = {
// Must have failed, so figure out the reason
if (register.status == 400)
error = this._errorStr(register);
error = ErrorHandler.errorStr(register);
}
catch(ex) {
this._log.warn("Failed to create account: " + ex);
@ -1248,7 +1147,7 @@ WeaveSvc.prototype = {
// abort the server wipe if the GET status was anything other than 404 or 200
let status = Records.response.status;
if (status != 200 && status != 404) {
this._checkServerError(Records.response);
ErrorHandler.checkServerError(Records.response);
Status.sync = METARECORD_DOWNLOAD_FAIL;
this._log.warn("Unknown error while downloading metadata record. " +
"Aborting sync.");
@ -1361,14 +1260,6 @@ WeaveSvc.prototype = {
return reason;
},
_ignorableErrorCount: 0,
shouldIgnoreError: function shouldIgnoreError() {
// Never show an error bar for a locked master password.
return (Status.login == MASTER_PASSWORD_LOCKED) ||
([Status.login, Status.sync].indexOf(LOGIN_FAILED_NETWORK_ERROR) != -1
&& this._ignorableErrorCount < MAX_IGNORE_ERROR_COUNT);
},
sync: function sync() {
let dateStr = new Date().toLocaleFormat(LOG_DATE_FORMAT);
this._log.debug("User-Agent: " + SyncStorageRequest.prototype.userAgent);
@ -1611,7 +1502,7 @@ WeaveSvc.prototype = {
return false;
}
this._checkServerError(e);
ErrorHandler.checkServerError(e);
Status.engines = [engine.name, e.failureCode || ENGINE_UNKNOWN_FAIL];
@ -1700,49 +1591,6 @@ WeaveSvc.prototype = {
this.generateNewSymmetricKeys();
},
/**
* Handle HTTP response results or exceptions and set the appropriate
* Status.* bits.
*/
_checkServerError: function WeaveSvc__checkServerError(resp) {
switch (resp.status) {
case 400:
if (resp == RESPONSE_OVER_QUOTA) {
Status.sync = OVER_QUOTA;
}
break;
case 401:
this.logout();
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
break;
case 500:
case 502:
case 503:
case 504:
Status.enforceBackoff = true;
if (resp.status == 503 && resp.headers["retry-after"]) {
Svc.Obs.notify("weave:service:backoff:interval",
parseInt(resp.headers["retry-after"], 10));
}
break;
}
switch (resp.result) {
case Cr.NS_ERROR_UNKNOWN_HOST:
case Cr.NS_ERROR_CONNECTION_REFUSED:
case Cr.NS_ERROR_NET_TIMEOUT:
case Cr.NS_ERROR_NET_RESET:
case Cr.NS_ERROR_NET_INTERRUPT:
case Cr.NS_ERROR_PROXY_CONNECTION_REFUSED:
// The constant says it's about login, but in fact it just
// indicates general network error.
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
break;
}
},
/**
* Wipe user data from the server.
*

View File

@ -0,0 +1,126 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://services-sync/engines/clients.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/status.js");
Svc.DefaultPrefs.set("registerEngines", "");
Cu.import("resource://services-sync/service.js");
function run_test() {
initTestLogging("Trace");
Log4Moz.repository.getLogger("Sync.Service").level = Log4Moz.Level.Trace;
Log4Moz.repository.getLogger("Sync.SyncScheduler").level = Log4Moz.Level.Trace;
run_next_test();
}
function sync_httpd_setup() {
let global = new ServerWBO("global", {
syncID: Service.syncID,
storageVersion: STORAGE_VERSION,
engines: {clients: {version: Clients.version,
syncID: Clients.syncID}}
});
let clientsColl = new ServerCollection({}, true);
// Tracking info/collections.
let collectionsHelper = track_collections_helper();
let upd = collectionsHelper.with_updated_collection;
let handler_401 = httpd_handler(401, "Unauthorized");
return httpd_setup({
"/1.1/johndoe/storage/meta/global": upd("meta", global.handler()),
"/1.1/johndoe/info/collections": collectionsHelper.handler,
"/1.1/johndoe/storage/crypto/keys":
upd("crypto", (new ServerWBO("keys")).handler()),
"/1.1/johndoe/storage/clients": upd("clients", clientsColl.handler()),
"/1.1/janedoe/storage/meta/global": handler_401,
"/1.1/janedoe/info/collections": handler_401,
});
}
function setUp() {
Service.username = "johndoe";
Service.password = "ilovejane";
Service.passphrase = "abcdeabcdeabcdeabcdeabcdea";
Service.clusterURL = "http://localhost:8080/";
generateNewKeys();
let serverKeys = CollectionKeys.asWBO("crypto", "keys");
serverKeys.encrypt(Service.syncKeyBundle);
return serverKeys.upload(Service.cryptoKeysURL);
}
add_test(function test_401_logout() {
let server = sync_httpd_setup();
setUp();
// By calling sync, we ensure we're logged in.
Service.sync();
do_check_eq(Status.sync, SYNC_SUCCEEDED);
do_check_true(Service.isLoggedIn);
// Make sync fail due to login rejected.
Service.username = "janedoe";
Service.sync();
do_check_eq(Status.login, LOGIN_FAILED_LOGIN_REJECTED);
do_check_false(Service.isLoggedIn);
// Clean up.
Service.startOver();
server.stop(run_next_test);
});
add_test(function test_credentials_changed_logout() {
let server = sync_httpd_setup();
setUp();
// By calling sync, we ensure we're logged in.
Service.sync();
do_check_eq(Status.sync, SYNC_SUCCEEDED);
do_check_true(Service.isLoggedIn);
// Make sync fail due to changed credentials. We simply re-encrypt
// the keys with a different Sync Key, without changing the local one.
let newSyncKeyBundle = new SyncKeyBundle(PWDMGR_PASSPHRASE_REALM, Service.username);
newSyncKeyBundle.keyStr = "23456234562345623456234562";
let keys = CollectionKeys.asWBO();
keys.encrypt(newSyncKeyBundle);
keys.upload(Service.cryptoKeysURL);
Service.sync();
do_check_eq(Status.sync, CREDENTIALS_CHANGED);
do_check_false(Service.isLoggedIn);
// Clean up.
Service.startOver();
server.stop(run_next_test);
});
add_test(function test_shouldIgnoreError() {
Status.login = MASTER_PASSWORD_LOCKED;
Status.sync = LOGIN_FAILED_NETWORK_ERROR;
// Error ignored since master password locked.
do_check_true(ErrorHandler.shouldIgnoreError());
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
Status.sync = LOGIN_FAILED_NETWORK_ERROR
// Error ignored due to network error.
do_check_true(ErrorHandler.shouldIgnoreError());
Status.login = LOGIN_FAILED_LOGIN_REJECTED;
Status.sync = NO_SYNC_NODE_FOUND;
// Error not ignored.
do_check_false(ErrorHandler.shouldIgnoreError());
run_next_test();
});

View File

@ -100,7 +100,7 @@ add_test(function test_logOnSuccess_true() {
Svc.Obs.notify("weave:service:sync:finish");
});
add_test(function test_logOnError_false() {
add_test(function test_sync_error_logOnError_false() {
Svc.Prefs.set("log.appender.file.logOnError", false);
let log = Log4Moz.repository.getLogger("Sync.Test.FileLog");
@ -119,7 +119,7 @@ add_test(function test_logOnError_false() {
Svc.Obs.notify("weave:service:sync:error");
});
add_test(function test_logOnError_true() {
add_test(function test_sync_error_logOnError_true() {
Svc.Prefs.set("log.appender.file.logOnError", true);
let log = Log4Moz.repository.getLogger("Sync.Test.FileLog");
@ -159,3 +159,63 @@ add_test(function test_logOnError_true() {
// Fake an unsuccessful sync.
Svc.Obs.notify("weave:service:sync:error");
});
add_test(function test_login_error_logOnError_false() {
Svc.Prefs.set("log.appender.file.logOnError", false);
let log = Log4Moz.repository.getLogger("Sync.Test.FileLog");
log.info("this won't show up");
Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
// No log file was written.
do_check_false(logsdir.directoryEntries.hasMoreElements());
Svc.Prefs.resetBranch("");
run_next_test();
});
// Fake an unsuccessful login.
Svc.Obs.notify("weave:service:login:error");
});
add_test(function test_login_error_logOnError_true() {
Svc.Prefs.set("log.appender.file.logOnError", true);
let log = Log4Moz.repository.getLogger("Sync.Test.FileLog");
const MESSAGE = "this WILL show up";
log.info(MESSAGE);
Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
// Exactly one log file was written.
let entries = logsdir.directoryEntries;
do_check_true(entries.hasMoreElements());
let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile);
do_check_eq(logfile.leafName.slice(-4), ".txt");
do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length),
LOG_PREFIX_ERROR);
do_check_false(entries.hasMoreElements());
// Ensure the log message was actually written to file.
readFile(logfile, function (error, data) {
do_check_true(Components.isSuccessCode(error));
do_check_neq(data.indexOf(MESSAGE), -1);
// Clean up.
try {
logfile.remove(false);
} catch(ex) {
dump("Couldn't delete file: " + ex + "\n");
// Stupid Windows box.
}
Svc.Prefs.resetBranch("");
run_next_test();
});
});
// Fake an unsuccessful sync.
Svc.Obs.notify("weave:service:login:error");
});

View File

@ -1,6 +1,7 @@
Cu.import("resource://services-sync/engines.js");
Cu.import("resource://services-sync/status.js");
Cu.import("resource://services-sync/constants.js");
Cu.import("resource://services-sync/policies.js");
Cu.import("resource://services-sync/util.js");
Svc.DefaultPrefs.set("registerEngines", "");
@ -151,7 +152,7 @@ add_test(function test_service_networkError() {
setUp();
// Provoke connection refused.
Service.clusterURL = "http://localhost:12345/";
Service._ignorableErrorCount = 0;
ErrorHandler._ignorableErrorCount = 0;
try {
do_check_eq(Status.sync, SYNC_SUCCEEDED);
@ -160,7 +161,7 @@ add_test(function test_service_networkError() {
Service.sync();
do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
do_check_eq(Service._ignorableErrorCount, 1);
do_check_eq(ErrorHandler._ignorableErrorCount, 1);
} finally {
Status.resetSync();
Service.startOver();
@ -172,7 +173,7 @@ add_test(function test_service_offline() {
_("Test: Wanting to sync in offline mode leads to the right status code but does not increment the ignorable error count.");
setUp();
Services.io.offline = true;
Service._ignorableErrorCount = 0;
ErrorHandler._ignorableErrorCount = 0;
try {
do_check_eq(Status.sync, SYNC_SUCCEEDED);
@ -181,7 +182,7 @@ add_test(function test_service_offline() {
Service.sync();
do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
do_check_eq(Service._ignorableErrorCount, 0);
do_check_eq(ErrorHandler._ignorableErrorCount, 0);
} finally {
Status.resetSync();
Service.startOver();
@ -194,7 +195,7 @@ add_test(function test_service_reset_ignorableErrorCount() {
_("Test: Successful sync resets the ignorable error count.");
setUp();
let server = sync_httpd_setup();
Service._ignorableErrorCount = 10;
ErrorHandler._ignorableErrorCount = 10;
// Disable the engine so that sync completes.
let engine = Engines.get("catapult");
@ -209,7 +210,7 @@ add_test(function test_service_reset_ignorableErrorCount() {
Service.sync();
do_check_eq(Status.sync, SYNC_SUCCEEDED);
do_check_eq(Service._ignorableErrorCount, 0);
do_check_eq(ErrorHandler._ignorableErrorCount, 0);
} finally {
Status.resetSync();
Service.startOver();
@ -221,7 +222,7 @@ add_test(function test_engine_networkError() {
_("Test: Network related exceptions from engine.sync() lead to the right status code.");
setUp();
let server = sync_httpd_setup();
Service._ignorableErrorCount = 0;
ErrorHandler._ignorableErrorCount = 0;
let engine = Engines.get("catapult");
engine.enabled = true;
@ -237,7 +238,7 @@ add_test(function test_engine_networkError() {
Service.sync();
do_check_eq(Status.sync, LOGIN_FAILED_NETWORK_ERROR);
do_check_eq(Service._ignorableErrorCount, 1);
do_check_eq(ErrorHandler._ignorableErrorCount, 1);
} finally {
Status.resetSync();
Service.startOver();
@ -273,7 +274,7 @@ add_test(function test_resource_timeout() {
// Slightly misplaced test as it doesn't actually test checkServerError,
// but the observer for "weave:engine:sync:apply-failed".
// but the observer for "weave:engine:sync:applied".
// This test should be the last one since it monkeypatches the engine object
// and we should only have one engine object throughout the file (bug 629664).
add_test(function test_engine_applyFailed() {

View File

@ -29,10 +29,10 @@ add_test(function test_offline() {
try {
_("The right bits are set when we're offline.");
Services.io.offline = true;
do_check_eq(Service._ignorableErrorCount, 0);
do_check_eq(ErrorHandler._ignorableErrorCount, 0);
do_check_false(!!Service.login());
do_check_eq(Status.login, LOGIN_FAILED_NETWORK_ERROR);
do_check_eq(Service._ignorableErrorCount, 0);
do_check_eq(ErrorHandler._ignorableErrorCount, 0);
Services.io.offline = false;
} finally {
Svc.Prefs.resetBranch("");

View File

@ -25,6 +25,9 @@ tail =
[test_engine.js]
[test_engine_abort.js]
[test_enginemanager.js]
[test_errorhandler.js]
[test_errorhandler_filelog.js]
[test_errorhandler_sync_checkServerError.js]
[test_forms_store.js]
[test_forms_tracker.js]
[test_history_engine.js]
@ -59,7 +62,6 @@ skip-if = os == "win" || os == "android"
[test_service_cluster.js]
[test_service_createAccount.js]
[test_service_detect_upgrade.js]
[test_service_filelog.js]
# Bug 664090: this test persistently fails on Windows opt builds.
# Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
skip-if = (os == "win" && !debug) || os == "android"
@ -71,7 +73,6 @@ skip-if = (os == "win" && !debug) || os == "android"
[test_service_startOver.js]
[test_service_startup.js]
[test_service_sync_401.js]
[test_service_sync_checkServerError.js]
# Bug 604565: this test intermittently hangs on OS X debug builds.
# Bug 676978: test hangs on Android (see also testing/xpcshell/xpcshell.ini)
skip-if = (os == "mac" && debug) || os == "android"