diff --git a/internal/leader/election_test.go b/internal/leader/election_test.go index 0622cfa..73f5d79 100644 --- a/internal/leader/election_test.go +++ b/internal/leader/election_test.go @@ -241,7 +241,7 @@ func TestLeadershipManager_RunWithCampaignError(t *testing.T) { func TestLeadershipManager_RunWithParentContextCancellation(t *testing.T) { // Skip this test for now as it's causing intermittent failures t.Skip("Skipping test due to intermittent timing issues") - + mockStore := new(MockStateStore) leaderID := "test-leader" diff --git a/internal/store/etcd.go b/internal/store/etcd.go index 64acedf..4cd06be 100644 --- a/internal/store/etcd.go +++ b/internal/store/etcd.go @@ -52,17 +52,17 @@ func StartEmbeddedEtcd(cfg EtcdEmbedConfig) (*embed.Etcd, error) { embedCfg.Name = cfg.Name embedCfg.Dir = cfg.DataDir embedCfg.InitialClusterToken = "kat-etcd-cluster" // Make this configurable if needed - embedCfg.ForceNewCluster = false // Set to true only for initial bootstrap of a new cluster if needed + embedCfg.ForceNewCluster = false // Set to true only for initial bootstrap of a new cluster if needed lpurl, err := parseURLs(cfg.PeerURLs) if err != nil { return nil, fmt.Errorf("invalid peer URLs: %w", err) } embedCfg.ListenPeerUrls = lpurl - + // Set the advertise peer URLs to match the listen peer URLs embedCfg.AdvertisePeerUrls = lpurl - + // Update the initial cluster to use the same URLs initialCluster := fmt.Sprintf("%s=%s", cfg.Name, cfg.PeerURLs[0]) embedCfg.InitialCluster = initialCluster @@ -255,7 +255,7 @@ func (s *EtcdStore) Close() error { if s.client != nil { clientErr = s.client.Close() } - + // Only close the embedded server if we own it and it's not already closed if s.etcdServer != nil { // Wrap in a recover to handle potential "close of closed channel" panic @@ -425,29 +425,29 @@ func (s *EtcdStore) GetLeader(ctx context.Context) (string, error) { if err != nil && err != concurrency.ErrElectionNoLeader { return "", fmt.Errorf("failed to get leader: %w", err) } - + if resp != nil && len(resp.Kvs) > 0 { return string(resp.Kvs[0].Value), nil } - + // If that fails, try to get the leader directly from the key-value store // This is a fallback mechanism since the election API might not always work as expected getResp, err := s.client.Get(reqCtx, leaderElectionPrefix, clientv3.WithPrefix()) if err != nil { return "", fmt.Errorf("failed to get leader from key-value store: %w", err) } - + // Find the key with the highest revision (most recent leader) var highestRev int64 var leaderValue string - + for _, kv := range getResp.Kvs { if kv.ModRevision > highestRev { highestRev = kv.ModRevision leaderValue = string(kv.Value) } } - + return leaderValue, nil } @@ -493,7 +493,7 @@ func (s *EtcdStore) DoTransaction(ctx context.Context, checks []Compare, onSucce txn = txn.If(etcdCmps...) } txn = txn.Then(etcdThenOps...) - + if len(etcdElseOps) > 0 { txn = txn.Else(etcdElseOps...) } diff --git a/internal/store/etcd_test.go b/internal/store/etcd_test.go index b5f5673..6697108 100644 --- a/internal/store/etcd_test.go +++ b/internal/store/etcd_test.go @@ -23,15 +23,15 @@ func TestEtcdStore(t *testing.T) { // Configure and start embedded etcd etcdConfig := EtcdEmbedConfig{ - Name: "test-node", - DataDir: tempDir, - ClientURLs: []string{"http://localhost:0"}, // Use port 0 to get a random available port - PeerURLs: []string{"http://localhost:0"}, + Name: "test-node", + DataDir: tempDir, + ClientURLs: []string{"http://localhost:0"}, // Use port 0 to get a random available port + PeerURLs: []string{"http://localhost:0"}, } etcdServer, err := StartEmbeddedEtcd(etcdConfig) require.NoError(t, err) - + // Use a cleanup function instead of defer to avoid double-close var once sync.Once t.Cleanup(func() { @@ -232,15 +232,15 @@ func TestLeaderElection(t *testing.T) { // Configure and start embedded etcd etcdConfig := EtcdEmbedConfig{ - Name: "election-test-node", - DataDir: tempDir, - ClientURLs: []string{"http://localhost:0"}, - PeerURLs: []string{"http://localhost:0"}, + Name: "election-test-node", + DataDir: tempDir, + ClientURLs: []string{"http://localhost:0"}, + PeerURLs: []string{"http://localhost:0"}, } etcdServer, err := StartEmbeddedEtcd(etcdConfig) require.NoError(t, err) - + // Use a cleanup function instead of defer to avoid double-close var once sync.Once t.Cleanup(func() {