@@ -13,6 +13,7 @@ import (
1313 "runtime"
1414 "runtime/debug"
1515 "strings"
16+ "sync/atomic"
1617 "time"
1718 "unicode"
1819 "unicode/utf8"
@@ -2151,21 +2152,27 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
21512152 conditionSucceeded
21522153 )
21532154
2154- var lastFinishedTickErrs []error
2155+ var lastFinishedTickErrs atomic. Value // of []error
21552156 ch := make (chan int , 1 )
21562157
21572158 checkCond := func () {
21582159 result := conditionExitedUnexpectedly
21592160 collect := new (CollectT )
21602161 defer func () {
2162+ // At this point, the condition has returned or exited. It is safe
2163+ // to check collect.errors and collect.exited, unless the user has
2164+ // created additional goroutines that access 'collect', which would
2165+ // be a misuse and is not supported.
21612166 if collect .exited {
21622167 // Condition exited via [CollectT.FailNow], which is a regular
21632168 // way to fail the condition early and exit the goroutine.
21642169 result = conditionFailed
21652170 }
21662171 // Keep the collected tick errors, so that they can be copied to 't'
21672172 // when timeout is reached or there is an unexpected exit.
2168- lastFinishedTickErrs = collect .errors
2173+ // Always store the actual value of collect.errors, even if nil
2174+ lastFinishedTickErrs .Store (collect .errors )
2175+
21692176 ch <- result
21702177 }()
21712178 condition (collect )
@@ -2176,6 +2183,16 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
21762183 }
21772184 }
21782185
2186+ copyLastFinishedTickErrs := func () {
2187+ errs , ok := lastFinishedTickErrs .Load ().([]error )
2188+ if ! ok {
2189+ return
2190+ }
2191+ for _ , err := range errs {
2192+ t .Errorf ("%v" , err )
2193+ }
2194+ }
2195+
21792196 timer := time .NewTimer (waitFor )
21802197 defer timer .Stop ()
21812198
@@ -2190,19 +2207,15 @@ func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time
21902207 for {
21912208 select {
21922209 case <- timer .C :
2193- for _ , err := range lastFinishedTickErrs {
2194- t .Errorf ("%v" , err )
2195- }
2210+ copyLastFinishedTickErrs ()
21962211 return Fail (t , "Condition never satisfied" , msgAndArgs ... )
21972212 case <- tickC :
21982213 tickC = nil
21992214 go checkCond ()
22002215 case result := <- ch :
22012216 switch result {
22022217 case conditionExitedUnexpectedly :
2203- for _ , err := range lastFinishedTickErrs {
2204- t .Errorf ("%v" , err )
2205- }
2218+ copyLastFinishedTickErrs ()
22062219 return Fail (t , "Condition exited unexpectedly" , msgAndArgs ... )
22072220 case conditionSucceeded :
22082221 return true
0 commit comments