mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: add clock pkg for testing time (#13461)
Adds a package for testing time/timer/ticker functions. Implementation is limited to `NewTimer` and `NewContextTicker`, but will eventually be expanded to all `time` functions from the standard library as well as `context.WithTimeout()`, `context.WithDeadline()`. Replaces `benbjohnson/clock` for the pubsub watchdog, as a proof of concept. Eventually, as we expand functionality, we will replace most time-related functions with this library for testing.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package clock
|
||||
|
||||
import "time"
|
||||
|
||||
type Timer struct {
|
||||
C <-chan time.Time
|
||||
//nolint: revive
|
||||
c chan time.Time
|
||||
timer *time.Timer // realtime impl, if set
|
||||
nxt time.Time // next tick time
|
||||
mock *Mock // mock clock, if set
|
||||
fn func() // AfterFunc function, if set
|
||||
stopped bool // True if stopped, false if running
|
||||
}
|
||||
|
||||
func (t *Timer) fire(tt time.Time) {
|
||||
if !tt.Equal(t.nxt) {
|
||||
panic("mock timer fired at wrong time")
|
||||
}
|
||||
t.mock.removeTimer(t)
|
||||
t.c <- tt
|
||||
if t.fn != nil {
|
||||
t.fn()
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Timer) next() time.Time {
|
||||
return t.nxt
|
||||
}
|
||||
|
||||
func (t *Timer) Stop(tags ...string) bool {
|
||||
if t.timer != nil {
|
||||
return t.timer.Stop()
|
||||
}
|
||||
t.mock.mu.Lock()
|
||||
defer t.mock.mu.Unlock()
|
||||
c := newCall(clockFunctionTimerStop, tags)
|
||||
t.mock.matchCallLocked(c)
|
||||
defer close(c.complete)
|
||||
result := !t.stopped
|
||||
t.mock.removeTimerLocked(t)
|
||||
return result
|
||||
}
|
||||
|
||||
func (t *Timer) Reset(d time.Duration, tags ...string) bool {
|
||||
if t.timer != nil {
|
||||
return t.timer.Reset(d)
|
||||
}
|
||||
if d < 0 {
|
||||
panic("duration must be positive or zero")
|
||||
}
|
||||
t.mock.mu.Lock()
|
||||
defer t.mock.mu.Unlock()
|
||||
c := newCall(clockFunctionTimerReset, tags, withDuration(d))
|
||||
t.mock.matchCallLocked(c)
|
||||
defer close(c.complete)
|
||||
result := !t.stopped
|
||||
t.mock.removeTimerLocked(t)
|
||||
t.stopped = false
|
||||
t.nxt = t.mock.cur.Add(d)
|
||||
select {
|
||||
case <-t.c:
|
||||
default:
|
||||
}
|
||||
t.mock.addTimerLocked(t)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user