From bfa7b47c22d9fe6a8e347b76ff0b626dbd5978d3 Mon Sep 17 00:00:00 2001 From: Fabian Holler Date: Wed, 13 Apr 2022 12:10:59 +0200 Subject: [PATCH] tests: add testcase to ensure reader routine terminates Add a testcase for the bug that the reader go-routine tries to send a message to the buffered rpc channel but call() terminated because it read an error from the errors chan or the errors chan was closed. It cause that reader routine gets stuck forever and does not terminate when the connection is closed. More information: https://github.com/rabbitmq/amqp091-go/issues/69. This testcase does not reproduce the issue reliably, but it is triggered in ~80% of executions. --- connection_test.go | 31 +++++++++++++++++++++++++++++++ go.mod | 2 ++ 2 files changed, 33 insertions(+) diff --git a/connection_test.go b/connection_test.go index 167487d..88fa934 100644 --- a/connection_test.go +++ b/connection_test.go @@ -14,6 +14,8 @@ import ( "sync" "testing" "time" + + "go.uber.org/goleak" ) func TestRequiredServerLocale(t *testing.T) { @@ -210,3 +212,32 @@ func TestChannelIsClosed(t *testing.T) { t.Fatal("channel expected to be marked as closed") } } + +// TestReaderGoRoutineTerminatesWhenMsgIsProcessedDuringClose tests the issue +// described in https://github.com/rabbitmq/amqp091-go/issues/69. +func TestReaderGoRoutineTerminatesWhenMsgIsProcessedDuringClose(t *testing.T) { + const routines = 10 + defer goleak.VerifyNone(t) + c := integrationConnection(t, t.Name()) + + var wg sync.WaitGroup + startSigCh := make(chan interface{}) + + for i := 0; i < routines; i++ { + wg.Add(1) + go func(id int) { + defer wg.Done() + + <-startSigCh + + err := c.Close() + if err != nil { + t.Logf("close failed in routine %d: %s", id, err.Error()) + } + }(i) + } + close(startSigCh) + + t.Log("waiting for go-routines to terminate") + wg.Wait() +} diff --git a/go.mod b/go.mod index d26956a..e1bdee9 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/rabbitmq/amqp091-go go 1.16 + +require go.uber.org/goleak v1.1.12