services/sync/tests/unit/test_errorhandler_filelog.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 Cu.import("resource://gre/modules/Log.jsm");
michael@0 5 Cu.import("resource://services-common/utils.js");
michael@0 6 Cu.import("resource://services-sync/service.js");
michael@0 7 Cu.import("resource://services-sync/util.js");
michael@0 8 Cu.import("resource://gre/modules/FileUtils.jsm");
michael@0 9 Cu.import("resource://gre/modules/NetUtil.jsm");
michael@0 10
michael@0 11 const logsdir = FileUtils.getDir("ProfD", ["weave", "logs"], true);
michael@0 12 const LOG_PREFIX_SUCCESS = "success-";
michael@0 13 const LOG_PREFIX_ERROR = "error-";
michael@0 14
michael@0 15 // Delay to wait before cleanup, to allow files to age.
michael@0 16 // This is so large because the file timestamp granularity is per-second, and
michael@0 17 // so otherwise we can end up with all of our files -- the ones we want to
michael@0 18 // keep, and the ones we want to clean up -- having the same modified time.
michael@0 19 const CLEANUP_DELAY = 2000;
michael@0 20 const DELAY_BUFFER = 500; // Buffer for timers on different OS platforms.
michael@0 21
michael@0 22 const PROLONGED_ERROR_DURATION =
michael@0 23 (Svc.Prefs.get('errorhandler.networkFailureReportTimeout') * 2) * 1000;
michael@0 24
michael@0 25 let errorHandler = Service.errorHandler;
michael@0 26
michael@0 27 function setLastSync(lastSyncValue) {
michael@0 28 Svc.Prefs.set("lastSync", (new Date(Date.now() - lastSyncValue)).toString());
michael@0 29 }
michael@0 30
michael@0 31 function run_test() {
michael@0 32 initTestLogging("Trace");
michael@0 33
michael@0 34 Log.repository.getLogger("Sync.Service").level = Log.Level.Trace;
michael@0 35 Log.repository.getLogger("Sync.SyncScheduler").level = Log.Level.Trace;
michael@0 36 Log.repository.getLogger("Sync.ErrorHandler").level = Log.Level.Trace;
michael@0 37
michael@0 38 run_next_test();
michael@0 39 }
michael@0 40
michael@0 41 add_test(function test_noOutput() {
michael@0 42 // Ensure that the log appender won't print anything.
michael@0 43 errorHandler._logAppender.level = Log.Level.Fatal + 1;
michael@0 44
michael@0 45 // Clear log output from startup.
michael@0 46 Svc.Prefs.set("log.appender.file.logOnSuccess", false);
michael@0 47 Svc.Obs.notify("weave:service:sync:finish");
michael@0 48
michael@0 49 // Clear again without having issued any output.
michael@0 50 Svc.Prefs.set("log.appender.file.logOnSuccess", true);
michael@0 51
michael@0 52 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 53 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 54
michael@0 55 errorHandler._logAppender.level = Log.Level.Trace;
michael@0 56 Svc.Prefs.resetBranch("");
michael@0 57 run_next_test();
michael@0 58 });
michael@0 59
michael@0 60 // Fake a successful sync.
michael@0 61 Svc.Obs.notify("weave:service:sync:finish");
michael@0 62 });
michael@0 63
michael@0 64 add_test(function test_logOnSuccess_false() {
michael@0 65 Svc.Prefs.set("log.appender.file.logOnSuccess", false);
michael@0 66
michael@0 67 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 68 log.info("this won't show up");
michael@0 69
michael@0 70 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 71 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 72 // No log file was written.
michael@0 73 do_check_false(logsdir.directoryEntries.hasMoreElements());
michael@0 74
michael@0 75 Svc.Prefs.resetBranch("");
michael@0 76 run_next_test();
michael@0 77 });
michael@0 78
michael@0 79 // Fake a successful sync.
michael@0 80 Svc.Obs.notify("weave:service:sync:finish");
michael@0 81 });
michael@0 82
michael@0 83 function readFile(file, callback) {
michael@0 84 NetUtil.asyncFetch(file, function (inputStream, statusCode, request) {
michael@0 85 let data = NetUtil.readInputStreamToString(inputStream,
michael@0 86 inputStream.available());
michael@0 87 callback(statusCode, data);
michael@0 88 });
michael@0 89 }
michael@0 90
michael@0 91 add_test(function test_logOnSuccess_true() {
michael@0 92 Svc.Prefs.set("log.appender.file.logOnSuccess", true);
michael@0 93
michael@0 94 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 95 const MESSAGE = "this WILL show up";
michael@0 96 log.info(MESSAGE);
michael@0 97
michael@0 98 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 99 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 100
michael@0 101 // Exactly one log file was written.
michael@0 102 let entries = logsdir.directoryEntries;
michael@0 103 do_check_true(entries.hasMoreElements());
michael@0 104 let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile);
michael@0 105 do_check_eq(logfile.leafName.slice(-4), ".txt");
michael@0 106 do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_SUCCESS.length),
michael@0 107 LOG_PREFIX_SUCCESS);
michael@0 108 do_check_false(entries.hasMoreElements());
michael@0 109
michael@0 110 // Ensure the log message was actually written to file.
michael@0 111 readFile(logfile, function (error, data) {
michael@0 112 do_check_true(Components.isSuccessCode(error));
michael@0 113 do_check_neq(data.indexOf(MESSAGE), -1);
michael@0 114
michael@0 115 // Clean up.
michael@0 116 try {
michael@0 117 logfile.remove(false);
michael@0 118 } catch(ex) {
michael@0 119 dump("Couldn't delete file: " + ex + "\n");
michael@0 120 // Stupid Windows box.
michael@0 121 }
michael@0 122
michael@0 123 Svc.Prefs.resetBranch("");
michael@0 124 run_next_test();
michael@0 125 });
michael@0 126 });
michael@0 127
michael@0 128 // Fake a successful sync.
michael@0 129 Svc.Obs.notify("weave:service:sync:finish");
michael@0 130 });
michael@0 131
michael@0 132 add_test(function test_sync_error_logOnError_false() {
michael@0 133 Svc.Prefs.set("log.appender.file.logOnError", false);
michael@0 134
michael@0 135 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 136 log.info("this won't show up");
michael@0 137
michael@0 138 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 139 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 140 // No log file was written.
michael@0 141 do_check_false(logsdir.directoryEntries.hasMoreElements());
michael@0 142
michael@0 143 Svc.Prefs.resetBranch("");
michael@0 144 run_next_test();
michael@0 145 });
michael@0 146
michael@0 147 // Fake an unsuccessful sync due to prolonged failure.
michael@0 148 setLastSync(PROLONGED_ERROR_DURATION);
michael@0 149 Svc.Obs.notify("weave:service:sync:error");
michael@0 150 });
michael@0 151
michael@0 152 add_test(function test_sync_error_logOnError_true() {
michael@0 153 Svc.Prefs.set("log.appender.file.logOnError", true);
michael@0 154
michael@0 155 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 156 const MESSAGE = "this WILL show up";
michael@0 157 log.info(MESSAGE);
michael@0 158
michael@0 159 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 160 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 161
michael@0 162 // Exactly one log file was written.
michael@0 163 let entries = logsdir.directoryEntries;
michael@0 164 do_check_true(entries.hasMoreElements());
michael@0 165 let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile);
michael@0 166 do_check_eq(logfile.leafName.slice(-4), ".txt");
michael@0 167 do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length),
michael@0 168 LOG_PREFIX_ERROR);
michael@0 169 do_check_false(entries.hasMoreElements());
michael@0 170
michael@0 171 // Ensure the log message was actually written to file.
michael@0 172 readFile(logfile, function (error, data) {
michael@0 173 do_check_true(Components.isSuccessCode(error));
michael@0 174 do_check_neq(data.indexOf(MESSAGE), -1);
michael@0 175
michael@0 176 // Clean up.
michael@0 177 try {
michael@0 178 logfile.remove(false);
michael@0 179 } catch(ex) {
michael@0 180 dump("Couldn't delete file: " + ex + "\n");
michael@0 181 // Stupid Windows box.
michael@0 182 }
michael@0 183
michael@0 184 Svc.Prefs.resetBranch("");
michael@0 185 run_next_test();
michael@0 186 });
michael@0 187 });
michael@0 188
michael@0 189 // Fake an unsuccessful sync due to prolonged failure.
michael@0 190 setLastSync(PROLONGED_ERROR_DURATION);
michael@0 191 Svc.Obs.notify("weave:service:sync:error");
michael@0 192 });
michael@0 193
michael@0 194 add_test(function test_login_error_logOnError_false() {
michael@0 195 Svc.Prefs.set("log.appender.file.logOnError", false);
michael@0 196
michael@0 197 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 198 log.info("this won't show up");
michael@0 199
michael@0 200 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 201 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 202 // No log file was written.
michael@0 203 do_check_false(logsdir.directoryEntries.hasMoreElements());
michael@0 204
michael@0 205 Svc.Prefs.resetBranch("");
michael@0 206 run_next_test();
michael@0 207 });
michael@0 208
michael@0 209 // Fake an unsuccessful login due to prolonged failure.
michael@0 210 setLastSync(PROLONGED_ERROR_DURATION);
michael@0 211 Svc.Obs.notify("weave:service:login:error");
michael@0 212 });
michael@0 213
michael@0 214 add_test(function test_login_error_logOnError_true() {
michael@0 215 Svc.Prefs.set("log.appender.file.logOnError", true);
michael@0 216
michael@0 217 let log = Log.repository.getLogger("Sync.Test.FileLog");
michael@0 218 const MESSAGE = "this WILL show up";
michael@0 219 log.info(MESSAGE);
michael@0 220
michael@0 221 Svc.Obs.add("weave:service:reset-file-log", function onResetFileLog() {
michael@0 222 Svc.Obs.remove("weave:service:reset-file-log", onResetFileLog);
michael@0 223
michael@0 224 // Exactly one log file was written.
michael@0 225 let entries = logsdir.directoryEntries;
michael@0 226 do_check_true(entries.hasMoreElements());
michael@0 227 let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile);
michael@0 228 do_check_eq(logfile.leafName.slice(-4), ".txt");
michael@0 229 do_check_eq(logfile.leafName.slice(0, LOG_PREFIX_ERROR.length),
michael@0 230 LOG_PREFIX_ERROR);
michael@0 231 do_check_false(entries.hasMoreElements());
michael@0 232
michael@0 233 // Ensure the log message was actually written to file.
michael@0 234 readFile(logfile, function (error, data) {
michael@0 235 do_check_true(Components.isSuccessCode(error));
michael@0 236 do_check_neq(data.indexOf(MESSAGE), -1);
michael@0 237
michael@0 238 // Clean up.
michael@0 239 try {
michael@0 240 logfile.remove(false);
michael@0 241 } catch(ex) {
michael@0 242 dump("Couldn't delete file: " + ex + "\n");
michael@0 243 // Stupid Windows box.
michael@0 244 }
michael@0 245
michael@0 246 Svc.Prefs.resetBranch("");
michael@0 247 run_next_test();
michael@0 248 });
michael@0 249 });
michael@0 250
michael@0 251 // Fake an unsuccessful login due to prolonged failure.
michael@0 252 setLastSync(PROLONGED_ERROR_DURATION);
michael@0 253 Svc.Obs.notify("weave:service:login:error");
michael@0 254 });
michael@0 255
michael@0 256 // Check that error log files are deleted above an age threshold.
michael@0 257 add_test(function test_logErrorCleanup_age() {
michael@0 258 _("Beginning test_logErrorCleanup_age.");
michael@0 259 let maxAge = CLEANUP_DELAY / 1000;
michael@0 260 let oldLogs = [];
michael@0 261 let numLogs = 10;
michael@0 262 let errString = "some error log\n";
michael@0 263
michael@0 264 Svc.Prefs.set("log.appender.file.logOnError", true);
michael@0 265 Svc.Prefs.set("log.appender.file.maxErrorAge", maxAge);
michael@0 266
michael@0 267 _("Making some files.");
michael@0 268 for (let i = 0; i < numLogs; i++) {
michael@0 269 let now = Date.now();
michael@0 270 let filename = LOG_PREFIX_ERROR + now + "" + i + ".txt";
michael@0 271 let newLog = FileUtils.getFile("ProfD", ["weave", "logs", filename]);
michael@0 272 let foStream = FileUtils.openFileOutputStream(newLog);
michael@0 273 foStream.write(errString, errString.length);
michael@0 274 foStream.close();
michael@0 275 _(" > Created " + filename);
michael@0 276 oldLogs.push(newLog.leafName);
michael@0 277 }
michael@0 278
michael@0 279 Svc.Obs.add("weave:service:cleanup-logs", function onCleanupLogs() {
michael@0 280 Svc.Obs.remove("weave:service:cleanup-logs", onCleanupLogs);
michael@0 281
michael@0 282 // Only the newest created log file remains.
michael@0 283 let entries = logsdir.directoryEntries;
michael@0 284 do_check_true(entries.hasMoreElements());
michael@0 285 let logfile = entries.getNext().QueryInterface(Ci.nsILocalFile);
michael@0 286 do_check_true(oldLogs.every(function (e) {
michael@0 287 return e != logfile.leafName;
michael@0 288 }));
michael@0 289 do_check_false(entries.hasMoreElements());
michael@0 290
michael@0 291 // Clean up.
michael@0 292 try {
michael@0 293 logfile.remove(false);
michael@0 294 } catch(ex) {
michael@0 295 dump("Couldn't delete file: " + ex + "\n");
michael@0 296 // Stupid Windows box.
michael@0 297 }
michael@0 298
michael@0 299 Svc.Prefs.resetBranch("");
michael@0 300 run_next_test();
michael@0 301 });
michael@0 302
michael@0 303 let delay = CLEANUP_DELAY + DELAY_BUFFER;
michael@0 304
michael@0 305 _("Cleaning up logs after " + delay + "msec.");
michael@0 306 CommonUtils.namedTimer(function onTimer() {
michael@0 307 Svc.Obs.notify("weave:service:sync:error");
michael@0 308 }, delay, this, "cleanup-timer");
michael@0 309 });

mercurial