From f8271d8506ea734c87719986479c2640c7d1f516 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Wed, 18 Dec 2024 19:47:39 +0000 Subject: [PATCH] Add test for join existing cluster Signed-off-by: Brad Davidson --- pkg/etcd/etcd_test.go | 68 ++++++++++++++++++++++++++++++++++++++----- tests/unit.go | 7 ++++- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/pkg/etcd/etcd_test.go b/pkg/etcd/etcd_test.go index f875a24ad1..52f5d6d461 100644 --- a/pkg/etcd/etcd_test.go +++ b/pkg/etcd/etcd_test.go @@ -2,8 +2,10 @@ package etcd import ( "context" + "encoding/json" "net" "net/http" + "net/http/httptest" "os" "path/filepath" "sync" @@ -27,6 +29,7 @@ import ( "google.golang.org/grpc/reflection" "google.golang.org/grpc/status" utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" ) func init() { @@ -234,6 +237,22 @@ func Test_UnitETCD_Register(t *testing.T) { } func Test_UnitETCD_Start(t *testing.T) { + // dummy supervisor API for testing + var memberAddr string + server := httptest.NewServer(http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if req.URL.Path == "/db/info" { + members := []*etcdserverpb.Member{{ + ClientURLs: []string{"https://" + net.JoinHostPort(memberAddr, "2379")}, + PeerURLs: []string{"https://" + net.JoinHostPort(memberAddr, "2380")}, + }} + resp.Header().Set("Content-Type", "application/json") + json.NewEncoder(resp).Encode(&Members{ + Members: members, + }) + } + })) + defer server.Close() + type contextInfo struct { ctx context.Context cancel context.CancelFunc @@ -265,9 +284,6 @@ func Test_UnitETCD_Start(t *testing.T) { address: mustGetAddress(), name: "default", }, - args: args{ - clientAccessInfo: nil, - }, setup: func(e *ETCD, ctxInfo *contextInfo) error { ctxInfo.ctx, ctxInfo.cancel = context.WithCancel(context.Background()) e.config.EtcdDisableSnapshots = true @@ -294,8 +310,37 @@ func Test_UnitETCD_Start(t *testing.T) { name: "default", cron: cron.New(), }, + setup: func(e *ETCD, ctxInfo *contextInfo) error { + ctxInfo.ctx, ctxInfo.cancel = context.WithCancel(context.Background()) + testutil.GenerateRuntime(e.config) + return nil + }, + teardown: func(e *ETCD, ctxInfo *contextInfo) error { + // RemoveSelf will fail with a specific error, but it still does cleanup for testing purposes + err := e.RemoveSelf(ctxInfo.ctx) + ctxInfo.cancel() + time.Sleep(5 * time.Second) + testutil.CleanupDataDir(e.config) + if err != nil && err.Error() != etcdserver.ErrNotEnoughStartedMembers.Error() { + return err + } + return nil + }, + }, + { + name: "valid clientAccessInfo", + fields: fields{ + config: generateTestConfig(), + address: mustGetAddress(), + name: "default", + cron: cron.New(), + }, args: args{ - clientAccessInfo: nil, + clientAccessInfo: &clientaccess.Info{ + BaseURL: "http://" + server.Listener.Addr().String(), + Username: "server", + Password: "token", + }, }, setup: func(e *ETCD, ctxInfo *contextInfo) error { ctxInfo.ctx, ctxInfo.cancel = context.WithCancel(context.Background()) @@ -322,9 +367,6 @@ func Test_UnitETCD_Start(t *testing.T) { name: "default", cron: cron.New(), }, - args: args{ - clientAccessInfo: nil, - }, setup: func(e *ETCD, ctxInfo *contextInfo) error { ctxInfo.ctx, ctxInfo.cancel = context.WithCancel(context.Background()) if err := testutil.GenerateRuntime(e.config); err != nil { @@ -364,6 +406,18 @@ func Test_UnitETCD_Start(t *testing.T) { if err := e.Start(tt.fields.context.ctx, tt.args.clientAccessInfo); (err != nil) != tt.wantErr { t.Errorf("ETCD.Start() error = %v, wantErr %v", err, tt.wantErr) } + if !tt.wantErr { + memberAddr = e.address + if err := wait.PollUntilContextTimeout(tt.fields.context.ctx, time.Second, time.Minute, true, func(ctx context.Context) (bool, error) { + if _, err := e.getETCDStatus(tt.fields.context.ctx, ""); err != nil { + t.Logf("Waiting to get etcd status: %v", err) + return false, nil + } + return true, nil + }); err != nil { + t.Errorf("Failed to get etcd status: %v", err) + } + } if err := tt.teardown(e, &tt.fields.context); err != nil { t.Errorf("Teardown for ETCD.Start() failed = %v", err) } diff --git a/tests/unit.go b/tests/unit.go index 5bc40cea3b..61aecba649 100644 --- a/tests/unit.go +++ b/tests/unit.go @@ -43,7 +43,12 @@ func CleanupDataDir(cnf *config.Control) { // GenerateRuntime creates a temporary data dir and configures // config.ControlRuntime with all the appropriate certificate keys. func GenerateRuntime(cnf *config.Control) error { - cnf.Runtime = config.NewRuntime(nil) + // reuse ready channel from existing runtime if set + var readyCh <-chan struct{} + if cnf.Runtime != nil { + readyCh = cnf.Runtime.ContainerRuntimeReady + } + cnf.Runtime = config.NewRuntime(readyCh) if err := GenerateDataDir(cnf); err != nil { return err }