From 7134ea039385d6789f392c3b1a1640a60ea52a07 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Oct 2025 13:49:16 +1100 Subject: [PATCH] Backtester: Fix intermittent race condition in TestExecuteStrategy (#2080) * Initial plan * Fix intermittent race condition in TestExecuteStrategy Add synchronization point after async ExecuteStrategy call to wait for background goroutine completion before resetting metadata. This prevents the race condition where Stop() could be called after metadata reset, causing errAlreadyRan instead of the expected errLiveOnly. Co-authored-by: thrasher- <4685270+thrasher-@users.noreply.github.com> * Use assert.Eventually instead of manual polling loop Replace manual for-loop polling with assert.Eventually for cleaner and more idiomatic test synchronization. Co-authored-by: gloriousCode <9261323+gloriousCode@users.noreply.github.com> * Use require.Eventually instead of assert.Eventually Change to require.Eventually to ensure test stops immediately if the async goroutine doesn't complete, preventing potential race conditions from leaking into subsequent test assertions. Co-authored-by: shazbert <9391715+shazbert@users.noreply.github.com> * Change error message from "should" to "must" Update assertion message to reflect mandatory nature of the condition when using require.Eventually. Co-authored-by: shazbert <9391715+shazbert@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: thrasher- <4685270+thrasher-@users.noreply.github.com> Co-authored-by: gloriousCode <9261323+gloriousCode@users.noreply.github.com> Co-authored-by: shazbert <9391715+shazbert@users.noreply.github.com> --- backtester/engine/backtest_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backtester/engine/backtest_test.go b/backtester/engine/backtest_test.go index 326c8ef6..ecf89c74 100644 --- a/backtester/engine/backtest_test.go +++ b/backtester/engine/backtest_test.go @@ -1641,6 +1641,10 @@ func TestExecuteStrategy(t *testing.T) { err = bt.ExecuteStrategy(false) require.NoError(t, err) + // Wait for the async goroutine to complete before proceeding + // to avoid race condition where Stop() is called after we reset metadata + require.Eventually(t, bt.HasRan, time.Second, 10*time.Millisecond, "async goroutine must complete") + bt.m.Lock() bt.MetaData.LiveTesting = true bt.MetaData.DateStarted = time.Time{}