Conversation
….testFailedRequest testFailedRequest returned as soon as getOrThrowUninterruptibly() threw, without waiting for the promise completion listener to remove the request from remoteRequests/localRequests. Since sibling test methods only depend on testNoConnectionRequest, TestNG may run any of them right after testFailedRequest, so their entry assertions could observe the stale entry and fail intermittently. The assertions placed after getOrThrowUninterruptibly() were also unreachable: the call threw before reaching them, so the test never verified its own cleanup. Catch the expected exception explicitly and wait for the maps to drain, as the sibling test methods already do.
vharseko
added a commit
to vharseko/OpenICF
that referenced
this pull request
Sep 19, 2026
…ty answer The Docker jobs fetched releases/latest anonymously; the 60 req/h limit is per runner IP, so a rate-limited answer silently left release_version empty, metadata-action produced no tag and buildx failed two steps later with "tag is needed when pushing to registry" (PR OpenIdentityPlatform#140, run 35429703030). Use the tag rather than the release title: it is what the Dockerfile's releases/download URL is built from, and it is never empty.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the intermittent
RequestDistributorTest.testSimpleRequestCI failure reported in #137 by closing the gap intestFailedRequest, the one test method in the class that did not wait for its own request to be unregistered before returning.Root cause
RemoteRequest.getSendFunction()registers the map cleanup as a promise completion listener:which is what runs
remoteRequests.remove(request.getRequestId())(RemoteConnectionGroup.allocateRequest).In
PromiseImpl.setState()the waiter is woken before the listener queue is drained:So returning from
getOrThrowUninterruptibly()does not guarantee the entry has leftremoteRequests. The window is normally microseconds, which is why this only shows up on a loaded CI runner.testSimpleRequest(3 s sleep),testCallbackRequest,testBlockingCallbackRequestandtestCancelRequest(5x1 s retry loops) all absorb that window before they return.testFailedRequestdid not:The call throws
RuntimeException("Unknown Test case number")(set viagetExceptionHandler().handleException(...)inTestRemoteRequest.handleIncomingMessage, i.e. theHAS_EXCEPTIONpath), so both assertions were dead code and the method went straight tofinally { connection.close(); }with no wait at all. Since every one of these methods only declaresdependsOnMethods = { "testNoConnectionRequest" }, TestNG is free to scheduletestFailedRequestright beforetestSimpleRequestortestCallbackRequest, whose entry assertion onclient.getRemoteRequests().isEmpty()then races the pending listener — exactly the failure at line 147 in the report.The server side is not affected:
LocalRequest.handleException()callsremoveRequest()synchronously before the error message is even sent, which is consistent with the CI log failing ongetRemoteRequests()rather thangetLocalRequests().Change
testFailedRequestnow catches the expected exception explicitly (so theexpectedExceptionsannotation is no longer needed and the assertions become reachable) and waits forremoteRequests/localRequeststo drain with the same retry loop the sibling test methods use.Test plan
mvn -pl OpenICF-java-framework/connector-framework-rpc test -Dtest=RequestDistributorTest— 6/6 greenAssert.fail("Not Failed")if no exception, plus a message check on the caughtRuntimeExceptionFixes #137