Skip to content

Commit

Permalink
Merge pull request #14281 from clarkfw/migrate-member-add-tests
Browse files Browse the repository at this point in the history
tests: Migrate member add tests to common framework
  • Loading branch information
serathius authored Sep 6, 2022
2 parents a552655 + fcc076f commit f0c95ca
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 33 deletions.
100 changes: 100 additions & 0 deletions tests/common/member_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import (
"testing"
"time"

"github.com/stretchr/testify/require"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/server/v3/etcdserver"
"go.etcd.io/etcd/tests/v3/framework/testutils"
)

Expand Down Expand Up @@ -52,3 +55,100 @@ func TestMemberList(t *testing.T) {
})
}
}

func TestMemberAdd(t *testing.T) {
testRunner.BeforeTest(t)

learnerTcs := []struct {
name string
learner bool
}{
{
name: "NotLearner",
learner: false,
},
{
name: "Learner",
learner: true,
},
}

quorumTcs := []struct {
name string
strictReconfigCheck bool
waitForQuorum bool
expectError bool
}{
{
name: "StrictReconfigCheck/WaitForQuorum",
strictReconfigCheck: true,
waitForQuorum: true,
expectError: false,
},
{
name: "StrictReconfigCheck/NoWaitForQuorum",
strictReconfigCheck: true,
waitForQuorum: false,
expectError: true,
},
{
name: "DisableStrictReconfigCheck/WaitForQuorum",
strictReconfigCheck: false,
waitForQuorum: true,
expectError: false,
},
{
name: "DisableStrictReconfigCheck/NoWaitForQuorum",
strictReconfigCheck: false,
waitForQuorum: false,
expectError: false,
},
}

for _, learnerTc := range learnerTcs {
for _, quorumTc := range quorumTcs {
for _, clusterTc := range clusterTestCases {
t.Run(learnerTc.name+"/"+quorumTc.name+"/"+clusterTc.name, func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
c := clusterTc.config
if !quorumTc.strictReconfigCheck {
c.DisableStrictReconfigCheck = true
}
clus := testRunner.NewCluster(ctx, t, c)
defer clus.Close()
cc := clus.Client()

testutils.ExecuteUntil(ctx, t, func() {
var addResp *clientv3.MemberAddResponse
var err error
if quorumTc.waitForQuorum {
time.Sleep(etcdserver.HealthInterval)
}
if learnerTc.learner {
addResp, err = cc.MemberAddAsLearner(ctx, "newmember", []string{"http://localhost:123"})
} else {
addResp, err = cc.MemberAdd(ctx, "newmember", []string{"http://localhost:123"})
}
if quorumTc.expectError && c.ClusterSize > 1 {
// calling MemberAdd/MemberAddAsLearner on a single node will not fail,
// whether strictReconfigCheck or whether waitForQuorum
require.ErrorContains(t, err, "etcdserver: unhealthy cluster")
} else {
require.NoError(t, err, "MemberAdd failed")
if addResp.Member == nil {
t.Fatalf("MemberAdd failed, expected: member != nil, got: member == nil")
}
if addResp.Member.ID == 0 {
t.Fatalf("MemberAdd failed, expected: ID != 0, got: ID == 0")
}
if len(addResp.Member.PeerURLs) == 0 {
t.Fatalf("MemberAdd failed, expected: non-empty PeerURLs, got: empty PeerURLs")
}
}
})
})
}
}
}
}
26 changes: 1 addition & 25 deletions tests/e2e/ctl_v3_member_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,7 @@ func TestCtlV3MemberRemoveClientAutoTLS(t *testing.T) {
func TestCtlV3MemberRemovePeerTLS(t *testing.T) {
testCtl(t, memberRemoveTest, withQuorum(), withDisableStrictReconfig(), withCfg(*e2e.NewConfigPeerTLS()))
}
func TestCtlV3MemberAdd(t *testing.T) { testCtl(t, memberAddTest) }
func TestCtlV3MemberAddNoTLS(t *testing.T) { testCtl(t, memberAddTest, withCfg(*e2e.NewConfigNoTLS())) }
func TestCtlV3MemberAddClientTLS(t *testing.T) {
testCtl(t, memberAddTest, withCfg(*e2e.NewConfigClientTLS()))
}
func TestCtlV3MemberAddClientAutoTLS(t *testing.T) {
testCtl(t, memberAddTest, withCfg(*e2e.NewConfigClientAutoTLS()))
}
func TestCtlV3MemberAddPeerTLS(t *testing.T) {
testCtl(t, memberAddTest, withCfg(*e2e.NewConfigPeerTLS()))
}
func TestCtlV3MemberAddForLearner(t *testing.T) { testCtl(t, memberAddForLearnerTest) }
func TestCtlV3MemberUpdate(t *testing.T) { testCtl(t, memberUpdateTest) }
func TestCtlV3MemberUpdate(t *testing.T) { testCtl(t, memberUpdateTest) }
func TestCtlV3MemberUpdateNoTLS(t *testing.T) {
testCtl(t, memberUpdateTest, withCfg(*e2e.NewConfigNoTLS()))
}
Expand Down Expand Up @@ -178,18 +166,6 @@ func ctlV3MemberRemove(cx ctlCtx, ep, memberID, clusterID string) error {
return e2e.SpawnWithExpectWithEnv(cmdArgs, cx.envMap, fmt.Sprintf("%s removed from cluster %s", memberID, clusterID))
}

func memberAddTest(cx ctlCtx) {
if err := ctlV3MemberAdd(cx, fmt.Sprintf("http://localhost:%d", e2e.EtcdProcessBasePort+11), false); err != nil {
cx.t.Fatal(err)
}
}

func memberAddForLearnerTest(cx ctlCtx) {
if err := ctlV3MemberAdd(cx, fmt.Sprintf("http://localhost:%d", e2e.EtcdProcessBasePort+11), true); err != nil {
cx.t.Fatal(err)
}
}

func ctlV3MemberAdd(cx ctlCtx, peerURL string, isLearner bool) error {
cmdArgs := append(cx.PrefixArgs(), "member", "add", "newmember", fmt.Sprintf("--peer-urls=%s", peerURL))
if isLearner {
Expand Down
8 changes: 0 additions & 8 deletions tests/framework/e2e/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,6 @@ func NewConfigClientTLS() *EtcdProcessClusterConfig {
}
}

func NewConfigClientBoth() *EtcdProcessClusterConfig {
return &EtcdProcessClusterConfig{
ClusterSize: 1,
ClientTLS: ClientTLSAndNonTLS,
InitialToken: "new",
}
}

func NewConfigClientAutoTLS() *EtcdProcessClusterConfig {
return &EtcdProcessClusterConfig{
ClusterSize: 1,
Expand Down
8 changes: 8 additions & 0 deletions tests/framework/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,11 @@ func (c integrationClient) Watch(ctx context.Context, key string, opts config.Wa

return c.Client.Watch(ctx, key, opOpts...)
}

func (c integrationClient) MemberAdd(ctx context.Context, _ string, peerAddrs []string) (*clientv3.MemberAddResponse, error) {
return c.Client.MemberAdd(ctx, peerAddrs)
}

func (c integrationClient) MemberAddAsLearner(ctx context.Context, _ string, peerAddrs []string) (*clientv3.MemberAddResponse, error) {
return c.Client.MemberAddAsLearner(ctx, peerAddrs)
}
2 changes: 2 additions & 0 deletions tests/framework/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ type Client interface {
Txn(context context.Context, compares, ifSucess, ifFail []string, o config.TxnOptions) (*clientv3.TxnResponse, error)

MemberList(context context.Context) (*clientv3.MemberListResponse, error)
MemberAdd(context context.Context, name string, peerAddrs []string) (*clientv3.MemberAddResponse, error)
MemberAddAsLearner(context context.Context, name string, peerAddrs []string) (*clientv3.MemberAddResponse, error)

Watch(ctx context.Context, key string, opts config.WatchOptions) clientv3.WatchChan
}

0 comments on commit f0c95ca

Please sign in to comment.