1 package embed_test
2
3 import (
4 "context"
5 "os"
6 "testing"
7 "time"
8
9 "github.com/go-logr/logr/testr"
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12 ctrl "sigs.k8s.io/controller-runtime"
13
14 "edge-infra.dev/pkg/sds/lib/etcd/client"
15 "edge-infra.dev/pkg/sds/lib/etcd/client/retry"
16 "edge-infra.dev/pkg/sds/lib/etcd/server/embed"
17 )
18
19 func setupTestCtx(t *testing.T) context.Context {
20 logOptions := testr.Options{
21 LogTimestamp: true,
22 Verbosity: -1,
23 }
24
25 ctx := ctrl.LoggerInto(context.Background(), testr.NewWithOptions(t, logOptions))
26 return ctx
27 }
28
29 func TestMain(m *testing.M) {
30 os.Exit(m.Run())
31 }
32
33 func TestCluster(t *testing.T) {
34 ctx := setupTestCtx(t)
35
36 c, err := initialCluster()
37 require.NoError(t, err)
38
39 require.NoError(t, c.Start(ctx))
40 defer c.Close(ctx)
41 require.Equal(t, 2, c.Size(), "The two initial members should be present in the initial cluster")
42
43 cli, err := createClient(c.ClientURLs()...)
44 require.NoError(t, err)
45
46 require.NoError(t, addNewMember(ctx, cli, c))
47
48 require.NoError(t, c.Stop(ctx))
49 require.NoError(t, c.Start(ctx))
50
51 for _, endpoint := range c.ClientURLs() {
52 _, err := cli.SafeStatus(ctx, endpoint)
53 assert.NoError(t, err)
54 }
55 }
56
57 func initialCluster() (*embed.Cluster, error) {
58 m1, err := embed.NewMember(&embed.Config{Name: "member-1"})
59 if err != nil {
60 return nil, err
61 }
62 m2, err := embed.NewMember(&embed.Config{Name: "member-2"})
63 if err != nil {
64 return nil, err
65 }
66
67 c, err := embed.NewCluster(m1, m2)
68 if err != nil {
69 return nil, err
70 }
71 return c, nil
72 }
73
74 func createClient(clientURLs ...string) (retry.Retrier, error) {
75 cli, err := client.New(nil, 5*time.Second, clientURLs...)
76 if err != nil {
77 return nil, err
78 }
79
80 config := retry.Config{
81 RequestTimeout: 500 * time.Millisecond,
82 InitialBackoff: 500 * time.Millisecond,
83 BackoffFactor: 1,
84 MaxRetries: 10,
85 }
86 return retry.New(*cli, config), nil
87 }
88
89 func addNewMember(ctx context.Context, cli retry.Retrier, c *embed.Cluster) error {
90 m3, err := embed.NewMember(&embed.Config{Name: "member-3"})
91 if err != nil {
92 return err
93 }
94
95 startFn, err := c.AddMember(m3)
96 if err != nil {
97 return err
98 }
99
100 maresp, err := cli.SafeMemberAddAsLearner(ctx, []string{m3.PeerURL().String()})
101 if err != nil {
102 return err
103 }
104 if err := startFn(); err != nil {
105 return err
106 }
107
108 _, err = cli.SafeMemberPromote(ctx, maresp.Member.ID)
109 if err != nil {
110 return err
111 }
112 return nil
113 }
114
View as plain text