github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/cluster/clusterproviders/etcd/etcd_provider_test.go (about) 1 package etcd 2 3 import ( 4 "fmt" 5 "net" 6 "strconv" 7 "testing" 8 "time" 9 10 "github.com/asynkron/protoactor-go/actor" 11 "github.com/asynkron/protoactor-go/cluster" 12 "github.com/asynkron/protoactor-go/remote" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 func newClusterForTest(name string, addr string, cp cluster.ClusterProvider) *cluster.Cluster { 17 host, _port, err := net.SplitHostPort(addr) 18 if err != nil { 19 panic(err) 20 } 21 port, _ := strconv.Atoi(_port) 22 remoteConfig := remote.Configure(host, port) 23 config := cluster.Configure(name, cp, nil, remoteConfig) 24 25 system := actor.NewActorSystem() 26 c := cluster.New(system, config) 27 // use for test without start remote 28 c.ActorSystem.ProcessRegistry.Address = addr 29 c.MemberList = cluster.NewMemberList(c) 30 c.Remote = remote.NewRemote(c.ActorSystem, c.Config.RemoteConfig) 31 32 return c 33 } 34 35 func TestStartMember(t *testing.T) { 36 if testing.Short() { 37 return 38 } 39 40 a := assert.New(t) 41 42 p, err := New() 43 a.NoError(err) 44 defer p.Shutdown(true) 45 46 c := newClusterForTest("test_etcd_provider", "127.0.0.1:8000", p) 47 eventstream := c.ActorSystem.EventStream 48 ch := make(chan interface{}, 16) 49 50 eventstream.Subscribe(func(m interface{}) { 51 if _, ok := m.(*cluster.ClusterTopology); ok { 52 ch <- m 53 } 54 }) 55 56 err = p.StartMember(c) 57 a.NoError(err) 58 59 select { 60 case <-time.After(5 * time.Second): 61 a.FailNow("no member joined yet") 62 63 case m := <-ch: 64 // member joined 65 msg, _ := m.(*cluster.ClusterTopology) 66 67 members := []*cluster.Member{ 68 { 69 // Id: "test_etcd_provider@127.0.0.1:8000", 70 Id: fmt.Sprintf("test_etcd_provider@%s", c.ActorSystem.ID), 71 Host: "127.0.0.1", 72 Port: 8000, 73 Kinds: []string{}, 74 }, 75 } 76 77 expected := &cluster.ClusterTopology{ 78 Members: members, 79 Joined: members, 80 Left: []*cluster.Member{}, 81 TopologyHash: msg.TopologyHash, 82 } 83 a.Equal(expected, msg) 84 85 } 86 } 87 88 func TestStartMember_Multiple(t *testing.T) { 89 if testing.Short() { 90 return 91 } 92 93 a := assert.New(t) 94 members := []struct { 95 cluster string 96 host string 97 port int 98 }{ 99 {"mycluster2", "127.0.0.1", 8001}, 100 {"mycluster2", "127.0.0.1", 8002}, 101 {"mycluster2", "127.0.0.1", 8003}, 102 } 103 104 p := make([]*Provider, len(members)) 105 106 var err error 107 108 t.Cleanup(func() { 109 for i := range p { 110 _ = p[i].Shutdown(true) 111 } 112 }) 113 114 for i, member := range members { 115 addr := fmt.Sprintf("%s:%d", member.host, member.port) 116 p[i], err = New() 117 a.NoError(err) 118 119 c := newClusterForTest(member.cluster, addr, p[i]) 120 err := p[i].StartMember(c) 121 a.NoError(err) 122 } 123 124 isNodesEqual := func(nodes []*Node) bool { 125 for _, node := range nodes { 126 for _, member := range members { 127 if node.Host == member.host && node.Port == member.port { 128 return true 129 } 130 } 131 } 132 133 return false 134 } 135 136 for i := range p { 137 nodes, err := p[i].fetchNodes() 138 a.NoError(err) 139 a.Equal(len(members), len(nodes)) 140 flag := isNodesEqual(nodes) 141 a.Truef(flag, "Member not found - %+v", p[i].self) 142 } 143 } 144 145 //func TestUpdateMemberState(t *testing.T) { 146 // if testing.Short() { 147 // return 148 // } 149 // assert := assert.New(t) 150 // 151 // p, _ := New() 152 // defer p.Shutdown(true) 153 // 154 // c := newClusterForTest("mycluster3", "127.0.0.1:8000", p) 155 // err := p.StartMember(c) 156 // assert.NoError(err) 157 // 158 // state := cluster.ClusterState{[]string{"yes"}} 159 // err = p.UpdateClusterState(state) 160 // assert.NoError(err) 161 //} 162 // 163 //func TestUpdateMemberState_DoesNotReregisterAfterShutdown(t *testing.T) { 164 // if testing.Short() { 165 // return 166 // } 167 // assert := assert.New(t) 168 // 169 // p, _ := New() 170 // c := newClusterForTest("mycluster4", "127.0.0.1:8001", p) 171 // err := p.StartMember(c) 172 // assert.NoError(err) 173 // t.Cleanup(func() { 174 // p.Shutdown(true) 175 // }) 176 // 177 // state := cluster.ClusterState{[]string{"yes"}} 178 // err = p.UpdateClusterState(state) 179 // assert.NoError(err) 180 // 181 // err = p.Shutdown(true) 182 // assert.NoError(err) 183 // 184 // err = p.UpdateClusterState(state) 185 // assert.Error(err) 186 //}