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  //}