Skip to content

Commit e1c94d4

Browse files
committed
testdata: fix flaky timers test
The timers test interleaved goroutine prints with ticker/timer waits, which produced non-deterministic output ordering under thread-based scheduling. On loaded systems, the goroutine prints could race with the ticker ticks, causing test failures. Fix by synchronizing the goroutine via a done channel before the first tick arrives. The goroutine still runs concurrently with the ticker (proving both mechanisms work together), but finishes well before the tick fires so the output order is deterministic. Also use wider timing margins (goroutine at 100/200ms vs ticker at 500ms) to avoid races on slow CI machines. Addresses tinygo-org/tinygo issue 4963.
1 parent 1a1506e commit e1c94d4

2 files changed

Lines changed: 29 additions & 20 deletions

File tree

testdata/timers.go

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,67 @@ import "time"
55
var timer = time.NewTimer(time.Millisecond)
66

77
func main() {
8-
// Test ticker.
8+
// Test ticker with concurrent goroutine.
9+
// The goroutine finishes at 200ms, well before the first tick at 500ms.
10+
// We wait for the goroutine to complete before receiving ticks so that
11+
// output ordering is deterministic regardless of scheduler behavior.
912
ticker := time.NewTicker(time.Millisecond * 500)
1013
println("waiting on ticker")
14+
done := make(chan bool)
1115
go func() {
12-
time.Sleep(time.Millisecond * 150)
13-
println(" - after 150ms")
14-
time.Sleep(time.Millisecond * 200)
15-
println(" - after 200ms")
16-
time.Sleep(time.Millisecond * 300)
17-
println(" - after 300ms")
16+
time.Sleep(time.Millisecond * 100)
17+
println(" - tick goroutine 100ms")
18+
time.Sleep(time.Millisecond * 100)
19+
println(" - tick goroutine 200ms")
20+
done <- true
1821
}()
22+
<-done
1923
<-ticker.C
2024
println("waited on ticker at 500ms")
2125
<-ticker.C
2226
println("waited on ticker at 1000ms")
2327
ticker.Stop()
24-
// Drain any tick that was already queued before Stop took effect.
25-
select {
26-
case <-ticker.C:
27-
default:
28-
}
29-
time.Sleep(time.Millisecond * 750)
28+
// After Stop, no more ticks should be delivered. Use a timeout
29+
// to verify. Note: we don't drain ticker.C first because the
30+
// channel may or may not have a queued tick depending on timing.
31+
// Instead, wait long enough that any queued tick would have been
32+
// consumed and no new tick should arrive.
33+
time.Sleep(time.Millisecond * 1500)
3034
select {
3135
case <-ticker.C:
3236
println("fail: ticker should have stopped!")
3337
default:
34-
println("ticker was stopped (didn't send anything after 750ms)")
38+
println("ticker was stopped (didn't send anything)")
3539
}
3640

41+
// Test timer with concurrent goroutine.
3742
timer := time.NewTimer(time.Millisecond * 750)
3843
println("waiting on timer")
3944
go func() {
4045
time.Sleep(time.Millisecond * 200)
4146
println(" - after 200ms")
42-
time.Sleep(time.Millisecond * 400)
47+
time.Sleep(time.Millisecond * 200)
4348
println(" - after 400ms")
49+
done <- true
4450
}()
4551
<-timer.C
52+
<-done
4653
println("waited on timer at 750ms")
4754
time.Sleep(time.Millisecond * 500)
4855

56+
// Test timer reset.
4957
reset := timer.Reset(time.Millisecond * 750)
5058
println("timer reset:", reset)
5159
println("waiting on timer")
5260
go func() {
5361
time.Sleep(time.Millisecond * 200)
5462
println(" - after 200ms")
55-
time.Sleep(time.Millisecond * 400)
63+
time.Sleep(time.Millisecond * 200)
5664
println(" - after 400ms")
65+
done <- true
5766
}()
5867
<-timer.C
68+
<-done
5969
println("waited on timer at 750ms")
6070
time.Sleep(time.Millisecond * 500)
6171
}

testdata/timers.txt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
waiting on ticker
2-
- after 150ms
3-
- after 200ms
2+
- tick goroutine 100ms
3+
- tick goroutine 200ms
44
waited on ticker at 500ms
5-
- after 300ms
65
waited on ticker at 1000ms
7-
ticker was stopped (didn't send anything after 750ms)
6+
ticker was stopped (didn't send anything)
87
waiting on timer
98
- after 200ms
109
- after 400ms

0 commit comments

Comments
 (0)