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

Commitad55c7a

Browse files
committed
chore: add Now, Since, AfterFunc to clock; use clock for configmaps test
1 parentddbd5b9 commitad55c7a

File tree

8 files changed

+103
-43
lines changed

8 files changed

+103
-43
lines changed

‎clock/clock.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ type Clock interface {
1717
// NewTimer creates a new Timer that will send the current time on its channel after at least
1818
// duration d.
1919
NewTimer(d time.Duration,tags...string)*Timer
20+
// AfterFunc waits for the duration to elapse and then calls f in its own goroutine. It returns
21+
// a Timer that can be used to cancel the call using its Stop method. The returned Timer's C
22+
// field is not used and will be nil.
23+
AfterFunc(d time.Duration,ffunc(),tags...string)*Timer
24+
25+
// Now returns the current local time.
26+
Now(tags...string) time.Time
27+
// Since returns the time elapsed since t. It is shorthand for Clock.Now().Sub(t).
28+
Since(t time.Time,tags...string) time.Duration
2029
}
2130

2231
// Waiter can be waited on for an error.

‎clock/mock.go‎

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,46 @@ func (m *Mock) NewTimer(d time.Duration, tags ...string) *Timer {
7171
returnt
7272
}
7373

74+
func (m*Mock)AfterFunc(d time.Duration,ffunc(),tags...string)*Timer {
75+
ifd<0 {
76+
panic("duration must be positive or zero")
77+
}
78+
m.mu.Lock()
79+
deferm.mu.Unlock()
80+
m.matchCallLocked(&Call{
81+
fn:clockFunctionAfterFunc,
82+
Duration:d,
83+
Tags:tags,
84+
})
85+
t:=&Timer{
86+
nxt:m.cur.Add(d),
87+
fn:f,
88+
mock:m,
89+
}
90+
m.addTimerLocked(t)
91+
returnt
92+
}
93+
94+
func (m*Mock)Now(tags...string) time.Time {
95+
m.mu.Lock()
96+
deferm.mu.Unlock()
97+
m.matchCallLocked(&Call{
98+
fn:clockFunctionNow,
99+
Tags:tags,
100+
})
101+
returnm.cur
102+
}
103+
104+
func (m*Mock)Since(t time.Time,tags...string) time.Duration {
105+
m.mu.Lock()
106+
deferm.mu.Unlock()
107+
m.matchCallLocked(&Call{
108+
fn:clockFunctionSince,
109+
Tags:tags,
110+
})
111+
returnm.cur.Sub(t)
112+
}
113+
74114
func (m*Mock)addTimerLocked(t*Timer) {
75115
m.all=append(m.all,t)
76116
m.recomputeNextLocked()
@@ -142,9 +182,13 @@ func (m *Mock) matchCallLocked(c *Call) {
142182
m.mu.Lock()
143183
}
144184

145-
// AdvanceWaiter is returned from Advance and Set calls and allows you to wait for tick functions of
146-
// tickers created using TickerFunc to complete. If multiple timers or tickers trigger
147-
// simultaneously, they are all run on separate go routines.
185+
// AdvanceWaiter is returned from Advance and Set calls and allows you to wait for:
186+
//
187+
// - tick functions of tickers created using NewContextTicker
188+
// - functions passed to AfterFunc
189+
//
190+
// to complete. If multiple timers or tickers trigger simultaneously, they are all run on separate
191+
// go routines.
148192
typeAdvanceWaiterstruct {
149193
chchanstruct{}
150194
}
@@ -190,7 +234,7 @@ func (m *Mock) Advance(d time.Duration) AdvanceWaiter {
190234

191235
func (m*Mock)advanceLocked(d time.Duration) {
192236
ifm.advancing {
193-
panic("multiple simultaneous calls to Advance not supported")
237+
panic("multiple simultaneous calls to Advance/Set not supported")
194238
}
195239
m.advancing=true
196240
deferfunc() {
@@ -262,6 +306,10 @@ func (t Trapper) NewTimer(tags ...string) *Trap {
262306
returnt.mock.newTrap(clockFunctionNewTimer,tags)
263307
}
264308

309+
func (tTrapper)AfterFunc(tags...string)*Trap {
310+
returnt.mock.newTrap(clockFunctionAfterFunc,tags)
311+
}
312+
265313
func (tTrapper)TimerStop(tags...string)*Trap {
266314
returnt.mock.newTrap(clockFunctionTimerStop,tags)
267315
}
@@ -278,6 +326,14 @@ func (t Trapper) TickerFuncWait(tags ...string) *Trap {
278326
returnt.mock.newTrap(clockFunctionTickerFuncWait,tags)
279327
}
280328

329+
func (tTrapper)Now(tags...string)*Trap {
330+
returnt.mock.newTrap(clockFunctionNow,tags)
331+
}
332+
333+
func (tTrapper)Since(tags...string)*Trap {
334+
returnt.mock.newTrap(clockFunctionSince,tags)
335+
}
336+
281337
func (m*Mock)Trap()Trapper {
282338
returnTrapper{m}
283339
}
@@ -385,10 +441,13 @@ type clockFunction int
385441

386442
const (
387443
clockFunctionNewTimerclockFunction=iota
444+
clockFunctionAfterFunc
388445
clockFunctionTimerStop
389446
clockFunctionTimerReset
390447
clockFunctionTickerFunc
391448
clockFunctionTickerFuncWait
449+
clockFunctionNow
450+
clockFunctionSince
392451
)
393452

394453
typecallArgfunc(c*Call)

‎clock/real.go‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,17 @@ func (realClock) NewTimer(d time.Duration, _ ...string) *Timer {
5555
return&Timer{C:rt.C,timer:rt}
5656
}
5757

58+
func (realClock)AfterFunc(d time.Duration,ffunc(),_...string)*Timer {
59+
rt:=time.AfterFunc(d,f)
60+
return&Timer{C:rt.C,timer:rt}
61+
}
62+
63+
func (realClock)Now(_...string) time.Time {
64+
returntime.Now()
65+
}
66+
67+
func (realClock)Since(t time.Time,_...string) time.Duration {
68+
returntime.Since(t)
69+
}
70+
5871
var_Clock=realClock{}

‎clock/timer.go‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ func (t *Timer) fire(tt time.Time) {
1818
panic("mock timer fired at wrong time")
1919
}
2020
t.mock.removeTimer(t)
21-
t.c<-tt
2221
ift.fn!=nil {
2322
t.fn()
23+
}else {
24+
t.c<-tt
2425
}
2526
}
2627

‎go.mod‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ require (
198198
requirego.uber.org/mockv0.4.0
199199

200200
require (
201-
github.com/benbjohnson/clockv1.3.5
202201
github.com/coder/serpentv0.7.0
203202
github.com/gomarkdown/markdownv0.0.0-20231222211730-1d6d20845b47
204203
github.com/google/go-github/v61v61.0.0

‎go.sum‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE
126126
github.com/aymanbagabas/go-osc52/v2v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
127127
github.com/aymerick/douceurv0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
128128
github.com/aymerick/douceurv0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
129-
github.com/benbjohnson/clockv1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
130-
github.com/benbjohnson/clockv1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
131129
github.com/beorn7/perksv1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
132130
github.com/beorn7/perksv1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
133131
github.com/bep/clocksv0.5.0 h1:hhvKVGLPQWRVsBP/UB7ErrHYIO42gINVbvqxvYTPVps=

‎tailnet/configmaps.go‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"sync"
1010
"time"
1111

12-
"github.com/benbjohnson/clock"
1312
"github.com/google/uuid"
1413
"go4.org/netipx"
1514
"tailscale.com/ipn/ipnstate"
@@ -25,6 +24,7 @@ import (
2524
"tailscale.com/wgengine/wgcfg/nmcfg"
2625

2726
"cdr.dev/slog"
27+
"github.com/coder/coder/v2/clock"
2828
"github.com/coder/coder/v2/tailnet/proto"
2929
)
3030

@@ -116,7 +116,7 @@ func newConfigMaps(logger slog.Logger, engine engineConfigurable, nodeID tailcfg
116116
}},
117117
},
118118
peers:make(map[uuid.UUID]*peerLifecycle),
119-
clock:clock.New(),
119+
clock:clock.NewReal(),
120120
}
121121
goc.configLoop()
122122
returnc

‎tailnet/configmaps_internal_test.go‎

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"testing"
88
"time"
99

10-
"github.com/benbjohnson/clock"
1110
"github.com/google/uuid"
1211
"github.com/stretchr/testify/assert"
1312
"github.com/stretchr/testify/require"
@@ -22,6 +21,7 @@ import (
2221

2322
"cdr.dev/slog"
2423
"cdr.dev/slog/sloggers/slogtest"
24+
"github.com/coder/coder/v2/clock"
2525
"github.com/coder/coder/v2/tailnet/proto"
2626
"github.com/coder/coder/v2/testutil"
2727
)
@@ -195,9 +195,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_neverConfigures(t *testing.
195195
discoKey:=key.NewDisco()
196196
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
197197
deferuut.close()
198-
start:=time.Date(2024,time.March,29,8,0,0,0,time.UTC)
199198
mClock:=clock.NewMock()
200-
mClock.Set(start)
201199
uut.clock=mClock
202200

203201
p1ID:= uuid.UUID{1}
@@ -241,9 +239,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_outOfOrder(t *testing.T) {
241239
discoKey:=key.NewDisco()
242240
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
243241
deferuut.close()
244-
start:=time.Date(2024,time.March,29,8,0,0,0,time.UTC)
245242
mClock:=clock.NewMock()
246-
mClock.Set(start)
247243
uut.clock=mClock
248244

249245
p1ID:= uuid.UUID{1}
@@ -314,9 +310,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake(t *testing.T) {
314310
discoKey:=key.NewDisco()
315311
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
316312
deferuut.close()
317-
start:=time.Date(2024,time.March,29,8,0,0,0,time.UTC)
318313
mClock:=clock.NewMock()
319-
mClock.Set(start)
320314
uut.clock=mClock
321315

322316
p1ID:= uuid.UUID{1}
@@ -387,9 +381,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_timeout(t *testing.T) {
387381
discoKey:=key.NewDisco()
388382
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
389383
deferuut.close()
390-
start:=time.Date(2024,time.March,29,8,0,0,0,time.UTC)
391384
mClock:=clock.NewMock()
392-
mClock.Set(start)
393385
uut.clock=mClock
394386

395387
p1ID:= uuid.UUID{1}
@@ -412,7 +404,7 @@ func TestConfigMaps_updatePeers_new_waitForHandshake_timeout(t *testing.T) {
412404
}
413405
uut.updatePeers(u1)
414406

415-
mClock.Add(5*time.Second)
407+
mClock.Advance(5*time.Second).MustWait(ctx,t)
416408

417409
// it should now send the peer to the netmap
418410

@@ -574,9 +566,8 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
574566
discoKey:=key.NewDisco()
575567
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
576568
deferuut.close()
577-
start:=time.Date(2024,time.January,1,8,0,0,0,time.UTC)
578569
mClock:=clock.NewMock()
579-
mClock.Set(start)
570+
start:=mClock.Now()
580571
uut.clock=mClock
581572

582573
p1ID:= uuid.UUID{1}
@@ -600,7 +591,7 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
600591
require.Len(t,r.wg.Peers,1)
601592
_=testutil.RequireRecvCtx(ctx,t,s1)
602593

603-
mClock.Add(5*time.Second)
594+
mClock.Advance(5*time.Second).MustWait(ctx,t)
604595

605596
s2:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,start)
606597

@@ -621,7 +612,7 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
621612
// latest handshake has advanced by a minute, so we don't remove the peer.
622613
lh:=start.Add(time.Minute)
623614
s3:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,lh)
624-
mClock.Add(lostTimeout)
615+
mClock.Advance(lostTimeout).MustWait(ctx,t)
625616
_=testutil.RequireRecvCtx(ctx,t,s3)
626617
select {
627618
case<-fEng.setNetworkMap:
@@ -630,18 +621,10 @@ func TestConfigMaps_updatePeers_lost(t *testing.T) {
630621
// OK!
631622
}
632623

633-
// Before we update the clock again, we need to be sure the timeout has
634-
// completed running. To do that, we check the new lastHandshake has been set
635-
require.Eventually(t,func()bool {
636-
uut.L.Lock()
637-
deferuut.L.Unlock()
638-
returnuut.peers[p1ID].lastHandshake==lh
639-
},testutil.WaitShort,testutil.IntervalFast)
640-
641624
// Advance the clock again by a minute, which should trigger the reprogrammed
642625
// timeout.
643626
s4:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,lh)
644-
mClock.Add(time.Minute)
627+
mClock.Advance(time.Minute).MustWait(ctx,t)
645628

646629
nm=testutil.RequireRecvCtx(ctx,t,fEng.setNetworkMap)
647630
r=testutil.RequireRecvCtx(ctx,t,fEng.reconfig)
@@ -667,9 +650,8 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
667650
discoKey:=key.NewDisco()
668651
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
669652
deferuut.close()
670-
start:=time.Date(2024,time.January,1,8,0,0,0,time.UTC)
671653
mClock:=clock.NewMock()
672-
mClock.Set(start)
654+
start:=mClock.Now()
673655
uut.clock=mClock
674656

675657
p1ID:= uuid.UUID{1}
@@ -693,7 +675,7 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
693675
require.Len(t,r.wg.Peers,1)
694676
_=testutil.RequireRecvCtx(ctx,t,s1)
695677

696-
mClock.Add(5*time.Second)
678+
mClock.Advance(5*time.Second).MustWait(ctx,t)
697679

698680
s2:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,start)
699681

@@ -710,7 +692,7 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
710692
// OK!
711693
}
712694

713-
mClock.Add(5*time.Second)
695+
mClock.Advance(5*time.Second).MustWait(ctx,t)
714696
s3:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,start)
715697

716698
updates[0].Kind=proto.CoordinateResponse_PeerUpdate_NODE
@@ -727,7 +709,7 @@ func TestConfigMaps_updatePeers_lost_and_found(t *testing.T) {
727709

728710
// When we advance the clock, nothing happens because the timeout was
729711
// canceled
730-
mClock.Add(lostTimeout)
712+
mClock.Advance(lostTimeout).MustWait(ctx,t)
731713
select {
732714
case<-fEng.setNetworkMap:
733715
t.Fatal("should not reprogram")
@@ -753,9 +735,8 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
753735
discoKey:=key.NewDisco()
754736
uut:=newConfigMaps(logger,fEng,nodeID,nodePrivateKey,discoKey.Public())
755737
deferuut.close()
756-
start:=time.Date(2024,time.January,1,8,0,0,0,time.UTC)
757738
mClock:=clock.NewMock()
758-
mClock.Set(start)
739+
start:=mClock.Now()
759740
uut.clock=mClock
760741

761742
p1ID:= uuid.UUID{1}
@@ -788,7 +769,7 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
788769
require.Len(t,r.wg.Peers,2)
789770
_=testutil.RequireRecvCtx(ctx,t,s1)
790771

791-
mClock.Add(5*time.Second)
772+
mClock.Advance(5*time.Second).MustWait(ctx,t)
792773
uut.setAllPeersLost()
793774

794775
// No reprogramming yet, since we keep the peer around.
@@ -802,7 +783,7 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
802783
// When we advance the clock, even by a few ms, the timeout for peer 2 pops
803784
// because our status only includes a handshake for peer 1
804785
s2:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,start)
805-
mClock.Add(time.Millisecond*10)
786+
mClock.Advance(time.Millisecond*10).MustWait(ctx,t)
806787
_=testutil.RequireRecvCtx(ctx,t,s2)
807788

808789
nm=testutil.RequireRecvCtx(ctx,t,fEng.setNetworkMap)
@@ -812,7 +793,7 @@ func TestConfigMaps_setAllPeersLost(t *testing.T) {
812793

813794
// Finally, advance the clock until after the timeout
814795
s3:=expectStatusWithHandshake(ctx,t,fEng,p1Node.Key,start)
815-
mClock.Add(lostTimeout)
796+
mClock.Advance(lostTimeout).MustWait(ctx,t)
816797
_=testutil.RequireRecvCtx(ctx,t,s3)
817798

818799
nm=testutil.RequireRecvCtx(ctx,t,fEng.setNetworkMap)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp