Skip to content

Improve runtime, reduce log output, and stabilize SSL failure assertions for SSLCertificateTest#1215

Draft
Copilot wants to merge 26 commits into
masterfrom
copilot/improve-ssl-certificatetest-runtime
Draft

Improve runtime, reduce log output, and stabilize SSL failure assertions for SSLCertificateTest#1215
Copilot wants to merge 26 commits into
masterfrom
copilot/improve-ssl-certificatetest-runtime

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 6, 2026

SSLCertificateTest was consuming ~20 of the CI job's ~45 minutes, logging ~45k of ~120k log lines. This PR now includes six targeted fixes:

Timeout and heartbeat tuning

  • TIMEOUT_SECONDS: 15s → 7s
  • HeartBtInt: 30s → 5s across all session settings builders — a heartbeat exchange within the window is sufficient to confirm a healthy session

Reconnect interval cleanup

  • Removed all explicit Initiator.SETTING_RECONNECT_INTERVAL overrides in this test class so the default 30 second reconnect interval is used
  • This avoids repeated expected SSL exceptions during the 7 second assertion window

Reduce log noise for expected failures

  • exceptionExpected is now configured at connector construction time and stored as an immutable (final) field on TestConnector
  • Removed the mutable expectException() path; shouldFailWhen* tests now construct relevant connectors with exceptionExpected=true before start()
  • Removed late flag mutation from assertSslExceptionThrown(...)
  • The MINA filter in prepareConnector logs message-only when exceptions are expected, and full stack trace otherwise
  • Exception logs include connector context (initiator/acceptor and connectPort/acceptPort)
  • Logging format was normalized with a static prefix first (exceptionCaught ...), and expected-path logs are explicitly marked (exceptionCaught (expected) ...)

This cuts the bulk of log output generated by shouldFailWhen* tests while making the remaining output easier to attribute.

Parallel no-exception checks

Added assertNoSslExceptionsThrown(TestConnector... connectors) — runs each connector's latch-wait concurrently instead of sequentially. For a test with N connectors this replaces N×7s with a single 7s wait.

// before: sequential, each blocks for up to 7s
initiator.assertNoSslExceptionThrown();
// ... initiator assertions ...
acceptor.assertNoSslExceptionThrown();

// after: single concurrent wait
assertNoSslExceptionsThrown(initiator, acceptor);
// ... initiator and acceptor assertions ...

Threads are named (ssl-check<Type><index>) for debuggability. On failure, a composite error message summarises all failures upfront with individual errors as suppressed exceptions. Applied across 15 test methods.

Test name logging

Added a class-level LOGGER and a @Rule TestName field to SSLCertificateTest. The existing @Before setUp() now logs >>> Running test: <methodName> before every test, making it easy to correlate log output with the active test method in CI logs.

Targeted flakiness stabilization for shouldFailWhenUsingEmptyServerKeyStore()

  • Kept strict SSL-exception assertion on the acceptor.
  • Updated initiator assertion to accept failure as an outcome set:
    • SSL exception observed, or
    • no SSL exception observed but the initiator did not send FIX Logon before disconnect/reset.
  • Implemented minimal Logon tracking on TestInitiator via toAdmin(...) (MsgType.LOGON) to support this check.
  • Extracted this fallback into a dedicated helper assertion (assertSslExceptionThrownOrLogonNotSent(...)) for clarity.

This stabilizes the test across JSSE/provider/timing differences while preserving intended behavior.

Copilot AI and others added 2 commits May 6, 2026 11:15
…rallelize no-exception checks

Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/f464dac4-ab03-4de1-a750-fbcb1d6bd19c

Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve runtime for SSLCertificateTest Improve runtime for SSLCertificateTest May 6, 2026
Copilot AI requested a review from chrjohn May 6, 2026 11:21
Copilot finished work on behalf of chrjohn May 6, 2026 11:21
Comment thread quickfixj-core/src/test/java/quickfix/mina/ssl/SSLCertificateTest.java Outdated
Copilot finished work on behalf of chrjohn May 6, 2026 13:51
Copilot AI requested a review from chrjohn May 6, 2026 13:51
Copilot finished work on behalf of chrjohn May 6, 2026 15:07
@chrjohn chrjohn changed the title Improve runtime for SSLCertificateTest Improve runtime for SSLCertificateTest May 6, 2026
@chrjohn chrjohn changed the title Improve runtime for SSLCertificateTest Improve runtime and log output for SSLCertificateTest May 6, 2026
Copilot finished work on behalf of chrjohn May 6, 2026 15:48
Refactor createDefaults method to initialize defaults directly.
Copilot stopped work on behalf of chrjohn due to an error May 6, 2026 17:05
@chrjohn chrjohn changed the title Improve runtime and log output for SSLCertificateTest Improve runtime and reduce log output for SSLCertificateTest May 6, 2026
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 9, 2026

@copilot
shouldFailWhenUsingEmptyServerKeyStore sometimes does not see the expected exception for the initiator. Only the acceptor gets the exception reliably.

...

