Conversation
`start` spawns the test process before its own error handler. When the spawn fails, for example because the program in `juliaCmd` does not exist, the error escapes to the `@async` task in `_launch_julia_process!`, and its `catch` only logs it. The reactor gets no message, so the process stays in ProcessStarting, its test run never completes, and a shutdown waits the full grace period for the process. The `catch` now also posts `TestProcessIOErrorMsg(ps.id, :fatal)`, as the other error paths in this file do. The existing fatal IO error path then errors the queued test items and removes the process.
This branch has not been deployed
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.
I found this problem while I was trying out a customized version of the JuliaMCP.jl server. I used AI help to debug the problem to its root cause and to prepare the fix.
Problem
When the controller cannot spawn the program in
juliaCmd, the test run does not complete. Its test items stay pending, and its test processes keep the statusLaunching. The client gets no error. The only record is this log entry:To reproduce, start a test run with a
juliaCmdthat does not exist, for example/nonexistent/julia. A value such as"julia +1.12"gives the same result, because the controller uses the full string as one program name. A cancel ends the test run, but the test processes stay in the controller. At shutdown, the controller then waits the full grace period of 30 s for them.Cause
startspawns the process insrc/testprocess.jl:417-423, before thetryat:430. The code after:430sendsTestProcessIOErrorMsgorTestProcessTerminatedMsgto the reactor. A spawn error skips this code. The error goes to thecatchof the@asynctask in_launch_julia_process!(src/testitemcontroller.jl:2615-2621), and thiscatchonly writes the log entry. So the reactor gets no message. The process stays inProcessStarting, andexecute_testrunwaits for its test items with no limit.Fix
The
catchin_launch_julia_process!now also sendsTestProcessIOErrorMsg(ps.id, :fatal). It uses the sametry put!(…) catch endline as 7 other error paths in this file. The existing path for a fatal IO error does the rest:handle!(::TestProcessIOErrorMsg)sendsTestProcessTerminatedMsg._handle_termination_during_run!errors the queued test items, and the test run completes.handle!(::TestProcessTerminatedMsg)removes the process and callson_process_terminated.The handler ignores a message for an unknown or dead process, so a second message for the same process has no effect. The change also covers other errors that escape
startbefore its error handler, for example fromSockets.listen.Tests
The new test item
A Julia command that cannot be spawned errors all test itemsintest/test_process_crash.jlruns 2 test items on 2 processes. ItsjuliaCmdis a path that does not exist.run_testrun timed out after 60s. Both processes log theIOErrorabove. After the timeout, the controller also does not stop within the 10 sshutdown_timeout.The other test items in
test_process_crash.jlalso pass with the fix.Possible follow-up
The message of an errored test item is "Test process crashed before running test item '…'". This message does not give the cause. A follow-up can keep a short cause on the process state and add it to this message. An example cause is "
julia +1.12: no such file or directory (ENOENT)". The fullIOErrortext is not suitable for this, because it contains the environment of the controller. This PR does not change the message.