Skip to content

Commit 226cdb1

Browse files
committed
test(txtop): Added a regression test for panic channel closure error
Signed-off-by: Akhil Repala <arepala@blinklabs.io>
1 parent 336fa21 commit 226cdb1

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

main_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,45 @@ func TestTogglePaused(t *testing.T) {
204204
}
205205
}
206206

207+
func TestErrorChanIsolation(t *testing.T) {
208+
// Regression test for issue #287: panic: send on closed channel.
209+
//
210+
// gouroboros closes whichever error channel it is given during connection
211+
// shutdown. Passing the same shared errorChan to every connection means
212+
// the first shutdown closes it, and the second connection panics when it
213+
// tries to send on the now-closed channel.
214+
//
215+
// The fix gives each connection its own connErrChan and relays errors into
216+
// the shared channel. This test verifies that pattern: two simulated
217+
// connection lifecycles must not panic and must relay their errors.
218+
219+
sharedErrChan := make(chan error, 10)
220+
221+
simulateConnection := func(id int) {
222+
connErrChan := make(chan error, 10)
223+
done := make(chan struct{})
224+
go func() {
225+
defer close(done)
226+
for err := range connErrChan {
227+
select {
228+
case sharedErrChan <- err:
229+
default:
230+
}
231+
}
232+
}()
233+
connErrChan <- fmt.Errorf("error from connection %d", id)
234+
close(connErrChan) // gouroboros closes this on shutdown
235+
<-done // wait for relay goroutine to finish
236+
}
237+
238+
simulateConnection(1)
239+
simulateConnection(2) // would panic before the fix
240+
241+
if len(sharedErrChan) != 2 {
242+
t.Errorf("expected 2 relayed errors, got %d", len(sharedErrChan))
243+
}
244+
}
245+
207246
func TestLogBuffer_Write(t *testing.T) {
208247
lb := &LogBuffer{maxLines: 3}
209248

0 commit comments

Comments
 (0)