Implemented for shouldFailWhenUsingEmptyServerKeyStore() in 34a7835. The initiator now accepts outcome-set behavior: it passes if an SSL exception is observed, or (if not) asserts that no Logon was sent before disconnect. Acceptor remains strict on SSL exception. I also updated the PR description to document this targeted change.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • localhost-quickfixj
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260509112429257_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-09T11-24-28_446-jvmRun1 surefire-20260509112429257_1tmp surefire_0-20260509112429257_2tmp (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260509112544266_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-09T11-25-44_194-jvmRun1 surefire-20260509112544266_1tmp surefire_0-20260509112544266_2tmp (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260509112645065_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-09T11-26-45_005-jvmRun1 surefire-20260509112645065_1tmp surefire_0-20260509112645065_2tmp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title Improve runtime and reduce log output for SSLCertificateTest Improve runtime, reduce log output, and stabilize SSL failure assertions for SSLCertificateTest May 9, 2026
Copilot finished work on behalf of chrjohn May 9, 2026 11:29
Comment thread quickfixj-core/src/test/java/quickfix/mina/ssl/SSLCertificateTest.java Outdated
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 11, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • localhost-quickfixj
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260511102601661_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-11T10-26-00_863-jvmRun1 surefire-20260511102601661_1tmp surefire_0-20260511102601661_2tmp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from chrjohn May 11, 2026 10:27
@chrjohn chrjohn modified the milestones: QFJ 3.0.1, QFJ 3.0.2 May 12, 2026
@chrjohn
Copy link
Copy Markdown
Member

chrjohn commented May 14, 2026

@the-thing could you please take a look at this whenever you have the time. Thank you

@the-thing
Copy link
Copy Markdown
Contributor

Sure. More AI slop. We are doomed...

Copy link
Copy Markdown
Contributor

@the-thing the-thing left a comment

Choose a reason for hiding this comment

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

Looks ok-ish. Did it improve running time and or differences across different operating systems?

private final SessionConnector connector;
private final CountDownLatch exceptionThrownLatch;
private final AtomicReference<Throwable> exception;
private volatile boolean exceptionExpected = false;
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.

This shouldn't be volatile. This should be final and set during construction time. Test case knows beforehand if the exception being thrown is required or not.

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.

Now when I look at this it looks that the flag is used only for logging. I have a feeling it shouldn't be here at all.

String portLabel = getPortLabel(session);
int port = getPort(session);
if (exceptionExpected) {
LOGGER.info("{} {}={} exceptionCaught: {}", connectionType, portLabel, port, cause.getMessage());
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.

For logging, usually the static message comes first and then additional context arguments.

SSLUtil.assertNotAuthenticated(connector, sessionID, authOn);
}

public void expectException() {
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.

To be removed once the field is final.

}

public void assertSslExceptionThrown(String expectedErrorMessage, Class<?> expectedErrorType) throws Exception {
exceptionExpected = true;
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.

Needs to be removed.

initiator.assertSslExceptionThrown();
// Depending on JSSE/provider timing, initiator may fail before surfacing an SSL exception.
try {
initiator.assertSslExceptionThrown();
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.

Ok I see what it's doing. When exception is expected but it is not thrown it switches to validate if logon was sent - seems reasonable.

Probably this should be abstracted into a separate asset method e.g. "assertSslExceptionThrownOrLogonNotSent" etc.

@chrjohn
Copy link
Copy Markdown
Member

chrjohn commented May 14, 2026

Sure. More AI slop. We are doomed...

Hi @the-thing , IMHO it's not slop as long as someone asked for it. :) I created an issue here #1214 to improve things.
I did not want to ask you, as the creator of the test, to sacrifice your valuable time on the improvement of a test which does its job very well. Thank you as always for your review comments and contributions. 👍
For me as a maintainer using copilot saves me quite some time. I can kick off a task and come back to it later. I think you can tell by the lifetime those PRs exist that it is still taking some time for me to review and merge and that I do not blindly trust everything it generates.

Looks ok-ish. Did it improve running time and or differences across different operating systems?

Complete CI job time is down from about 45 mins to about 30 mins. I did not yet count how many lines of log file less.

@the-thing
Copy link
Copy Markdown
Contributor

No problem. Take it with a pinch of salt. I use AI myself occasionally, but I think it is being used too much.

Complete CI job time is down from about 45 mins to about 30 mins. I did not yet count how many lines of log file less.

That is really good.

@chrjohn
Copy link
Copy Markdown
Member

chrjohn commented May 15, 2026

@copilot please integrate proposed review changes by the-thing

Copilot AI and others added 2 commits May 15, 2026 13:23
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 15, 2026

@copilot please integrate proposed review changes by the-thing

Integrated the proposed review changes from @the-thing in SSLCertificateTest: constructor-time immutable expected-exception configuration (removed mutable toggles), logging format adjustment, and extracted helper assertion for the initiator fallback. Also aligned the mixed multi-session failure test with constructor-based expected exceptions. Verified with SSLCertificateTest passing locally. Commits: 22eac2e, e4ab1cf.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • localhost-quickfixj
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260515130442013_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-15T13-04-41_183-jvmRun1 surefire-20260515130442013_1tmp surefire_0-20260515130442013_2tmp in/m2.conf (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260515131434412_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-15T13-14-34_342-jvmRun1 surefire-20260515131434412_1tmp surefire_0-20260515131434412_2tmp (dns block)
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java -Xmx2g -Djava.net.preferIPv4Stack=true --add-opens java.base/java.lang=ALL-UNNAMED -jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire/surefirebooter-20260515132646872_3.jar /home/REDACTED/work/quickfixj/quickfixj/quickfixj-core/target/surefire 2026-05-15T13-26-46_792-jvmRun1 surefire-20260515132646872_1tmp surefire_0-20260515132646872_2tmp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

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.

Runtime and log output for SSLCertificateTest needs to be improved

3 participants