[test] Tests that change the logging level do not work #4234
Labels
a:bug
PMD crashes or fails to analyse a file.
in:testing
About tests of pmd, eg the module pmd-lang-test or pmd-test
Milestone
Affects PMD Version: 7.0.x - because of SLF4J #896
Description:
There are a couple of tests that change the logging level in the pmd 7 branch, to test the
--debug
cli switch for instance:pmd/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java
Line 174 in 1f43af7
I'm afraid this only works by chance... When the trace level is enabled we are supposed to see log statements like
Adding file ...
from the file collector. If you add an assert likeassertThat(log, containsString("Adding file"));
to the linked test you will see that it fails, but only if you run the entire test class (not just the given test).The problem is that when we reinitialize the log level in Slf4jSimpleConfiguration, that doesn't change the log level of loggers that have already been created. This reset routine calls two methods via reflection:
org.slf4j.impl.SimpleLogger#init
: this parses system properties and changes the default logging level of the logger factory, meaning, new loggers will use that log levelorg.slf4j.impl.SimpleLoggerFactory#reset
: this clears theMap<String, Logger>
that caches loggers that have already been created. So the next time egLoggerFactory.getLogger(FileCollector.class)
is called, it will get a new logger with the correct new logging level.The problem is that we create logger instances only once, and then store them in static final fields:
pmd/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java
Line 52 in dd96116
The call to
LoggerFactory
is executed only once in a given VM, and the created logger will use whatever default log level is defined at that point. But if you later change the log level with the reset method, the logger ofFileCollector
will be the same in that static field, and will still use the old log level.This makes it significantly harder to test the behavior of the CLI with this debug flag... Tests are order dependent.
For instance in this test class:
pmd/pmd-java/src/test/java/net/sourceforge/pmd/cli/CLITest.java
Lines 68 to 70 in 29d31ec
This test apparently succeeds, but it's only because by chance, the first test that gets executed in this class uses the
--debug
flag. All other tests then actually observe TRACE and DEBUG level log statements, even those that don't use the--debug
flag. For instance this is the log of thetestWrongRuleset
test in this class, which doesn't use the debug flag:We announce that the log level is INFO, even though the level of other internal loggers actually stayed at TRACE.
Possible solutions
LoggerFactory.getLogger
? This would work but would probably be bad for performance, becausegetLogger
performs a lookup in a ConcurrentMap.SimpleLoggerFactory#reset
and clearing the logger cache, we couldThis third item seems to me like the easiest thing to do... @adangel wdyt?
The text was updated successfully, but these errors were encountered: