Skip to content

Windows Java smoke: ContractFloorTest fails in TempDir cleanup #902

Description

@kartikeya-27

ContractFloorTest > refusesToOpenStorageThatRequiresANewerBuild(Path) failed
on Java SDK Smoke (windows-x86_64) with:

ContractFloorTest > refusesToOpenStorageThatRequiresANewerBuild(Path) FAILED
    java.io.IOException at ForEachOps.java:184
644 tests completed, 1 failed, 2 skipped

Seen on PR #901, a branch that changes a Cargo exclude, renames a Rust test
file and edits a YAML comment — nothing that reaches the Java SDK. Every other
leg of the same run was green, including all three JDK rows, GraalVM and the
macOS smoke. The same job passed on the four most recent completed master runs,
so it is intermittent rather than a break.

What the frame says

ForEachOps is a stream terminal operation, so this is JUnit's @TempDir
cleanup walking the directory and deleting, not an assertion — the test body
passed. Windows refuses to delete a file with an open handle where POSIX does
not, which is consistent with only the Windows row seeing it.

It is also the one test in the class whose open is expected to throw, so it
is the only one with no try-with-resources closing anything.

What is ruled out

  • A leaked native handle. Java_..._NativeQueue_open returns through
    guard, which throws and returns 0 on error, so new JniQueueBackend(...)
    never runs and no handle exists to leak. On the Rust side
    crates/flexiq-java/src/backend.rs:161-166 propagates the contract-floor
    error with ?, dropping storage — there is no missing close to point at.
  • The first queue in the test. It is closed by try-with-resources, and
    JniQueueBackend.close calls NativeQueue.close synchronously under the
    write lock.
  • The known Java flake. WorkflowCacheTest.cachedStepIsReusedOnRerun is a
    fixed-budget await timing out; different test, different signature.

What is not established

Why a handle would still be open at cleanup, or whether one is. The remaining
candidates are connection-pool teardown timing and a runner-level lock
(Defender or the indexer touching a freshly written file), and nothing in the
log separates them.

Why it is hard to get further

ci-java.yml uploads the cdylib and no test report. Gradle's console output is
one line per failure — the exception type and nothing else. The message, the
stack and any suppressed causes live only in
sdks/java/build/reports/tests/, which dies with the runner. So every sighting
costs the same guesswork.

Uploading the reports on failure is the prerequisite for diagnosing this, and
is split out so it lands whether or not the cause is found.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Opportunisticarea/cibugSomething isn't workingjavaJava SDKtests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions