mirror of https://github.com/docker/docs.git
65 lines
1.6 KiB
Go
65 lines
1.6 KiB
Go
package leadership
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
libkvmock "github.com/docker/libkv/store/mock"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
func TestCandidate(t *testing.T) {
|
|
kv, err := libkvmock.New([]string{}, nil)
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, kv)
|
|
|
|
mockStore := kv.(*libkvmock.Mock)
|
|
mockLock := &libkvmock.Lock{}
|
|
mockStore.On("NewLock", "test_key", mock.Anything).Return(mockLock, nil)
|
|
|
|
// Lock and unlock always succeeds.
|
|
lostCh := make(chan struct{})
|
|
var mockLostCh <-chan struct{} = lostCh
|
|
mockLock.On("Lock").Return(mockLostCh, nil)
|
|
mockLock.On("Unlock").Return(nil)
|
|
|
|
candidate := NewCandidate(kv, "test_key", "test_node")
|
|
electedCh, _ := candidate.RunForElection()
|
|
|
|
// Should issue a false upon start, no matter what.
|
|
assert.False(t, <-electedCh)
|
|
|
|
// Since the lock always succeeeds, we should get elected.
|
|
assert.True(t, <-electedCh)
|
|
assert.True(t, candidate.IsLeader())
|
|
|
|
// Signaling a lost lock should get us de-elected...
|
|
close(lostCh)
|
|
assert.False(t, <-electedCh)
|
|
|
|
// And we should attempt to get re-elected again.
|
|
assert.True(t, <-electedCh)
|
|
|
|
// When we resign, unlock will get called, we'll be notified of the
|
|
// de-election and we'll try to get the lock again.
|
|
go candidate.Resign()
|
|
assert.False(t, <-electedCh)
|
|
assert.True(t, <-electedCh)
|
|
|
|
candidate.Stop()
|
|
|
|
// Ensure that the chan closes after some time
|
|
for {
|
|
select {
|
|
case _, open := <-electedCh:
|
|
if !open {
|
|
mockStore.AssertExpectations(t)
|
|
return
|
|
}
|
|
case <-time.After(1 * time.Second):
|
|
t.Fatalf("electedCh not closed correctly")
|
|
}
|
|
}
|
|
}
|