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.
This commit is contained in:
Spike Curtis
2024-06-18 15:40:56 +04:00
committed by GitHub
parent 1de023a121
commit d0b2f6196c
3 changed files with 97 additions and 12 deletions

82
clock/mock_test.go Normal file
View File

@ -0,0 +1,82 @@
package clock_test
import (
"context"
"testing"
"time"
"github.com/coder/coder/v2/clock"
)
func TestTimer_NegativeDuration(t *testing.T) {
t.Parallel()
// nolint:gocritic // trying to avoid Coder-specific stuff with an eye toward spinning this out
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
mClock := clock.NewMock(t)
start := mClock.Now()
trap := mClock.Trap().NewTimer()
defer trap.Close()
timers := make(chan *clock.Timer, 1)
go func() {
timers <- mClock.NewTimer(-time.Second)
}()
c := trap.MustWait(ctx)
c.Release()
// trap returns the actual passed value
if c.Duration != -time.Second {
t.Fatalf("expected -time.Second, got: %v", c.Duration)
}
tmr := <-timers
select {
case <-ctx.Done():
t.Fatal("timeout waiting for timer")
case tme := <-tmr.C:
// the tick is the current time, not the past
if !tme.Equal(start) {
t.Fatalf("expected time %v, got %v", start, tme)
}
}
if tmr.Stop() {
t.Fatal("timer still running")
}
}
func TestAfterFunc_NegativeDuration(t *testing.T) {
t.Parallel()
// nolint:gocritic // trying to avoid Coder-specific stuff with an eye toward spinning this out
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
mClock := clock.NewMock(t)
trap := mClock.Trap().AfterFunc()
defer trap.Close()
timers := make(chan *clock.Timer, 1)
done := make(chan struct{})
go func() {
timers <- mClock.AfterFunc(-time.Second, func() {
close(done)
})
}()
c := trap.MustWait(ctx)
c.Release()
// trap returns the actual passed value
if c.Duration != -time.Second {
t.Fatalf("expected -time.Second, got: %v", c.Duration)
}
tmr := <-timers
select {
case <-ctx.Done():
t.Fatal("timeout waiting for timer")
case <-done:
// OK!
}
if tmr.Stop() {
t.Fatal("timer still running")
}
}