Skip to content

Commit a55e775

Browse files
author
Uwe Jugel
committed
fix typos and race cond for changed logic
1 parent b8d84c8 commit a55e775

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

assert/assertions.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

require/requirements_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,6 @@ func TestEventuallyWithTOuterFailNow(t *testing.T) {
803803
}
804804

805805
EventuallyWithT(mockT, condition, 100*time.Millisecond, 20*time.Millisecond)
806-
True(t, mockT.Failed, "Check should pass")
807-
Equal(t, 1, counter, "Condition is expected to be called 1 times")
806+
True(t, mockT.Failed, "Check should fail")
807+
Equal(t, 1, counter, "Condition is expected to be called once")
808808
}

0 commit comments

Comments
 (0)