Skip to content

Commit

Permalink
Added PR feedback.
Browse files Browse the repository at this point in the history
  • Loading branch information
hpidcock committed Aug 7, 2022
1 parent 176b0b7 commit 3137a9d
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 49 deletions.
10 changes: 0 additions & 10 deletions testclock/clock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package testclock_test

import (
"sync"
gotesting "testing"
"time"

"github.com/juju/loggo"
Expand All @@ -20,10 +19,6 @@ type clockSuite struct {
testing.LoggingSuite
}

func TestAll(t *gotesting.T) {
gc.TestingT(t)
}

var _ = gc.Suite(&clockSuite{})

func (*clockSuite) TestNow(c *gc.C) {
Expand All @@ -32,11 +27,6 @@ func (*clockSuite) TestNow(c *gc.C) {
c.Assert(cl.Now(), gc.Equals, t0)
}

var (
shortWait = 50 * time.Millisecond
longWait = time.Second
)

func (*clockSuite) TestAdvanceLogs(c *gc.C) {
loggo.GetLogger("juju.clock").SetLogLevel(loggo.DEBUG)
t0 := time.Now()
Expand Down
7 changes: 5 additions & 2 deletions testclock/dilated.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ func (t *dilatedWallTimer) Stop() bool {

func dilateTime(epoch, realNow time.Time,
realSecondDuration, dilatedOffset time.Duration) time.Time {
return epoch.Add(dilatedOffset).
Add(time.Duration(float64(realNow.Sub(epoch)) / realSecondDuration.Seconds()))
delta := realNow.Sub(epoch)
if delta < 0 {
delta = time.Duration(0)
}
return epoch.Add(dilatedOffset).Add(time.Duration(float64(delta) / realSecondDuration.Seconds()))
}
94 changes: 57 additions & 37 deletions testclock/dilated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import (
"github.com/juju/clock/testclock"
)

const (
halfSecond = 500 * time.Millisecond
doubleSecond = 2 * time.Second
)

type dilatedClockSuite struct {
testing.LoggingSuite
}
Expand All @@ -23,21 +28,21 @@ var _ = gc.Suite(&dilatedClockSuite{})

func (*dilatedClockSuite) TestSlowedAfter(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(2 * time.Second)
cl := testclock.NewDilatedWallClock(doubleSecond)
t1 := <-cl.After(time.Second)
c.Assert(t1.Sub(t0).Seconds(), jc.GreaterThan, 1.9)
}

func (*dilatedClockSuite) TestFastAfter(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
cl := testclock.NewDilatedWallClock(halfSecond)
t1 := <-cl.After(time.Second)
c.Assert(t1.Sub(t0).Milliseconds(), jc.LessThan, 600)
}

func (*dilatedClockSuite) TestSlowedAfterFunc(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(2 * time.Second)
cl := testclock.NewDilatedWallClock(doubleSecond)
mut := sync.Mutex{}
mut.Lock()
cl.AfterFunc(time.Second, func() {
Expand All @@ -49,7 +54,7 @@ func (*dilatedClockSuite) TestSlowedAfterFunc(c *gc.C) {

func (*dilatedClockSuite) TestFastAfterFunc(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
cl := testclock.NewDilatedWallClock(halfSecond)
mut := sync.Mutex{}
mut.Lock()
cl.AfterFunc(time.Second, func() {
Expand All @@ -61,7 +66,7 @@ func (*dilatedClockSuite) TestFastAfterFunc(c *gc.C) {

func (*dilatedClockSuite) TestSlowedNow(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(2 * time.Second)
cl := testclock.NewDilatedWallClock(doubleSecond)
<-time.After(time.Second)
t2 := cl.Now()
c.Assert(t2.Sub(t0).Milliseconds(), jc.GreaterThan, 400)
Expand All @@ -74,7 +79,7 @@ func (*dilatedClockSuite) TestSlowedNow(c *gc.C) {

func (*dilatedClockSuite) TestFastNow(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
cl := testclock.NewDilatedWallClock(halfSecond)
<-time.After(time.Second)
t2 := cl.Now()
c.Assert(t2.Sub(t0).Milliseconds(), jc.GreaterThan, 1900)
Expand All @@ -87,27 +92,30 @@ func (*dilatedClockSuite) TestFastNow(c *gc.C) {

func (*dilatedClockSuite) TestAdvance(c *gc.C) {
t0 := time.Now()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
first := cl.After(1 * time.Second)
cl.Advance(500 * time.Millisecond)
cl := testclock.NewDilatedWallClock(halfSecond)
first := cl.After(time.Second)
cl.Advance(halfSecond)
<-time.After(250 * time.Millisecond)
select {
case t := <-first:
c.Assert(t.Sub(t0).Milliseconds(), jc.GreaterThan, 249)
case <-time.After(50 * time.Millisecond):
case <-time.After(shortWait):
c.Fatal("timer failed to trigger early")
}
}

func (*dilatedClockSuite) TestAdvanceMulti(c *gc.C) {
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
first := cl.After(1 * time.Second)
cl := testclock.NewDilatedWallClock(halfSecond)
first := cl.After(time.Second)
second := cl.After(2 * time.Second)
third := cl.After(1 * time.Hour)
fourth := cl.After(24 * time.Hour)

done := time.After(longWait)
fourth := cl.After(12*time.Hour + longWait*2 + time.Second)

cl.Advance(12 * time.Hour)

n := 0
done := time.After(10 * time.Second)
out:
for {
select {
Expand All @@ -128,57 +136,69 @@ out:

func (*dilatedClockSuite) TestStop(c *gc.C) {
numGo := runtime.NumGoroutine()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
a := cl.NewTimer(1 * time.Second)
time.Sleep(100 * time.Millisecond)
cl := testclock.NewDilatedWallClock(halfSecond)
a := cl.NewTimer(time.Second)
time.Sleep(shortWait)
ok := a.Stop()
c.Assert(ok, jc.IsTrue)
ok = a.Stop()
c.Assert(ok, jc.IsFalse)
select {
case <-a.Chan():
c.Fatal("stopped clock fired")
case <-time.After(1 * time.Second):
case <-time.After(time.Second):
}
time.Sleep(50 * time.Millisecond)
numGoAfter := runtime.NumGoroutine()
c.Assert(numGoAfter, gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
for i := 0; i < 3; i++ {
if runtime.NumGoroutine() == numGo {
break
}
time.Sleep(shortWait)
}
c.Assert(runtime.NumGoroutine(), gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
}

func (*dilatedClockSuite) TestReset(c *gc.C) {
numGo := runtime.NumGoroutine()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
a := cl.NewTimer(1 * time.Second)
cl := testclock.NewDilatedWallClock(halfSecond)
a := cl.NewTimer(time.Second)
time.Sleep(250 * time.Millisecond)
ok := a.Reset(1 * time.Second)
ok := a.Reset(time.Second)
c.Assert(ok, jc.IsTrue)
<-time.After(500 * time.Millisecond)
<-time.After(halfSecond)
select {
case <-a.Chan():
case <-time.After(50 * time.Millisecond):
case <-time.After(shortWait):
c.Fatal("clock did not fire")
}
time.Sleep(50 * time.Millisecond)
numGoAfter := runtime.NumGoroutine()
c.Assert(numGoAfter, gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
for i := 0; i < 3; i++ {
if runtime.NumGoroutine() == numGo {
break
}
time.Sleep(shortWait)
}
c.Assert(runtime.NumGoroutine(), gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
}

func (*dilatedClockSuite) TestStopReset(c *gc.C) {
numGo := runtime.NumGoroutine()
cl := testclock.NewDilatedWallClock(500 * time.Millisecond)
a := cl.NewTimer(1 * time.Second)
cl := testclock.NewDilatedWallClock(halfSecond)
a := cl.NewTimer(time.Second)
time.Sleep(250 * time.Millisecond)
ok := a.Stop()
c.Assert(ok, jc.IsTrue)
ok = a.Reset(1 * time.Second)
ok = a.Reset(time.Second)
c.Assert(ok, jc.IsTrue)
<-time.After(500 * time.Millisecond)
<-time.After(halfSecond)
select {
case <-a.Chan():
case <-time.After(50 * time.Millisecond):
case <-time.After(shortWait):
c.Fatal("clock did not fire")
}
time.Sleep(50 * time.Millisecond)
numGoAfter := runtime.NumGoroutine()
c.Assert(numGoAfter, gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
for i := 0; i < 3; i++ {
if runtime.NumGoroutine() == numGo {
break
}
time.Sleep(shortWait)
}
c.Assert(runtime.NumGoroutine(), gc.Equals, numGo, gc.Commentf("clock goroutine still running"))
}
3 changes: 3 additions & 0 deletions testclock/interfaces.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Copyright 2022 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package testclock

import (
Expand Down
20 changes: 20 additions & 0 deletions testclock/package_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2022 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package testclock_test

import (
gotesting "testing"
"time"

gc "gopkg.in/check.v1"
)

func TestAll(t *gotesting.T) {
gc.TestingT(t)
}

const (
shortWait = 50 * time.Millisecond
longWait = time.Second
)

0 comments on commit 3137a9d

Please sign in to comment.