lnd/cluster/etcd_elector_test.go
Eng Zer Jun 5d5ad9ce65
cluster: use T.TempDir to create temporary test directory
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2022-08-24 08:58:16 +08:00

103 lines
1.9 KiB
Go

//go:build kvdb_etcd
// +build kvdb_etcd
package cluster
import (
"context"
"os"
"runtime/pprof"
"sync"
"testing"
"time"
"github.com/lightningnetwork/lnd/kvdb/etcd"
"github.com/stretchr/testify/require"
)
// GuardTimeout implements a test level timeout guard.
func GuardTimeout(t *testing.T, timeout time.Duration) func() {
done := make(chan struct{})
go func() {
select {
case <-time.After(timeout):
err := pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
require.NoError(t, err)
panic("test timeout")
case <-done:
}
}()
return func() {
close(done)
}
}
// TestEtcdElector tests that two candidates competing for leadership works as
// expected and that elected leader can resign and allow others to take on.
func TestEtcdElector(t *testing.T) {
guard := GuardTimeout(t, 5*time.Second)
defer guard()
tmpDir := t.TempDir()
etcdCfg, cleanup, err := etcd.NewEmbeddedEtcdInstance(tmpDir, 0, 0, "")
require.NoError(t, err)
defer cleanup()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
const (
election = "/election/"
id1 = "e1"
id2 = "e2"
ttl = 5
)
e1, err := newEtcdLeaderElector(
ctx, id1, election, ttl, etcdCfg,
)
require.NoError(t, err)
e2, err := newEtcdLeaderElector(
ctx, id2, election, ttl, etcdCfg,
)
require.NoError(t, err)
var wg sync.WaitGroup
ch := make(chan *etcdLeaderElector)
wg.Add(2)
ctxb := context.Background()
go func() {
defer wg.Done()
require.NoError(t, e1.Campaign(ctxb))
ch <- e1
}()
go func() {
defer wg.Done()
require.NoError(t, e2.Campaign(ctxb))
ch <- e2
}()
tmp := <-ch
first, err := tmp.Leader(ctxb)
require.NoError(t, err)
require.NoError(t, tmp.Resign())
tmp = <-ch
second, err := tmp.Leader(ctxb)
require.NoError(t, err)
require.NoError(t, tmp.Resign())
require.Contains(t, []string{id1, id2}, first)
require.Contains(t, []string{id1, id2}, second)
require.NotEqual(t, first, second)
wg.Wait()
}