go-ethereum/common/countdown/countdown_test.go

157 lines
4.2 KiB
Go

package countdown
import (
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestCountdownWillCallback(t *testing.T) {
var fakeI interface{}
called := make(chan int)
OnTimeoutFn := func(time.Time, interface{}) error {
called <- 1
return nil
}
countdown := NewCountDown(1000 * time.Millisecond)
countdown.OnTimeoutFn = OnTimeoutFn
countdown.Reset(fakeI)
<-called
t.Log("Times up, successfully called OnTimeoutFn")
}
func TestCountdownShouldReset(t *testing.T) {
var fakeI interface{}
called := make(chan int)
OnTimeoutFn := func(time.Time, interface{}) error {
called <- 1
return nil
}
countdown := NewCountDown(5000 * time.Millisecond)
countdown.OnTimeoutFn = OnTimeoutFn
// Check countdown did not start
assert.False(t, countdown.isInitilised())
countdown.Reset(fakeI)
// Now the countdown should already started
assert.True(t, countdown.isInitilised())
expectedCalledTime := time.Now().Add(9000 * time.Millisecond)
resetTimer := time.NewTimer(4000 * time.Millisecond)
firstReset:
for {
select {
case <-called:
if time.Now().After(expectedCalledTime) {
// Make sure the countdown runs forever
assert.True(t, countdown.isInitilised())
t.Log("Correctly reset the countdown once")
} else {
t.Fatalf("Countdown did not reset correctly first time")
}
break firstReset
case <-resetTimer.C:
countdown.Reset(fakeI)
}
}
// Now the countdown is paused after calling the callback function, let's reset it again
assert.True(t, countdown.isInitilised())
expectedTimeAfterReset := time.Now().Add(5000 * time.Millisecond)
<-called
// Always initilised
assert.True(t, countdown.isInitilised())
if time.Now().After(expectedTimeAfterReset) {
t.Log("Correctly reset the countdown second time")
} else {
t.Fatalf("Countdown did not reset correctly second time")
}
}
func TestCountdownShouldResetEvenIfErrored(t *testing.T) {
var fakeI interface{}
called := make(chan int)
OnTimeoutFn := func(time.Time, interface{}) error {
called <- 1
return errors.New("ERROR!")
}
countdown := NewCountDown(5000 * time.Millisecond)
countdown.OnTimeoutFn = OnTimeoutFn
// Check countdown did not start
assert.False(t, countdown.isInitilised())
countdown.Reset(fakeI)
// Now the countdown should already started
assert.True(t, countdown.isInitilised())
expectedCalledTime := time.Now().Add(9000 * time.Millisecond)
resetTimer := time.NewTimer(4000 * time.Millisecond)
firstReset:
for {
select {
case <-called:
if time.Now().After(expectedCalledTime) {
// Make sure the countdown runs forever
assert.True(t, countdown.isInitilised())
t.Log("Correctly reset the countdown once")
} else {
t.Fatalf("Countdown did not reset correctly first time")
}
break firstReset
case <-resetTimer.C:
countdown.Reset(fakeI)
}
}
// Now the countdown is paused after calling the callback function, let's reset it again
assert.True(t, countdown.isInitilised())
expectedTimeAfterReset := time.Now().Add(5000 * time.Millisecond)
<-called
// Always initilised
assert.True(t, countdown.isInitilised())
if time.Now().After(expectedTimeAfterReset) {
t.Log("Correctly reset the countdown second time")
} else {
t.Fatalf("Countdown did not reset correctly second time")
}
}
func TestCountdownShouldBeAbleToStop(t *testing.T) {
var fakeI interface{}
called := make(chan int)
OnTimeoutFn := func(time.Time, interface{}) error {
called <- 1
return nil
}
countdown := NewCountDown(5000 * time.Millisecond)
countdown.OnTimeoutFn = OnTimeoutFn
// Check countdown did not start
assert.False(t, countdown.isInitilised())
countdown.Reset(fakeI)
// Now the countdown should already started
assert.True(t, countdown.isInitilised())
// Try manually stop the timer before it triggers the callback
stopTimer := time.NewTimer(4000 * time.Millisecond)
<-stopTimer.C
countdown.StopTimer()
assert.False(t, countdown.isInitilised())
}
func TestCountdownShouldAvoidDeadlock(t *testing.T) {
var fakeI interface{}
called := make(chan int)
countdown := NewCountDown(5000 * time.Millisecond)
OnTimeoutFn := func(time.Time, interface{}) error {
countdown.Reset(fakeI)
called <- 1
return nil
}
countdown.OnTimeoutFn = OnTimeoutFn
countdown.Reset(fakeI)
<-called
}