slachiewicz opened a new issue, #1839:
URL: https://github.com/apache/maven-mvnd/issues/1839

   Integration tests can hang until the CI job's 6-hour limit, locally and on 
GitHub Actions, and can leave test daemons running afterwards. One was still 
alive 2 h 42 min after a local `./mvnw clean verify`. Nothing in the setup 
bounds either case.
   
   ### Why a stuck daemon never goes away
   
   - Idle expiry only applies in the `Idle` state 
([DaemonExpiration.java:109](https://github.com/apache/maven-mvnd/blob/master/daemon/src/main/java/org/mvndaemon/mvnd/daemon/DaemonExpiration.java#L109)).
 When a `Busy` daemon loses its registry entry, it only moves to stop-when-done 
([Server.java:400](https://github.com/apache/maven-mvnd/blob/master/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java#L400)),
 so a hung build keeps it alive indefinitely.
   - The daemon ignores SIGINT 
([Server.java:113](https://github.com/apache/maven-mvnd/blob/master/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java#L113)),
 so interrupting `./mvnw` leaves it running.
   - The sender thread sends `KEEP_ALIVE` whether or not the build progresses 
([Server.java:526](https://github.com/apache/maven-mvnd/blob/master/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java#L526)),
 so the client's `maxKeepAliveMs` bound never fires for a hung build.
   - When `request.get(1, MINUTES)` times out it throws rather than returning 
`null` 
([Server.java:279](https://github.com/apache/maven-mvnd/blob/master/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java#L279)).
 The catch block keeps the initial `Busy` state, so a daemon whose client never 
sent a request is never reused and never expires.
   
   ### Why the tests don't catch it
   
   - No default JUnit timeout (only `InteractiveTest` and `DaemonCrashTest` use 
`@Timeout`), no surefire `forkedProcessTimeoutInSeconds`, and no 
`timeout-minutes` in the workflows.
   - `TestClientOutput` only records messages, so a build that prompts or reads 
stdin waits forever in any test except `InteractiveTest`.
   - Cleanup is only `afterAll` → 
[TestRegistry.killAll()](https://github.com/apache/maven-mvnd/blob/master/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestRegistry.java#L41).
 It does not run when the test JVM is killed, removes the registry entry even 
when the kill failed, and only prints the failure.
   - Test daemons use the default 3-hour idle timeout.
   
   ### Plan
   
   1. Test side:
      - add a default JUnit timeout, `forkedProcessTimeoutInSeconds` and 
`timeout-minutes`;
      - kill registered daemons from a JVM shutdown hook;
      - before each test class, kill leftover processes started with that 
test's `-Dmvnd.daemonStorage`;
      - make `killAll` force-kill and fail loudly;
      - fail fast on `Prompt` and `RequestInput` in `TestClientOutput`;
      - lower the test idle timeout to about 10 minutes.
   2. Daemon: return to `Idle` when no request arrives within the minute.
   3. Port both to `mvnd-1.x`.
   
   #1835 makes the forked-process pump thread a daemon thread, so a child that 
keeps its output open no longer keeps the daemon JVM alive. #1558 touches 
`awaitIdle` in the same class but not the cleanup path.
   
   Which test hangs is not yet known. The daemon log (`daemon-*.log` under the 
test's registry directory, or the "Upload daemon test logs" artifact on CI) and 
`jstack` on the stuck daemon will show it.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to