wrote manager tests
parent
7e33632f9e
commit
bf2040807c
@ -0,0 +1,206 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// creating, starting and stopping tests
|
||||
|
||||
// newManager is a helper for creating new managers for tests
|
||||
func newManager(conn int, want error, t *testing.T) *Manager {
|
||||
var manager *Manager
|
||||
var err error
|
||||
assert := assert.New(t)
|
||||
|
||||
manager, err = New(conn)
|
||||
|
||||
if err != want {
|
||||
t.Fatalf(
|
||||
`New(%d) = %v, %v, %d max connections failed`,
|
||||
conn,
|
||||
manager,
|
||||
err,
|
||||
conn,
|
||||
)
|
||||
}
|
||||
|
||||
assert.Equal(manager.IsActive(), 0, "manager should start inactive")
|
||||
|
||||
return manager
|
||||
}
|
||||
|
||||
// TestEmptyManager creates a new manager with 0 max connections
|
||||
func TestEmptyManager(t *testing.T) {
|
||||
conn := 0
|
||||
newManager(conn, nil, t)
|
||||
}
|
||||
|
||||
// TestPostiveManager creates a new manager with valid max connections
|
||||
func TestPositiveManager(t *testing.T) {
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
newManager(conn, nil, t)
|
||||
}
|
||||
|
||||
// TestNegativeManager creates a new manager with negative max connections
|
||||
func TestNegativeManager(t *testing.T) {
|
||||
conn := -1 * rand.Intn(MaxConnAttempts)
|
||||
newManager(conn, ErrInvalidMaxConn, t)
|
||||
}
|
||||
|
||||
// TestInvalidManager creates a new manager with large max connections
|
||||
func TestInvalidManager(t *testing.T) {
|
||||
conn := MaxConnAttempts + 0xf
|
||||
newManager(conn, ErrInvalidMaxConn, t)
|
||||
}
|
||||
|
||||
// TestManagerLifeCycle tests that a manager can start and exit several times
|
||||
func TestManagerLifeCycle(t *testing.T) {
|
||||
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
cycles := 10
|
||||
|
||||
// starting and stopping sequentially
|
||||
for i := 0; i < cycles; i++ {
|
||||
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
assert.Equal(manager.IsActive(), 1, "manager is inactive after start")
|
||||
|
||||
assert.NoError(manager.Stop(), "stopping manager failed")
|
||||
assert.Equal(manager.IsActive(), 0, "manager is active after stop")
|
||||
}
|
||||
}
|
||||
|
||||
// TestManagerStopFail tests that stopping an inactive manager will error
|
||||
func TestManagerStopFail(t *testing.T) {
|
||||
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
|
||||
// stopping sequentially
|
||||
assert.NoError(manager.Stop(), "stopping manager failed")
|
||||
assert.Error(manager.Stop(), "stopping inactive manager should fail")
|
||||
}
|
||||
|
||||
// TestManagerStartFail tests that starting an active manager will error
|
||||
func TestManagerStartFail(t *testing.T) {
|
||||
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
// starting sequentially
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
assert.Error(manager.Start(), "starting active manager should fail")
|
||||
}
|
||||
|
||||
// auxiliary tests
|
||||
|
||||
// TestManagerTimeout checks that timeouts exponentially backoff
|
||||
func TestManagerTimeout(t *testing.T) {
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := 10
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
assert.Equal(manager.IsActive(), 1, "manager is inactive")
|
||||
|
||||
prevTimeout, err := manager.Timeout()
|
||||
|
||||
for i := 1; i <= conn; i++ {
|
||||
assert.NoError(err, "generating timeout failed")
|
||||
assert.True(prevTimeout > 0, "invalid timeout")
|
||||
|
||||
timeout, err := manager.Timeout()
|
||||
|
||||
if i == conn {
|
||||
assert.Error(err, "allowed exceeding max attempts")
|
||||
} else {
|
||||
assert.NoError(err, "generating timeout failed")
|
||||
assert.True(
|
||||
timeout == 2*prevTimeout,
|
||||
"incorrect timeout %d, expected %d",
|
||||
timeout, 2*prevTimeout,
|
||||
)
|
||||
}
|
||||
|
||||
prevTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// TestManagerHB tests the heartbeat channel opens and closes
|
||||
func TestManagerHB(t *testing.T) {
|
||||
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
assert.Equal(manager.IsActive(), 1, "manager is inactive")
|
||||
|
||||
ch := make(chan struct{})
|
||||
|
||||
go manager.HeartBeat(ch, 10, 0, time.Millisecond)
|
||||
|
||||
for range ch {
|
||||
// close on first ping
|
||||
assert.NoError(manager.Stop(), "stopping manager failed")
|
||||
}
|
||||
|
||||
assert.Equal(manager.IsActive(), 0, "manager is active")
|
||||
}
|
||||
|
||||
// TestManagerHBTiming tests the heartbeat channel timing is correct
|
||||
func TestManagerHBTiming(t *testing.T) {
|
||||
|
||||
var manager *Manager
|
||||
assert := assert.New(t)
|
||||
|
||||
conn := rand.Intn(MaxConnAttempts)
|
||||
manager = newManager(conn, nil, t)
|
||||
|
||||
assert.NoError(manager.Start(), "starting manager failed")
|
||||
assert.Equal(manager.IsActive(), 1, "manager is inactive")
|
||||
|
||||
ch := make(chan struct{})
|
||||
hb := 100
|
||||
pings := 10
|
||||
|
||||
// expected time with some tolerance for other events
|
||||
expected := time.Duration(pings*hb+5) * time.Millisecond
|
||||
|
||||
go manager.HeartBeat(ch, hb, 0, time.Millisecond)
|
||||
|
||||
iter := 0
|
||||
start := time.Now()
|
||||
for range ch {
|
||||
// close after 10 pings
|
||||
iter += 1
|
||||
if iter >= pings {
|
||||
assert.NoError(manager.Stop(), "stopping manager failed")
|
||||
}
|
||||
}
|
||||
end := time.Now()
|
||||
|
||||
assert.Equal(manager.IsActive(), 0, "manager is active")
|
||||
assert.WithinDuration(start, end, expected, "inaccurate heartbeat")
|
||||
}
|
Loading…
Reference in New Issue