summaryrefslogtreecommitdiffstats
path: root/services/common
diff options
context:
space:
mode:
Diffstat (limited to 'services/common')
-rw-r--r--services/common/logmanager.sys.mjs447
-rw-r--r--services/common/moz.build1
-rw-r--r--services/common/tests/unit/test_load_modules.js8
-rw-r--r--services/common/tests/unit/test_logmanager.js330
-rw-r--r--services/common/tests/unit/xpcshell.toml2
5 files changed, 2 insertions, 786 deletions
diff --git a/services/common/logmanager.sys.mjs b/services/common/logmanager.sys.mjs
deleted file mode 100644
index 724cfde38b..0000000000
--- a/services/common/logmanager.sys.mjs
+++ /dev/null
@@ -1,447 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-"use strict;";
-
-import { Log } from "resource://gre/modules/Log.sys.mjs";
-
-const lazy = {};
-
-ChromeUtils.defineESModuleGetters(lazy, {
- FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
- NetUtil: "resource://gre/modules/NetUtil.sys.mjs",
-});
-
-const DEFAULT_MAX_ERROR_AGE = 20 * 24 * 60 * 60; // 20 days
-
-// "shared" logs (ie, where the same log name is used by multiple LogManager
-// instances) are a fact of life here - eg, FirefoxAccounts logs are used by
-// both Sync and Reading List.
-// However, different instances have different pref branches, so we need to
-// handle when one pref branch says "Debug" and the other says "Error"
-// So we (a) keep singleton console and dump appenders and (b) keep track
-// of the minimum (ie, most verbose) level and use that.
-// This avoids (a) the most recent setter winning (as that is indeterminate)
-// and (b) multiple dump/console appenders being added to the same log multiple
-// times, which would cause messages to appear twice.
-
-// Singletons used by each instance.
-var formatter;
-var dumpAppender;
-var consoleAppender;
-
-// A set of all preference roots used by all instances.
-var allBranches = new Set();
-
-const STREAM_SEGMENT_SIZE = 4096;
-const PR_UINT32_MAX = 0xffffffff;
-
-/**
- * Append to an nsIStorageStream
- *
- * This writes logging output to an in-memory stream which can later be read
- * back as an nsIInputStream. It can be used to avoid expensive I/O operations
- * during logging. Instead, one can periodically consume the input stream and
- * e.g. write it to disk asynchronously.
- */
-class StorageStreamAppender extends Log.Appender {
- constructor(formatter) {
- super(formatter);
- this._name = "StorageStreamAppender";
-
- this._converterStream = null; // holds the nsIConverterOutputStream
- this._outputStream = null; // holds the underlying nsIOutputStream
-
- this._ss = null;
- }
-
- get outputStream() {
- if (!this._outputStream) {
- // First create a raw stream. We can bail out early if that fails.
- this._outputStream = this.newOutputStream();
- if (!this._outputStream) {
- return null;
- }
-
- // Wrap the raw stream in an nsIConverterOutputStream. We can reuse
- // the instance if we already have one.
- if (!this._converterStream) {
- this._converterStream = Cc[
- "@mozilla.org/intl/converter-output-stream;1"
- ].createInstance(Ci.nsIConverterOutputStream);
- }
- this._converterStream.init(this._outputStream, "UTF-8");
- }
- return this._converterStream;
- }
-
- newOutputStream() {
- let ss = (this._ss = Cc["@mozilla.org/storagestream;1"].createInstance(
- Ci.nsIStorageStream
- ));
- ss.init(STREAM_SEGMENT_SIZE, PR_UINT32_MAX, null);
- return ss.getOutputStream(0);
- }
-
- getInputStream() {
- if (!this._ss) {
- return null;
- }
- return this._ss.newInputStream(0);
- }
-
- reset() {
- if (!this._outputStream) {
- return;
- }
- this.outputStream.close();
- this._outputStream = null;
- this._ss = null;
- }
-
- doAppend(formatted) {
- if (!formatted) {
- return;
- }
- try {
- this.outputStream.writeString(formatted + "\n");
- } catch (ex) {
- if (ex.result == Cr.NS_BASE_STREAM_CLOSED) {
- // The underlying output stream is closed, so let's open a new one
- // and try again.
- this._outputStream = null;
- }
- try {
- this.outputStream.writeString(formatted + "\n");
- } catch (ex) {
- // Ah well, we tried, but something seems to be hosed permanently.
- }
- }
- }
-}
-
-// A storage appender that is flushable to a file on disk. Policies for
-// when to flush, to what file, log rotation etc are up to the consumer
-// (although it does maintain a .sawError property to help the consumer decide
-// based on its policies)
-class FlushableStorageAppender extends StorageStreamAppender {
- constructor(formatter) {
- super(formatter);
- this.sawError = false;
- }
-
- append(message) {
- if (message.level >= Log.Level.Error) {
- this.sawError = true;
- }
- StorageStreamAppender.prototype.append.call(this, message);
- }
-
- reset() {
- super.reset();
- this.sawError = false;
- }
-
- // Flush the current stream to a file. Somewhat counter-intuitively, you
- // must pass a log which will be written to with details of the operation.
- async flushToFile(subdirArray, filename, log) {
- let inStream = this.getInputStream();
- this.reset();
- if (!inStream) {
- log.debug("Failed to flush log to a file - no input stream");
- return;
- }
- log.debug("Flushing file log");
- log.trace("Beginning stream copy to " + filename + ": " + Date.now());
- try {
- await this._copyStreamToFile(inStream, subdirArray, filename, log);
- log.trace("onCopyComplete", Date.now());
- } catch (ex) {
- log.error("Failed to copy log stream to file", ex);
- }
- }
-
- /**
- * Copy an input stream to the named file, doing everything off the main
- * thread.
- * subDirArray is an array of path components, relative to the profile
- * directory, where the file will be created.
- * outputFileName is the filename to create.
- * Returns a promise that is resolved on completion or rejected with an error.
- */
- async _copyStreamToFile(inputStream, subdirArray, outputFileName, log) {
- let outputDirectory = PathUtils.join(PathUtils.profileDir, ...subdirArray);
- await IOUtils.makeDirectory(outputDirectory);
- let fullOutputFileName = PathUtils.join(outputDirectory, outputFileName);
-
- let outputStream = Cc[
- "@mozilla.org/network/file-output-stream;1"
- ].createInstance(Ci.nsIFileOutputStream);
-
- outputStream.init(
- new lazy.FileUtils.File(fullOutputFileName),
- -1,
- -1,
- Ci.nsIFileOutputStream.DEFER_OPEN
- );
-
- await new Promise(resolve =>
- lazy.NetUtil.asyncCopy(inputStream, outputStream, () => resolve())
- );
-
- outputStream.close();
- log.trace("finished copy to", fullOutputFileName);
- }
-}
-
-// The public LogManager object.
-export function LogManager(prefRoot, logNames, logFilePrefix) {
- this._prefObservers = [];
- this.init(prefRoot, logNames, logFilePrefix);
-}
-
-LogManager.StorageStreamAppender = StorageStreamAppender;
-
-LogManager.prototype = {
- _cleaningUpFileLogs: false,
-
- init(prefRoot, logNames, logFilePrefix) {
- this._prefs = Services.prefs.getBranch(prefRoot);
- this._prefsBranch = prefRoot;
-
- this.logFilePrefix = logFilePrefix;
- if (!formatter) {
- // Create a formatter and various appenders to attach to the logs.
- formatter = new Log.BasicFormatter();
- consoleAppender = new Log.ConsoleAppender(formatter);
- dumpAppender = new Log.DumpAppender(formatter);
- }
-
- allBranches.add(this._prefsBranch);
- // We create a preference observer for all our prefs so they are magically
- // reflected if the pref changes after creation.
- let setupAppender = (
- appender,
- prefName,
- defaultLevel,
- findSmallest = false
- ) => {
- let observer = newVal => {
- let level = Log.Level[newVal] || defaultLevel;
- if (findSmallest) {
- // As some of our appenders have global impact (ie, there is only one
- // place 'dump' goes to), we need to find the smallest value from all
- // prefs controlling this appender.
- // For example, if consumerA has dump=Debug then consumerB sets
- // dump=Error, we need to keep dump=Debug so consumerA is respected.
- for (let branch of allBranches) {
- let lookPrefBranch = Services.prefs.getBranch(branch);
- let lookVal =
- Log.Level[lookPrefBranch.getStringPref(prefName, null)];
- if (lookVal && lookVal < level) {
- level = lookVal;
- }
- }
- }
- appender.level = level;
- };
- this._prefs.addObserver(prefName, observer);
- this._prefObservers.push([prefName, observer]);
- // and call the observer now with the current pref value.
- observer(this._prefs.getStringPref(prefName, null));
- return observer;
- };
-
- this._observeConsolePref = setupAppender(
- consoleAppender,
- "log.appender.console",
- Log.Level.Fatal,
- true
- );
- this._observeDumpPref = setupAppender(
- dumpAppender,
- "log.appender.dump",
- Log.Level.Error,
- true
- );
-
- // The file appender doesn't get the special singleton behaviour.
- let fapp = (this._fileAppender = new FlushableStorageAppender(formatter));
- // the stream gets a default of Debug as the user must go out of their way
- // to see the stuff spewed to it.
- this._observeStreamPref = setupAppender(
- fapp,
- "log.appender.file.level",
- Log.Level.Debug
- );
-
- // now attach the appenders to all our logs.
- for (let logName of logNames) {
- let log = Log.repository.getLogger(logName);
- for (let appender of [fapp, dumpAppender, consoleAppender]) {
- log.addAppender(appender);
- }
- }
- // and use the first specified log as a "root" for our log.
- this._log = Log.repository.getLogger(logNames[0] + ".LogManager");
- },
-
- /**
- * Cleanup this instance
- */
- finalize() {
- for (let [prefName, observer] of this._prefObservers) {
- this._prefs.removeObserver(prefName, observer);
- }
- this._prefObservers = [];
- try {
- allBranches.delete(this._prefsBranch);
- } catch (e) {}
- this._prefs = null;
- },
-
- get _logFileSubDirectoryEntries() {
- // At this point we don't allow a custom directory for the logs, nor allow
- // it to be outside the profile directory.
- // This returns an array of the the relative directory entries below the
- // profile dir, and is the directory about:sync-log uses.
- return ["weave", "logs"];
- },
-
- get sawError() {
- return this._fileAppender.sawError;
- },
-
- // Result values for resetFileLog.
- SUCCESS_LOG_WRITTEN: "success-log-written",
- ERROR_LOG_WRITTEN: "error-log-written",
-
- /**
- * Possibly generate a log file for all accumulated log messages and refresh
- * the input & output streams.
- * Whether a "success" or "error" log is written is determined based on
- * whether an "Error" log entry was written to any of the logs.
- * Returns a promise that resolves on completion with either null (for no
- * file written or on error), SUCCESS_LOG_WRITTEN if a "success" log was
- * written, or ERROR_LOG_WRITTEN if an "error" log was written.
- */
- async resetFileLog() {
- try {
- let flushToFile;
- let reasonPrefix;
- let reason;
- if (this._fileAppender.sawError) {
- reason = this.ERROR_LOG_WRITTEN;
- flushToFile = this._prefs.getBoolPref(
- "log.appender.file.logOnError",
- true
- );
- reasonPrefix = "error";
- } else {
- reason = this.SUCCESS_LOG_WRITTEN;
- flushToFile = this._prefs.getBoolPref(
- "log.appender.file.logOnSuccess",
- false
- );
- reasonPrefix = "success";
- }
-
- // might as well avoid creating an input stream if we aren't going to use it.
- if (!flushToFile) {
- this._fileAppender.reset();
- return null;
- }
-
- // We have reasonPrefix at the start of the filename so all "error"
- // logs are grouped in about:sync-log.
- let filename =
- reasonPrefix + "-" + this.logFilePrefix + "-" + Date.now() + ".txt";
- await this._fileAppender.flushToFile(
- this._logFileSubDirectoryEntries,
- filename,
- this._log
- );
- // It's not completely clear to markh why we only do log cleanups
- // for errors, but for now the Sync semantics have been copied...
- // (one theory is that only cleaning up on error makes it less
- // likely old error logs would be removed, but that's not true if
- // there are occasional errors - let's address this later!)
- if (reason == this.ERROR_LOG_WRITTEN && !this._cleaningUpFileLogs) {
- this._log.trace("Running cleanup.");
- try {
- await this.cleanupLogs();
- } catch (err) {
- this._log.error("Failed to cleanup logs", err);
- }
- }
- return reason;
- } catch (ex) {
- this._log.error("Failed to resetFileLog", ex);
- return null;
- }
- },
-
- /**
- * Finds all logs older than maxErrorAge and deletes them using async I/O.
- */
- cleanupLogs() {
- let maxAge = this._prefs.getIntPref(
- "log.appender.file.maxErrorAge",
- DEFAULT_MAX_ERROR_AGE
- );
- let threshold = Date.now() - 1000 * maxAge;
- this._log.debug("Log cleanup threshold time: " + threshold);
-
- let shouldDelete = fileInfo => {
- return fileInfo.lastModified < threshold;
- };
- return this._deleteLogFiles(shouldDelete);
- },
-
- /**
- * Finds all logs and removes them.
- */
- removeAllLogs() {
- return this._deleteLogFiles(() => true);
- },
-
- // Delete some log files. A callback is invoked for each found log file to
- // determine if that file should be removed.
- async _deleteLogFiles(cbShouldDelete) {
- this._cleaningUpFileLogs = true;
- let logDir = lazy.FileUtils.getDir(
- "ProfD",
- this._logFileSubDirectoryEntries
- );
- for (const path of await IOUtils.getChildren(logDir.path)) {
- const name = PathUtils.filename(path);
-
- if (!name.startsWith("error-") && !name.startsWith("success-")) {
- continue;
- }
-
- try {
- const info = await IOUtils.stat(path);
- if (!cbShouldDelete(info)) {
- continue;
- }
-
- this._log.trace(` > Cleanup removing ${name} (${info.lastModified})`);
- await IOUtils.remove(path);
- this._log.trace(`Deleted ${name}`);
- } catch (ex) {
- this._log.debug(
- `Encountered error trying to clean up old log file ${name}`,
- ex
- );
- }
- }
- this._cleaningUpFileLogs = false;
- this._log.debug("Done deleting files.");
- // This notification is used only for tests.
- Services.obs.notifyObservers(
- null,
- "services-tests:common:log-manager:cleanup-logs"
- );
- },
-};
diff --git a/services/common/moz.build b/services/common/moz.build
index 144ccaff04..42c5431de8 100644
--- a/services/common/moz.build
+++ b/services/common/moz.build
@@ -22,7 +22,6 @@ EXTRA_JS_MODULES["services-common"] += [
"kinto-http-client.sys.mjs",
"kinto-offline-client.sys.mjs",
"kinto-storage-adapter.sys.mjs",
- "logmanager.sys.mjs",
"observers.sys.mjs",
"rest.sys.mjs",
"uptake-telemetry.sys.mjs",
diff --git a/services/common/tests/unit/test_load_modules.js b/services/common/tests/unit/test_load_modules.js
index d86165266f..f188acb4f5 100644
--- a/services/common/tests/unit/test_load_modules.js
+++ b/services/common/tests/unit/test_load_modules.js
@@ -6,12 +6,7 @@ const { AppConstants } = ChromeUtils.importESModule(
);
const MODULE_BASE = "resource://services-common/";
-const shared_modules = [
- "async.sys.mjs",
- "logmanager.sys.mjs",
- "rest.sys.mjs",
- "utils.sys.mjs",
-];
+const shared_modules = ["async.sys.mjs", "rest.sys.mjs", "utils.sys.mjs"];
const non_android_modules = ["tokenserverclient.sys.mjs"];
@@ -51,6 +46,7 @@ function expectImportsToFail(mm, base = MODULE_BASE) {
function run_test() {
expectImportsToSucceed(shared_modules);
expectImportsToSucceed(shared_test_modules, TEST_BASE);
+ expectImportsToSucceed(["LogManager.sys.mjs"], "resource://gre/modules/");
if (AppConstants.platform != "android") {
expectImportsToSucceed(non_android_modules);
diff --git a/services/common/tests/unit/test_logmanager.js b/services/common/tests/unit/test_logmanager.js
deleted file mode 100644
index 89ac274e61..0000000000
--- a/services/common/tests/unit/test_logmanager.js
+++ /dev/null
@@ -1,330 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ */
-
-// NOTE: The sync test_errorhandler_* tests have quite good coverage for
-// other aspects of this.
-
-const { LogManager } = ChromeUtils.importESModule(
- "resource://services-common/logmanager.sys.mjs"
-);
-const { FileUtils } = ChromeUtils.importESModule(
- "resource://gre/modules/FileUtils.sys.mjs"
-);
-
-// Returns an array of [consoleAppender, dumpAppender, [fileAppenders]] for
-// the specified log. Note that fileAppenders will usually have length=1
-function getAppenders(log) {
- let capps = log.appenders.filter(app => app instanceof Log.ConsoleAppender);
- equal(capps.length, 1, "should only have one console appender");
- let dapps = log.appenders.filter(app => app instanceof Log.DumpAppender);
- equal(dapps.length, 1, "should only have one dump appender");
- let fapps = log.appenders.filter(
- app => app instanceof LogManager.StorageStreamAppender
- );
- return [capps[0], dapps[0], fapps];
-}
-
-// Test that the correct thing happens when no prefs exist for the log manager.
-add_task(async function test_noPrefs() {
- // tell the log manager to init with a pref branch that doesn't exist.
- let lm = new LogManager("no-such-branch.", ["TestLog"], "test");
-
- let log = Log.repository.getLogger("TestLog");
- let [capp, dapp, fapps] = getAppenders(log);
- // The console appender gets "Fatal" while the "dump" appender gets "Error" levels
- equal(capp.level, Log.Level.Fatal);
- equal(dapp.level, Log.Level.Error);
- // and the file (stream) appender gets Debug by default
- equal(fapps.length, 1, "only 1 file appender");
- equal(fapps[0].level, Log.Level.Debug);
- lm.finalize();
-});
-
-// Test that changes to the prefs used by the log manager are updated dynamically.
-add_task(async function test_PrefChanges() {
- Services.prefs.setStringPref(
- "log-manager.test.log.appender.console",
- "Trace"
- );
- Services.prefs.setStringPref("log-manager.test.log.appender.dump", "Trace");
- Services.prefs.setStringPref(
- "log-manager.test.log.appender.file.level",
- "Trace"
- );
- let lm = new LogManager("log-manager.test.", ["TestLog2"], "test");
-
- let log = Log.repository.getLogger("TestLog2");
- let [capp, dapp, [fapp]] = getAppenders(log);
- equal(capp.level, Log.Level.Trace);
- equal(dapp.level, Log.Level.Trace);
- equal(fapp.level, Log.Level.Trace);
- // adjust the prefs and they should magically be reflected in the appenders.
- Services.prefs.setStringPref(
- "log-manager.test.log.appender.console",
- "Debug"
- );
- Services.prefs.setStringPref("log-manager.test.log.appender.dump", "Debug");
- Services.prefs.setStringPref(
- "log-manager.test.log.appender.file.level",
- "Debug"
- );
- equal(capp.level, Log.Level.Debug);
- equal(dapp.level, Log.Level.Debug);
- equal(fapp.level, Log.Level.Debug);
- // and invalid values should cause them to fallback to their defaults.
- Services.prefs.setStringPref("log-manager.test.log.appender.console", "xxx");
- Services.prefs.setStringPref("log-manager.test.log.appender.dump", "xxx");
- Services.prefs.setStringPref(
- "log-manager.test.log.appender.file.level",
- "xxx"
- );
- equal(capp.level, Log.Level.Fatal);
- equal(dapp.level, Log.Level.Error);
- equal(fapp.level, Log.Level.Debug);
- lm.finalize();
-});
-
-// Test that the same log used by multiple log managers does the right thing.
-add_task(async function test_SharedLogs() {
- // create the prefs for the first instance.
- Services.prefs.setStringPref(
- "log-manager-1.test.log.appender.console",
- "Trace"
- );
- Services.prefs.setStringPref("log-manager-1.test.log.appender.dump", "Trace");
- Services.prefs.setStringPref(
- "log-manager-1.test.log.appender.file.level",
- "Trace"
- );
- let lm1 = new LogManager("log-manager-1.test.", ["TestLog3"], "test");
-
- // and the second.
- Services.prefs.setStringPref(
- "log-manager-2.test.log.appender.console",
- "Debug"
- );
- Services.prefs.setStringPref("log-manager-2.test.log.appender.dump", "Debug");
- Services.prefs.setStringPref(
- "log-manager-2.test.log.appender.file.level",
- "Debug"
- );
- let lm2 = new LogManager("log-manager-2.test.", ["TestLog3"], "test");
-
- let log = Log.repository.getLogger("TestLog3");
- let [capp, dapp] = getAppenders(log);
-
- // console and dump appenders should be "trace" as it is more verbose than
- // "debug"
- equal(capp.level, Log.Level.Trace);
- equal(dapp.level, Log.Level.Trace);
-
- // Set the prefs on the -1 branch to "Error" - it should then end up with
- // "Debug" from the -2 branch.
- Services.prefs.setStringPref(
- "log-manager-1.test.log.appender.console",
- "Error"
- );
- Services.prefs.setStringPref("log-manager-1.test.log.appender.dump", "Error");
- Services.prefs.setStringPref(
- "log-manager-1.test.log.appender.file.level",
- "Error"
- );
-
- equal(capp.level, Log.Level.Debug);
- equal(dapp.level, Log.Level.Debug);
-
- lm1.finalize();
- lm2.finalize();
-});
-
-// A little helper to test what log files exist. We expect exactly zero (if
-// prefix is null) or exactly one with the specified prefix.
-function checkLogFile(prefix) {
- let logsdir = FileUtils.getDir("ProfD", ["weave", "logs"]);
- let entries = logsdir.directoryEntries;
- if (!prefix) {
- // expecting no files.
- ok(!entries.hasMoreElements());
- } else {
- // expecting 1 file.
- ok(entries.hasMoreElements());
- let logfile = entries.getNext().QueryInterface(Ci.nsIFile);
- equal(logfile.leafName.slice(-4), ".txt");
- ok(logfile.leafName.startsWith(prefix + "-test-"), logfile.leafName);
- // and remove it ready for the next check.
- logfile.remove(false);
- }
-}
-
-// Test that we correctly write error logs by default
-add_task(async function test_logFileErrorDefault() {
- let lm = new LogManager("log-manager.test.", ["TestLog2"], "test");
-
- let log = Log.repository.getLogger("TestLog2");
- log.error("an error message");
- await lm.resetFileLog(lm.REASON_ERROR);
- // One error log file exists.
- checkLogFile("error");
-
- lm.finalize();
-});
-
-// Test that we correctly write success logs.
-add_task(async function test_logFileSuccess() {
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnError",
- false
- );
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- false
- );
-
- let lm = new LogManager("log-manager.test.", ["TestLog2"], "test");
-
- let log = Log.repository.getLogger("TestLog2");
- log.info("an info message");
- await lm.resetFileLog();
- // Zero log files exist.
- checkLogFile(null);
-
- // Reset logOnSuccess and do it again - log should appear.
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- true
- );
- log.info("an info message");
- await lm.resetFileLog();
-
- checkLogFile("success");
-
- // Now test with no "reason" specified and no "error" record.
- log.info("an info message");
- await lm.resetFileLog();
- // should get a "success" entry.
- checkLogFile("success");
-
- // With no "reason" and an error record - should get no success log.
- log.error("an error message");
- await lm.resetFileLog();
- // should get no entry
- checkLogFile(null);
-
- // And finally now with no error, to ensure that the fact we had an error
- // previously doesn't persist after the .resetFileLog call.
- log.info("an info message");
- await lm.resetFileLog();
- checkLogFile("success");
-
- lm.finalize();
-});
-
-// Test that we correctly write error logs.
-add_task(async function test_logFileError() {
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnError",
- false
- );
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- false
- );
-
- let lm = new LogManager("log-manager.test.", ["TestLog2"], "test");
-
- let log = Log.repository.getLogger("TestLog2");
- log.info("an info message");
- let reason = await lm.resetFileLog();
- Assert.equal(reason, null, "null returned when no file created.");
- // Zero log files exist.
- checkLogFile(null);
-
- // Reset logOnSuccess - success logs should appear if no error records.
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- true
- );
- log.info("an info message");
- reason = await lm.resetFileLog();
- Assert.equal(reason, lm.SUCCESS_LOG_WRITTEN);
- checkLogFile("success");
-
- // Set logOnError and unset logOnSuccess - error logs should appear.
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- false
- );
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnError",
- true
- );
- log.error("an error message");
- reason = await lm.resetFileLog();
- Assert.equal(reason, lm.ERROR_LOG_WRITTEN);
- checkLogFile("error");
-
- // Now test with no "error" record.
- log.info("an info message");
- reason = await lm.resetFileLog();
- // should get no file
- Assert.equal(reason, null);
- checkLogFile(null);
-
- // With an error record we should get an error log.
- log.error("an error message");
- reason = await lm.resetFileLog();
- // should get en error log
- Assert.equal(reason, lm.ERROR_LOG_WRITTEN);
- checkLogFile("error");
-
- // And finally now with success, to ensure that the fact we had an error
- // previously doesn't persist after the .resetFileLog call.
- log.info("an info message");
- await lm.resetFileLog();
- checkLogFile(null);
-
- lm.finalize();
-});
-
-function countLogFiles() {
- let logsdir = FileUtils.getDir("ProfD", ["weave", "logs"]);
- let count = 0;
- for (let entry of logsdir.directoryEntries) {
- void entry;
- count += 1;
- }
- return count;
-}
-
-// Test that removeAllLogs removes all log files.
-add_task(async function test_logFileError() {
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnError",
- true
- );
- Services.prefs.setBoolPref(
- "log-manager.test.log.appender.file.logOnSuccess",
- true
- );
-
- let lm = new LogManager("log-manager.test.", ["TestLog2"], "test");
-
- let log = Log.repository.getLogger("TestLog2");
- log.info("an info message");
- let reason = await lm.resetFileLog();
- Assert.equal(reason, lm.SUCCESS_LOG_WRITTEN, "success log was written.");
-
- log.error("an error message");
- reason = await lm.resetFileLog();
- Assert.equal(reason, lm.ERROR_LOG_WRITTEN);
-
- Assert.equal(countLogFiles(), 2, "expect 2 log files");
- await lm.removeAllLogs();
- Assert.equal(
- countLogFiles(),
- 0,
- "should be no log files after removing them"
- );
-
- lm.finalize();
-});
diff --git a/services/common/tests/unit/xpcshell.toml b/services/common/tests/unit/xpcshell.toml
index e4035f66b2..35c10dfce3 100644
--- a/services/common/tests/unit/xpcshell.toml
+++ b/services/common/tests/unit/xpcshell.toml
@@ -20,8 +20,6 @@ tags = "blocklist"
["test_load_modules.js"]
-["test_logmanager.js"]
-
["test_observers.js"]
["test_restrequest.js"]