1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
4.2 KiB
Go

package disco
import (
"sync"
"testing"
"time"
)
func Test_NewServce(t *testing.T) {
s := NewService(&mockClient{}, &mockStore{})
if s == nil {
t.Fatalf("service is nil")
}
}
func Test_RegisterGetLeaderOK(t *testing.T) {
m := &mockClient{}
m.getLeaderFn = func() (id string, apiAddr string, addr string, ok bool, e error) {
return "2", "localhost:4003", "localhost:4004", true, nil
}
m.initializeLeaderFn = func(tID, tAPIAddr, tAddr string) (bool, error) {
t.Fatalf("Leader initialized unexpectedly")
return false, nil
}
c := &mockStore{}
s := NewService(m, c)
s.RegisterInterval = 10 * time.Millisecond
ok, addr, err := s.Register("1", "localhost:4001", "localhost:4002")
if err != nil {
t.Fatalf("error registering with disco: %s", err.Error())
}
if ok {
t.Fatalf("registered as leader unexpectedly")
}
if exp, got := "localhost:4003", addr; exp != got {
t.Fatalf("returned addressed incorrect, exp %s, got %s", exp, got)
}
}
func Test_RegisterInitializeLeader(t *testing.T) {
m := &mockClient{}
m.getLeaderFn = func() (id string, apiAddr string, addr string, ok bool, e error) {
return "", "", "", false, nil
}
m.initializeLeaderFn = func(tID, tAPIAddr, tAddr string) (bool, error) {
if tID != "1" || tAPIAddr != "localhost:4001" || tAddr != "localhost:4002" {
t.Fatalf("wrong values passed to InitializeLeader")
}
return true, nil
}
c := &mockStore{}
s := NewService(m, c)
s.RegisterInterval = 10 * time.Millisecond
ok, addr, err := s.Register("1", "localhost:4001", "localhost:4002")
if err != nil {
t.Fatalf("error registering with disco: %s", err.Error())
}
if !ok {
t.Fatalf("failed to register as expected")
}
if exp, got := "localhost:4001", addr; exp != got {
t.Fatalf("returned addressed incorrect, exp %s, got %s", exp, got)
}
}
func Test_StartReportingTimer(t *testing.T) {
// WaitGroups won't work because we don't know how many times
// setLeaderFn will be called.
calledCh := make(chan struct{}, 10)
m := &mockClient{}
m.setLeaderFn = func(id, apiAddr, addr string) error {
if id != "1" || apiAddr != "localhost:4001" || addr != "localhost:4002" {
t.Fatalf("wrong values passed to SetLeader")
}
calledCh <- struct{}{}
return nil
}
c := &mockStore{}
c.isLeaderFn = func() bool {
return true
}
s := NewService(m, c)
s.ReportInterval = 10 * time.Millisecond
go s.StartReporting("1", "localhost:4001", "localhost:4002")
<-calledCh
}
func Test_StartReportingChange(t *testing.T) {
var wg sync.WaitGroup
m := &mockClient{}
m.setLeaderFn = func(id, apiAddr, addr string) error {
defer wg.Done()
if id != "1" || apiAddr != "localhost:4001" || addr != "localhost:4002" {
t.Fatalf("wrong values passed to SetLeader")
}
return nil
}
c := &mockStore{}
c.isLeaderFn = func() bool {
return true
}
var ch chan<- struct{}
c.registerLeaderChangeFn = func(c chan<- struct{}) {
ch = c
}
wg.Add(1)
s := NewService(m, c)
s.ReportInterval = 10 * time.Minute // Nothing will happen due to timer.
done := s.StartReporting("1", "localhost:4001", "localhost:4002")
// Signal a leadership change.
ch <- struct{}{}
wg.Wait()
close(done)
}
type mockClient struct {
getLeaderFn func() (id string, apiAddr string, addr string, ok bool, e error)
initializeLeaderFn func(id, apiAddr, addr string) (bool, error)
setLeaderFn func(id, apiAddr, addr string) error
}
func (m *mockClient) GetLeader() (id string, apiAddr string, addr string, ok bool, e error) {
if m.getLeaderFn != nil {
return m.getLeaderFn()
}
return
}
func (m *mockClient) InitializeLeader(id, apiAddr, addr string) (bool, error) {
if m.initializeLeaderFn != nil {
return m.initializeLeaderFn(id, apiAddr, addr)
}
return false, nil
}
func (m *mockClient) SetLeader(id, apiAddr, addr string) error {
if m.setLeaderFn != nil {
return m.setLeaderFn(id, apiAddr, addr)
}
return nil
}
func (m *mockClient) String() string {
return "mock"
}
type mockStore struct {
isLeaderFn func() bool
registerLeaderChangeFn func(c chan<- struct{})
}
func (m *mockStore) IsLeader() bool {
if m.isLeaderFn != nil {
return m.isLeaderFn()
}
return false
}
func (m *mockStore) RegisterLeaderChange(c chan<- struct{}) {
if m.registerLeaderChangeFn != nil {
m.registerLeaderChangeFn(c)
}
}