A goroutine leak in manager/state/raft/transport/transport_test.go
When call New() at
https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/mock_raft_test.go#L68
A goroutine is created to execute run() in New()
https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/transport.go#L79
And the run() can return when case <-ctx.Done() get executed
https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/transport.go#L100-L105
However, there is no tr.Stop() to cancel the context after calling New() sometimes. So the goroutine will block forever and leak. https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/transport.go#L119-L122
How to reproduce:
You can use goleak testing the function to reproduce the bug. For the test function , The newMockRaft( ) is called four times, but only one c.Get(3).Stop() get exectued. So goroutines leak.
https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/transport_test.go#L214
https://github.com/moby/swarmkit/blob/e8ecf83ee08e14a05e28992dc304576079d403c7/manager/state/raft/transport/transport_test.go#L230
The partial output is as follows:
leaks.go:78: found unexpected goroutines:
[Goroutine 9 in state select, with github.com/moby/swarmkit/v2/manager/state/raft/transport.(*Transport).run on top of the stack:
goroutine 9 [select]:
github.com/moby/swarmkit/v2/manager/state/raft/transport.(*Transport).run(0xc0000365f0, {0xe26d20, 0xc0000365a0})
/home/song2048/桌面/goProject/src/GoPV/GoPV/testdata/real-GoProjects/src/github.com/swarmkit/manager/state/raft/transport/transport.go:111 +0x1e7
created by github.com/moby/swarmkit/v2/manager/state/raft/transport.New in goroutine 8
/home/song2048/桌面/goProject/src/GoPV/GoPV/testdata/real-GoProjects/src/github.com/swarmkit/manager/state/raft/transport/transport.go:80 +0x29c
How to fix the bug: For the test function, we should call stop() three times at the end of the function to avoid leaking goroutines.
c.Get(1).Stop()
c.Get(2).Stop()
nr.Stop()