From 8dd16259287f58f9273002717ec4d27e97127719 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 12 Jun 2024 07:43:14 +0200 Subject: Merging upstream version 127.0. Signed-off-by: Daniel Baumann --- .../modules/tests/browser/browser_BrowserUtils.js | 33 +- .../browser/file_getSelectionDetails_inputs.html | 7 + toolkit/modules/tests/xpcshell/test_LogManager.js | 377 +++++++++++++++++++++ .../modules/tests/xpcshell/test_MatchURLFilters.js | 4 +- toolkit/modules/tests/xpcshell/test_ProfileAge.js | 31 ++ toolkit/modules/tests/xpcshell/xpcshell.toml | 2 + 6 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 toolkit/modules/tests/xpcshell/test_LogManager.js (limited to 'toolkit/modules/tests') diff --git a/toolkit/modules/tests/browser/browser_BrowserUtils.js b/toolkit/modules/tests/browser/browser_BrowserUtils.js index da28c07b69..de85566d98 100644 --- a/toolkit/modules/tests/browser/browser_BrowserUtils.js +++ b/toolkit/modules/tests/browser/browser_BrowserUtils.js @@ -21,7 +21,7 @@ add_task(async function test_getSelectionDetails_input() { content.getSelection().removeAllRanges(); let info = SelectionUtils.getSelectionDetails(content); Assert.equal(text, info.text); - Assert.ok(!info.collapsed); + Assert.strictEqual(info.docSelectionIsCollapsed, false); Assert.equal(linkURL, info.linkURL); } @@ -48,3 +48,34 @@ add_task(async function test_getSelectionDetails_input() { }); }); }); + +add_task(async function test_getSelectionDetails_shadow_selection() { + const url = kFixtureBaseURL + "file_getSelectionDetails_inputs.html"; + await SpecialPowers.pushPrefEnv({ + set: [["dom.shadowdom.selection_across_boundary.enabled", true]], + }); + await BrowserTestUtils.withNewTab({ gBrowser, url }, async browser => { + await SpecialPowers.spawn(browser, [], async () => { + function checkSelection() { + const { SelectionUtils } = ChromeUtils.importESModule( + "resource://gre/modules/SelectionUtils.sys.mjs" + ); + + const text = content.document.getElementById("outer"); + const host = content.document.getElementById("host"); + content + .getSelection() + .setBaseAndExtent( + text, + 0, + host.shadowRoot.getElementById("inner").firstChild, + 3 + ); + let info = SelectionUtils.getSelectionDetails(content); + // TODO(sefeng): verify info.text after bug 1881095 is fixed + Assert.strictEqual(info.docSelectionIsCollapsed, false); + } + checkSelection(); + }); + }); +}); diff --git a/toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html b/toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html index 2e49146785..a8946ded63 100644 --- a/toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html +++ b/toolkit/modules/tests/browser/file_getSelectionDetails_inputs.html @@ -5,5 +5,12 @@ + + OuterText +
+ +
diff --git a/toolkit/modules/tests/xpcshell/test_LogManager.js b/toolkit/modules/tests/xpcshell/test_LogManager.js new file mode 100644 index 0000000000..fa5e5abc2e --- /dev/null +++ b/toolkit/modules/tests/xpcshell/test_LogManager.js @@ -0,0 +1,377 @@ +/* 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://gre/modules/LogManager.sys.mjs" +); +const { Log } = ChromeUtils.importESModule( + "resource://gre/modules/Log.sys.mjs" +); +const { FileUtils } = ChromeUtils.importESModule( + "resource://gre/modules/FileUtils.sys.mjs" +); +const logManagerDefaultOptions = { + logFileSubDirectoryEntries: ["weave", "logs"], + testTopicPrefix: "services-tests:common:log-manager:", +}; + +// 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({ + ...logManagerDefaultOptions, + prefRoot: "no-such-branch.", + logNames: ["TestLog"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager.test.", + logNames: ["TestLog2"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager-1.test.", + logNames: ["TestLog3"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager-2.test.", + logNames: ["TestLog3"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager.test.", + logNames: ["TestLog2"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager.test.", + logNames: ["TestLog2"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager.test.", + logNames: ["TestLog2"], + logFilePrefix: "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({ + ...logManagerDefaultOptions, + prefRoot: "log-manager.test.", + logNames: ["TestLog2"], + logFilePrefix: "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/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js b/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js index e9e8813b77..7aaee5fece 100644 --- a/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js +++ b/toolkit/modules/tests/xpcshell/test_MatchURLFilters.js @@ -226,14 +226,14 @@ add_task(async function test_match_url_filters() { // TODO: should we explicitly cover hostContains, hostPrefix, hostSuffix for // these sub-cases? { shouldFail, filters: [{ hostEquals: "blank" }], url: "about:blank" }, - { shouldFail, filters: [{ hostEquals: "blank" }], url: "about://blank" }, + { shouldPass, filters: [{ hostEquals: "blank" }], url: "about://blank" }, { shouldFail, filters: [{ hostEquals: "testDataURL" }], url: "data:,testDataURL", }, { shouldPass, filters: [{ hostEquals: "" }], url: "about:blank" }, - { shouldPass, filters: [{ hostEquals: "" }], url: "about://blank" }, + { shouldFail, filters: [{ hostEquals: "" }], url: "about://blank" }, { shouldPass, filters: [{ hostEquals: "" }], url: "data:,testDataURL" }, // Path filters (pathEquals, pathContains, pathPrefix, pathSuffix). diff --git a/toolkit/modules/tests/xpcshell/test_ProfileAge.js b/toolkit/modules/tests/xpcshell/test_ProfileAge.js index 9a659a5894..e717b0dcd0 100644 --- a/toolkit/modules/tests/xpcshell/test_ProfileAge.js +++ b/toolkit/modules/tests/xpcshell/test_ProfileAge.js @@ -38,6 +38,7 @@ add_task( withDummyProfile(async profile => { const CREATED_TIME = Date.now() - 2000; const RESET_TIME = Date.now() - 1000; + const RECOVERY_TIME = Date.now() - 500; await IOUtils.writeJSON(PathUtils.join(profile, "times.json"), { created: CREATED_TIME, @@ -66,12 +67,21 @@ add_task( ); await promise; + let recoveryPromise = times.recordRecoveredFromBackup(RECOVERY_TIME); + Assert.equal( + await times2.recoveredFromBackup, + RECOVERY_TIME, + "Should have seen the right backup recovery time in the second instance immediately." + ); + await recoveryPromise; + let results = await IOUtils.readJSON(PathUtils.join(profile, "times.json")); Assert.deepEqual( results, { created: CREATED_TIME, reset: RESET_TIME, + recoveredFromBackup: RECOVERY_TIME, }, "Should have seen the right results." ); @@ -118,3 +128,24 @@ add_task( ); }) ); + +add_task( + withDummyProfile(async profile => { + const RECOVERY_TIME = Date.now() - 1000; + const RECOVERY_TIME2 = Date.now() - 2000; + + // The last call to recordRecoveredFromBackup should always win. + let times = await ProfileAge(profile); + await Promise.all([ + times.recordRecoveredFromBackup(RECOVERY_TIME), + times.recordRecoveredFromBackup(RECOVERY_TIME2), + ]); + + let results = await IOUtils.readJSON(PathUtils.join(profile, "times.json")); + Assert.equal( + results.recoveredFromBackup, + RECOVERY_TIME2, + "Should have seen the right results." + ); + }) +); diff --git a/toolkit/modules/tests/xpcshell/xpcshell.toml b/toolkit/modules/tests/xpcshell/xpcshell.toml index 52328fc24e..365646c907 100644 --- a/toolkit/modules/tests/xpcshell/xpcshell.toml +++ b/toolkit/modules/tests/xpcshell/xpcshell.toml @@ -63,6 +63,8 @@ tags = "remote-settings" ["test_Log.js"] +["test_LogManager.js"] + ["test_Log_double_ext.js"] ["test_Log_nsIStackFrame.js"] -- cgit v1.2.3