Skip to content

fix: refining CLIResult asserts related to missing or repeated messages - #51238

Open
shawkins wants to merge 2 commits into
keycloak:mainfrom
shawkins:iss51095
Open

fix: refining CLIResult asserts related to missing or repeated messages#51238
shawkins wants to merge 2 commits into
keycloak:mainfrom
shawkins:iss51095

Conversation

@shawkins

Copy link
Copy Markdown
Contributor

These changes should keep the intention of the asserts, but avoid adding a baked in atLeast durations when checking for no messages.

closes: #51095

@shawkins
shawkins requested a review from Copilot July 28, 2026 13:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Refines CLI output assertions used in Quarkus distribution/integration tests to better handle “no message” checks without relying on implicit timing, especially for running-server scenarios (issue #51095).

Changes:

  • Extends CLIResult “no output” assertion helper to optionally allow assertions while the server is still running.
  • Adds new CLIResult assertion helpers (assertNoMessageAfter, assertNoStartupMessage) and updates existing assertions to guard against misuse on running servers.
  • Updates multiple distribution tests to use the new assertions for startup/running-server output.

Reviewed changes

Copilot reviewed 1 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
quarkus/tests/junit5/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java Adds new assertion helpers and enforces safer usage when the server is still running.
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/MetricsDistTest.java Switches to startup-safe “no message” assertion for running server.
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ManagementOffDistTest.java Switches to startup-safe “no message” assertion for running server.
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ManagementDistTest.java Switches to startup-safe “no message” assertion for running server.
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/LoggingDistTest.java Updates logging assertions to use new helpers and adds a test provider.
quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FipsDistTest.java Replaces “shown 0 times” with startup-safe “no message” assertion.

@shawkins
shawkins force-pushed the iss51095 branch 2 times, most recently from 856dab2 to 4a57489 Compare July 28, 2026 13:47
@shawkins
shawkins marked this pull request as ready for review July 28, 2026 19:45
@shawkins
shawkins requested a review from a team as a code owner July 28, 2026 19:45
Copilot AI review requested due to automatic review settings July 28, 2026 19:45
@shawkins
shawkins requested a review from a team as a code owner July 28, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

quarkus/tests/junit5/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java:139

  • expected does not act as a completion fence unless it is emitted after every possible notExpected message. The new callers use the @PreMatching TestFilter request log as expected, but the HTTP access log is emitted after request processing, so this can still snapshot output before the forbidden access-log line arrives and false-pass. Use a marker that is emitted after access logging/output collection has completed.
        assertMessage(expected);
        noOutput("The standard output contains: " + notExpected, notExpected, this::getOutput, this, true);

quarkus/tests/junit5/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java:147

  • This bypass is unsafe for failed manual starts. RawKeycloakDistribution.waitFor(true) returns immediately when the process has already stopped without joining the asynchronous output reader, and ManagementDistTest.testManagementNoHttps now invokes this helper on an expected startup failure; the assertion can therefore false-pass while stdout is still being drained. Drain completed-process output or require a reliable completion signal before checking absence.
    default void assertNoStartupMessage(String message) {
        noOutput("The standard output contains: " + message, message, this::getOutput, this, true);

Copilot AI review requested due to automatic review settings July 28, 2026 20:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 7 changed files in this pull request and generated 1 comment.

Copilot AI review requested due to automatic review settings July 28, 2026 21:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 7 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 28, 2026 21:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 7 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

quarkus/tests/junit5/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java:139

  • assertMessage(expected) is not an output-completion barrier: the expected line may precede a forbidden line that is still being produced or drained. In the new access-log usages, TestFilter logs from a ContainerRequestFilter before access logging completes, so this immediate absence check can still falsely pass; use a sentinel guaranteed to be emitted after the candidate output (and wait for its new occurrence), or stop and fully drain the process before checking.
    default void assertNoMessageGiven(String expected, String notExpected) {
        assertMessage(expected);
        noOutput("The standard output contains: " + notExpected, notExpected, this::getOutput, this, true);

Pepo48
Pepo48 previously approved these changes Jul 30, 2026

@Pepo48 Pepo48 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I played with assertNoMessageGiven and managed to get it to false-pass. I broke the exclude pattern in Quarkus AccessLogHandler (the exact bug the test is meant to catch) and added a non-blocking 3s delay before the log write. The assertNoMessageGiven check passed silently - the access-log line just hadn't hit stdout yet. Only the file-based Awaitility check in httpAccessLogNotNamedPattern caught it.

I think it's because assertNoMessageGiven does a single snapshot right after finding the expected message, so anything arriving a bit later slips through.

Regardless, it's not a blocker for me, the real-world window is tiny and this is way better than the old approach. Just thought it was worth mentioning.

Therefore, I'm approving. Thanks, Steve.

@shawkins

Copy link
Copy Markdown
Contributor Author

I played with assertNoMessageGiven and managed to get it to false-pass. I broke the exclude pattern in Quarkus AccessLogHandler (the exact bug the test is meant to catch) and added a non-blocking 3s delay before the log write. The assertNoMessageGiven check passed silently - the access-log line just hadn't hit stdout yet. Only the file-based Awaitility check in httpAccessLogNotNamedPattern caught it.

I think it's because assertNoMessageGiven does a single snapshot right after finding the expected message, so anything arriving a bit later slips through.

Regardless, it's not a blocker for me, the real-world window is tiny and this is way better than the old approach. Just thought it was worth mentioning.

Therefore, I'm approving. Thanks, Steve.

This is possible and relates to what copilot was calling out as well. Essentially I had started down the path of reworking the TestFilter for this purpose, but that started to seem like overkill, so I just let it be based upon looking for a subsequent request log. Let me take a look again at what doing this the right way would entail.

closes: keycloak#51095

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
Copilot AI review requested due to automatic review settings July 30, 2026 23:40
@shawkins

Copy link
Copy Markdown
Contributor Author

@Pepo48 added a done handler to run after the access logging.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 9 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 30, 2026 23:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 9 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 30, 2026 23:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 9 changed files in this pull request and generated no new comments.

vmuzikar
vmuzikar previously approved these changes Jul 31, 2026

@vmuzikar vmuzikar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, leaving to @Pepo48 to merge.

@Pepo48 Pepo48 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CI failure is related - we just need to adjust the strings.

Apart from that LGTM as well.

when().get("http://127.0.0.1:8080/realms/master/clients/account/redirect").then()
.statusCode(200);
cliResult.assertNoMessage("127.0.0.1 GET /realms/master/clients/account/redirect");
cliResult.assertNoMessageGiven("Request GET /realms/master/clients/account/redirect has context request", "127.0.0.1 GET /realms/master/clients/account/redirect");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
cliResult.assertNoMessageGiven("Request GET /realms/master/clients/account/redirect has context request", "127.0.0.1 GET /realms/master/clients/account/redirect");
cliResult.assertNoMessageGiven("TestFilter Request GET /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/clients/account/redirect");

Comment on lines +348 to +350
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "[org.keycloak.http.access-log]");
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/.well-known/openid-configuration");
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/clients/account/redirect");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "[org.keycloak.http.access-log]");
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/.well-known/openid-configuration");
fileCliResult.assertNoMessageGiven("TestFilter GET Request /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/clients/account/redirect");
fileCliResult.assertNoMessageGiven("TestFilter Request GET /realms/master/clients/account/redirect is done", "[org.keycloak.http.access-log]");
fileCliResult.assertNoMessageGiven("TestFilter Request GET /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/.well-known/openid-configuration");
fileCliResult.assertNoMessageGiven("TestFilter Request GET /realms/master/clients/account/redirect is done", "127.0.0.1 GET /realms/master/clients/account/redirect");

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
@shawkins

Copy link
Copy Markdown
Contributor Author

CI failure is related - we just need to adjust the strings.

Yes, sorry I copied those in wrong to that test. I see we also have a few more spots for false positives like line 356, but I'm not sure it's worth the complexity to keep addressing this.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 9 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLIResult assertion timing issues

4 participants