From 4c1083f9cfb2b1284f368ce1a5e67dd67b6e1f7c Mon Sep 17 00:00:00 2001 From: Pavel Zbitskiy Date: Thu, 5 Mar 2026 11:56:56 -0500 Subject: [PATCH] tests: fix TestNodeSetCatchpointCatchupMode data race --- node/node.go | 4 ++-- node/node_test.go | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/node/node.go b/node/node.go index 23aae5cd06..200322dfe9 100644 --- a/node/node.go +++ b/node/node.go @@ -1247,7 +1247,7 @@ func (node *AlgorandFullNode) AbortCatchup(catchpoint string) error { // channel which contains the updated node context. This function need to work asynchronously so that the caller could // detect and handle the use case where the node is being shut down while we're switching to/from catchup mode without // deadlocking on the shared node mutex. -func (node *AlgorandFullNode) SetCatchpointCatchupMode(catchpointCatchupMode bool) (outCtxCh <-chan context.Context) { +func (node *AlgorandFullNode) SetCatchpointCatchupMode(enable bool) (outCtxCh <-chan context.Context) { // create a non-buffered channel to return the newly created context. The fact that it's non-buffered here // is important, as it allows us to synchronize the "receiving" of the new context before canceling of the previous // one. @@ -1262,7 +1262,7 @@ func (node *AlgorandFullNode) SetCatchpointCatchupMode(catchpointCatchupMode boo node.mu.Unlock() return } - if catchpointCatchupMode { + if enable { // stop.. defer func() { node.mu.Unlock() diff --git a/node/node_test.go b/node/node_test.go index 7026b363e4..2450632506 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -1181,6 +1181,10 @@ func TestNodeSetCatchpointCatchupMode(t *testing.T) { // "start" catchpoint catchup => close services outCh := n.SetCatchpointCatchupMode(true) <-outCh + // make sure SetCatchpointCatchupMode' goroutine has completely finished + // to prevent data race on stop/start services + n.waitMonitoringRoutines() + // "stop" catchpoint catchup => resume services outCh = n.SetCatchpointCatchupMode(false) <-outCh