mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-06 00:10:25 +00:00
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:
parent
0fad58b24b
commit
304bad1663
@ -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;
|
||||
}
|
||||
|
@ -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"],
|
||||
|
@ -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;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -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.
|
||||
*
|
||||
|
126
services/sync/tests/unit/test_errorhandler.js
Normal file
126
services/sync/tests/unit/test_errorhandler.js
Normal 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();
|
||||
});
|
@ -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");
|
||||
});
|
@ -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() {
|
@ -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("");
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user