Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd0b2f61

Browse files
authored
fix: allow mock clock Timers to accept negative duration (#13592)
The standard library `NewTimer`, `AfterFunc` and `Reset` allow negative durations, so our mock clock library should as well.
1 parent1de023a commitd0b2f61

File tree

3 files changed

+97
-12
lines changed

3 files changed

+97
-12
lines changed

‎clock/mock.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ func (m *Mock) TickerFunc(ctx context.Context, d time.Duration, f func() error,
5252
}
5353

5454
func (m*Mock)NewTimer(d time.Duration,tags...string)*Timer {
55-
ifd<0 {
56-
panic("duration must be positive or zero")
57-
}
5855
m.mu.Lock()
5956
deferm.mu.Unlock()
6057
c:=newCall(clockFunctionNewTimer,tags,withDuration(d))
@@ -67,14 +64,17 @@ func (m *Mock) NewTimer(d time.Duration, tags ...string) *Timer {
6764
nxt:m.cur.Add(d),
6865
mock:m,
6966
}
67+
ifd<=0 {
68+
// zero or negative duration timer means we should immediately fire
69+
// it, rather than add it.
70+
got.fire(t.mock.cur)
71+
returnt
72+
}
7073
m.addTimerLocked(t)
7174
returnt
7275
}
7376

7477
func (m*Mock)AfterFunc(d time.Duration,ffunc(),tags...string)*Timer {
75-
ifd<0 {
76-
panic("duration must be positive or zero")
77-
}
7878
m.mu.Lock()
7979
deferm.mu.Unlock()
8080
c:=newCall(clockFunctionAfterFunc,tags,withDuration(d))
@@ -85,6 +85,12 @@ func (m *Mock) AfterFunc(d time.Duration, f func(), tags ...string) *Timer {
8585
fn:f,
8686
mock:m,
8787
}
88+
ifd<=0 {
89+
// zero or negative duration timer means we should immediately fire
90+
// it, rather than add it.
91+
got.fire(t.mock.cur)
92+
returnt
93+
}
8894
m.addTimerLocked(t)
8995
returnt
9096
}

‎clock/mock_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package clock_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/coder/coder/v2/clock"
9+
)
10+
11+
funcTestTimer_NegativeDuration(t*testing.T) {
12+
t.Parallel()
13+
// nolint:gocritic // trying to avoid Coder-specific stuff with an eye toward spinning this out
14+
ctx,cancel:=context.WithTimeout(context.Background(),10*time.Second)
15+
defercancel()
16+
17+
mClock:=clock.NewMock(t)
18+
start:=mClock.Now()
19+
trap:=mClock.Trap().NewTimer()
20+
defertrap.Close()
21+
22+
timers:=make(chan*clock.Timer,1)
23+
gofunc() {
24+
timers<-mClock.NewTimer(-time.Second)
25+
}()
26+
c:=trap.MustWait(ctx)
27+
c.Release()
28+
// trap returns the actual passed value
29+
ifc.Duration!=-time.Second {
30+
t.Fatalf("expected -time.Second, got: %v",c.Duration)
31+
}
32+
33+
tmr:=<-timers
34+
select {
35+
case<-ctx.Done():
36+
t.Fatal("timeout waiting for timer")
37+
casetme:=<-tmr.C:
38+
// the tick is the current time, not the past
39+
if!tme.Equal(start) {
40+
t.Fatalf("expected time %v, got %v",start,tme)
41+
}
42+
}
43+
iftmr.Stop() {
44+
t.Fatal("timer still running")
45+
}
46+
}
47+
48+
funcTestAfterFunc_NegativeDuration(t*testing.T) {
49+
t.Parallel()
50+
// nolint:gocritic // trying to avoid Coder-specific stuff with an eye toward spinning this out
51+
ctx,cancel:=context.WithTimeout(context.Background(),10*time.Second)
52+
defercancel()
53+
54+
mClock:=clock.NewMock(t)
55+
trap:=mClock.Trap().AfterFunc()
56+
defertrap.Close()
57+
58+
timers:=make(chan*clock.Timer,1)
59+
done:=make(chanstruct{})
60+
gofunc() {
61+
timers<-mClock.AfterFunc(-time.Second,func() {
62+
close(done)
63+
})
64+
}()
65+
c:=trap.MustWait(ctx)
66+
c.Release()
67+
// trap returns the actual passed value
68+
ifc.Duration!=-time.Second {
69+
t.Fatalf("expected -time.Second, got: %v",c.Duration)
70+
}
71+
72+
tmr:=<-timers
73+
select {
74+
case<-ctx.Done():
75+
t.Fatal("timeout waiting for timer")
76+
case<-done:
77+
// OK!
78+
}
79+
iftmr.Stop() {
80+
t.Fatal("timer still running")
81+
}
82+
}

‎clock/timer.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ func (t *Timer) Reset(d time.Duration, tags ...string) bool {
4444
ift.timer!=nil {
4545
returnt.timer.Reset(d)
4646
}
47-
ifd<0 {
48-
panic("duration must be positive or zero")
49-
}
5047
t.mock.mu.Lock()
5148
defert.mock.mu.Unlock()
5249
c:=newCall(clockFunctionTimerReset,tags,withDuration(d))
@@ -57,9 +54,9 @@ func (t *Timer) Reset(d time.Duration, tags ...string) bool {
5754
case<-t.c:
5855
default:
5956
}
60-
ifd==0 {
61-
// zero duration timer means we should immediately re-fire it, rather
62-
// than remove and re-add it.
57+
ifd<=0 {
58+
// zeroor negativeduration timer means we should immediately re-fire
59+
//it, ratherthan remove and re-add it.
6360
t.stopped=false
6461
got.fire(t.mock.cur)
6562
returnresult

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp