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

fix: allow mock clock Timers to accept negative duration#13592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletionsclock/mock.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -52,9 +52,6 @@ func (m *Mock) TickerFunc(ctx context.Context, d time.Duration, f func() error,
}

func (m *Mock) NewTimer(d time.Duration, tags ...string) *Timer {
if d < 0 {
panic("duration must be positive or zero")
}
m.mu.Lock()
defer m.mu.Unlock()
c := newCall(clockFunctionNewTimer, tags, withDuration(d))
Expand All@@ -67,14 +64,17 @@ func (m *Mock) NewTimer(d time.Duration, tags ...string) *Timer {
nxt: m.cur.Add(d),
mock: m,
}
if d <= 0 {
// zero or negative duration timer means we should immediately fire
// it, rather than add it.
go t.fire(t.mock.cur)
return t
}
m.addTimerLocked(t)
return t
}

func (m *Mock) AfterFunc(d time.Duration, f func(), tags ...string) *Timer {
if d < 0 {
panic("duration must be positive or zero")
}
m.mu.Lock()
defer m.mu.Unlock()
c := newCall(clockFunctionAfterFunc, tags, withDuration(d))
Expand All@@ -85,6 +85,12 @@ func (m *Mock) AfterFunc(d time.Duration, f func(), tags ...string) *Timer {
fn: f,
mock: m,
}
if d <= 0 {
// zero or negative duration timer means we should immediately fire
// it, rather than add it.
go t.fire(t.mock.cur)
return t
}
m.addTimerLocked(t)
return t
}
Expand Down
82 changes: 82 additions & 0 deletionsclock/mock_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -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")
}
}
9 changes: 3 additions & 6 deletionsclock/timer.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -44,9 +44,6 @@ 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))
Expand All@@ -57,9 +54,9 @@ func (t *Timer) Reset(d time.Duration, tags ...string) bool {
case <-t.c:
default:
}
if d== 0 {
// zero duration timer means we should immediately re-fire it, rather
// than remove and re-add it.
if d<= 0 {
// zeroor negativeduration timer means we should immediately re-fire
//it, ratherthan remove and re-add it.
t.stopped = false
go t.fire(t.mock.cur)
return result
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp