Bug description
The root-b race shard intermittently fails in TestSDKServerEnablers_Scenario8_LifetimePipeIsQuietOnCleanShutdown after waiting 10 seconds for the lifetime-pipe watcher to observe p.Close().
Observed failures:
Both fail with:
--- FAIL: TestSDKServerEnablers_Scenario8_LifetimePipeIsQuietOnCleanShutdown (10.00s)
daemonhosting_test.go:959: the watcher did not observe its own Close within 10s
No race-detector report is present.
Steps to reproduce
Run the root-b race shard repeatedly on Linux:
The scheduling-sensitive sequence is:
openLifetimePipe wraps a blocking inherited pipe descriptor with os.NewFile and starts watch.
watch may enter a blocking Read while the writer remains open.
- The test calls
p.Close() and waits for p.Closed().
On Linux, closing the descriptor from another goroutine does not guarantee that an already-blocked read wakes. If Close wins before Read, the test passes; if Read wins, it can remain blocked until the writer closes.
Expected behavior
The test should verify that clean shutdown does not emit lifetime pipe read failed without requiring an unsupported join guarantee from lifetimePipe.Close.
Actual behavior
The test asserts that Close wakes and joins the watcher within 10 seconds. This contradicts both the implementation comment and ADR 0027 List 1 row 66, which explicitly state that Close does not join the watcher and that it exits when the parent endpoint reaches EOF.
Environment
- OS/version: GitHub-hosted Ubuntu 24.04 runners
- Go: 1.27.x with
-race
- Deployment shape:
cmd/mecated unit test in the root-b race shard
Suggested fix
Align the fixture with the documented lifecycle: call p.Close(), close the writer to release any in-flight Linux read, then wait for p.Closed() before checking the captured logs. Increasing the timeout alone will retain the race.
Tracked alongside #815 because both surfaced in the race shards, but the causes and fixes are independent.
Bug description
The root-b race shard intermittently fails in
TestSDKServerEnablers_Scenario8_LifetimePipeIsQuietOnCleanShutdownafter waiting 10 seconds for the lifetime-pipe watcher to observep.Close().Observed failures:
Both fail with:
No race-detector report is present.
Steps to reproduce
Run the root-b race shard repeatedly on Linux:
The scheduling-sensitive sequence is:
openLifetimePipewraps a blocking inherited pipe descriptor withos.NewFileand startswatch.watchmay enter a blockingReadwhile the writer remains open.p.Close()and waits forp.Closed().On Linux, closing the descriptor from another goroutine does not guarantee that an already-blocked read wakes. If
Closewins beforeRead, the test passes; ifReadwins, it can remain blocked until the writer closes.Expected behavior
The test should verify that clean shutdown does not emit
lifetime pipe read failedwithout requiring an unsupported join guarantee fromlifetimePipe.Close.Actual behavior
The test asserts that
Closewakes and joins the watcher within 10 seconds. This contradicts both the implementation comment and ADR 0027 List 1 row 66, which explicitly state thatClosedoes not join the watcher and that it exits when the parent endpoint reaches EOF.Environment
-racecmd/mecatedunit test in the root-b race shardSuggested fix
Align the fixture with the documented lifecycle: call
p.Close(), close the writer to release any in-flight Linux read, then wait forp.Closed()before checking the captured logs. Increasing the timeout alone will retain the race.Tracked alongside #815 because both surfaced in the race shards, but the causes and fixes are independent.