Skip to content

KAFKA-18834: Fix LoggingResourceTest#testSetLevelDefaultScope #19920

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

apalan60
Copy link
Contributor

@apalan60 apalan60 commented Jun 7, 2025

Jira: KAFKA-18834

  • Flaky behavior
    LoggingResourceTest#testSetLevelDefaultScope sometimes fails by not
    capturing its expected WARN log.

  • Root cause
    Both LoggersTest#testSetLevelWithValidRootLoggerNames and
    LoggingResourceTest#testSetLevelDefaultScope may share the same
    LoggerContext when executed in the same JVM.
    LoggersTest#testSetLevelWithValidRootLoggerNames calls
    loggers.setLevel("", ERROR), which mutates the global root logger
    level to ERROR and suppresses WARN logs, which causes subsequent tests
    to fail to emit WARN-level output.

  • Fix in this PR
    Resets the Log4j configuration after each test in LoggersTest,
    ensuring that any global changes are reverted.

Reviewers: Chia-Ping Tsai chia7712@gmail.com

@github-actions github-actions bot added triage PRs from the community connect tests Test fixes (including flaky tests) small Small PRs labels Jun 7, 2025
@apalan60
Copy link
Contributor Author

apalan60 commented Jun 7, 2025

Verified that this change resolves the issue by running the following command:

./gradlew cleanTest \
  connect:runtime:test \
  --tests LoggersTest.testSetLevelWithValidRootLoggerNames \
  --tests LoggingResourceTest.testSetLevelDefaultScope \
  -PmaxParallelForks=1

Both tests passed successfully:
LoggersTest#testSetLevelWithValidRootLoggerNames
LoggingResourceTest#testSetLevelDefaultScope

Test Results
kafka on  KAFKA-18834-Fix-LoggingResourceTest#testSetLevelDefaultScope- [$!] …
➜ ./gradlew cleanTest \
  connect:runtime:test \
    --tests LoggersTest.testSetLevelWithValidRootLoggerNames \
    --tests LoggingResourceTest.testSetLevelDefaultScope \
    -PmaxParallelForks=1 \

> Configure project :
Starting build with version 4.1.0-SNAPSHOT (commit id 82ea9d0f) using Gradle 8.14.1, Java 21 and Scala 2.13.16
Build properties: ignoreFailures=false, maxParallelForks=1, maxScalacThreads=8, maxTestRetries=0
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

> Task :connect:runtime:test

Gradle Test Run :connect:runtime:test > Gradle Test Executor 19 > LoggersTest > testSetLevelWithValidRootLoggerNames() PASSED

Gradle Test Run :connect:runtime:test > Gradle Test Executor 19 > LoggingResourceTest > testSetLevelDefaultScope() PASSED

BUILD SUCCESSFUL in 2s
153 actionable tasks: 2 executed, 151 up-to-date


@AfterEach
public void teardown() {
Configurator.setAllLevels(LogManager.ROOT_LOGGER_NAME, originalRootLevel);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes all 'child' loggers, right? If so, it is not a kind of restoring logger levels

Copy link
Contributor Author

@apalan60 apalan60 Jun 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chia7712
Thank you for catching this!

After rethinking the solution, I confirmed that calling setLevel in LoggersTest will overwrite every child loggers (see [1]). That means any test in LoggersTest that invokes setLevel risks leaking its changes into other test classes.

Instead of recording and restoring each logger's previous level, reloading the Log4j configuration after each test may be a simpler solution. This ensures that any global Log4j configuration changes made in LoggersTest are fully reset, and that the restored configuration matches what other tests would see when run independently, which maintains proper test isolation.

I’ve updated the teardown to call LoggerContext.getContext(false).reconfigure(). Please let me know if you have any further feedback!

@github-actions github-actions bot removed the triage PRs from the community label Jun 9, 2025
@apalan60
Copy link
Contributor Author

apalan60 commented Jun 9, 2025

I ran a few more test classes that use logging with the command below. They all passed successfully when executed in the same JVM.

./gradlew cleanTest \
-- :connect:runtime:test --tests "LoggersTest.testSetLevelWithValidRootLoggerNames" \
-- :core:test --tests "kafka.network.SocketServerTest"
- PmaxParallelForks=1 
./gradlew cleanTest \
  :connect:runtime:test \
    --tests "LoggersTest.testSetLevelWithValidRootLoggerNames" \
    --tests "LoggingResourceTest" \
    -PmaxParallelForks=1
./gradlew cleanTest \
  :connect:runtime:test --tests "LoggersTest.testSetLevelWithValidRootLoggerNames" \
  :core:test --tests "kafka.network.SocketServerTest" \
  -PmaxParallelForks=1


@AfterEach
public void tearDown() {
LoggerContext.getContext(false).reconfigure();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments for this reconfigure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chia7712

Sorry for the late update, I've added the comments.

@chia7712 chia7712 merged commit dc82c76 into apache:trunk Jun 26, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci-approved connect small Small PRs tests Test fixes (including flaky tests)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants