mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
kubeadm: increase ut coverage for util/etcd
Signed-off-by: xin.li <xin.li@daocloud.io>
This commit is contained in:
parent
e6acd1caf5
commit
430fd83454
@ -104,6 +104,8 @@ type Client struct {
|
|||||||
Endpoints []string
|
Endpoints []string
|
||||||
|
|
||||||
newEtcdClient func(endpoints []string) (etcdClient, error)
|
newEtcdClient func(endpoints []string) (etcdClient, error)
|
||||||
|
|
||||||
|
listMembersFunc func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new EtcdCluster client
|
// New creates a new EtcdCluster client
|
||||||
@ -135,6 +137,8 @@ func New(endpoints []string, ca, cert, key string) (*Client, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client.listMembersFunc = client.listMembers
|
||||||
|
|
||||||
return &client, nil
|
return &client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,11 +278,14 @@ type Member struct {
|
|||||||
PeerURL string
|
PeerURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) listMembers() (*clientv3.MemberListResponse, error) {
|
func (c *Client) listMembers(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
// Gets the member list
|
// Gets the member list
|
||||||
var lastError error
|
var lastError error
|
||||||
var resp *clientv3.MemberListResponse
|
var resp *clientv3.MemberListResponse
|
||||||
err := wait.ExponentialBackoff(etcdBackoff, func() (bool, error) {
|
if backoff == nil {
|
||||||
|
backoff = &etcdBackoff
|
||||||
|
}
|
||||||
|
err := wait.ExponentialBackoff(*backoff, func() (bool, error) {
|
||||||
cli, err := c.newEtcdClient(c.Endpoints)
|
cli, err := c.newEtcdClient(c.Endpoints)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lastError = err
|
lastError = err
|
||||||
@ -304,7 +311,7 @@ func (c *Client) listMembers() (*clientv3.MemberListResponse, error) {
|
|||||||
|
|
||||||
// GetMemberID returns the member ID of the given peer URL
|
// GetMemberID returns the member ID of the given peer URL
|
||||||
func (c *Client) GetMemberID(peerURL string) (uint64, error) {
|
func (c *Client) GetMemberID(peerURL string) (uint64, error) {
|
||||||
resp, err := c.listMembers()
|
resp, err := c.listMembersFunc(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@ -319,7 +326,7 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
|
|||||||
|
|
||||||
// ListMembers returns the member list.
|
// ListMembers returns the member list.
|
||||||
func (c *Client) ListMembers() ([]Member, error) {
|
func (c *Client) ListMembers() ([]Member, error) {
|
||||||
resp, err := c.listMembers()
|
resp, err := c.listMembersFunc(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -480,7 +487,7 @@ func (c *Client) addMember(name string, peerAddrs string, isLearner bool) ([]Mem
|
|||||||
|
|
||||||
// isLearner returns true if the given member ID is a learner.
|
// isLearner returns true if the given member ID is a learner.
|
||||||
func (c *Client) isLearner(memberID uint64) (bool, error) {
|
func (c *Client) isLearner(memberID uint64) (bool, error) {
|
||||||
resp, err := c.listMembers()
|
resp, err := c.listMembersFunc(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -482,6 +482,11 @@ func TestClient_GetMemberID(t *testing.T) {
|
|||||||
Endpoints: tt.fields.Endpoints,
|
Endpoints: tt.fields.Endpoints,
|
||||||
newEtcdClient: tt.fields.newEtcdClient,
|
newEtcdClient: tt.fields.newEtcdClient,
|
||||||
}
|
}
|
||||||
|
c.listMembersFunc = func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
|
f, _ := c.newEtcdClient([]string{})
|
||||||
|
resp, _ := f.MemberList(context.TODO())
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
got, err := c.GetMemberID(tt.args.peerURL)
|
got, err := c.GetMemberID(tt.args.peerURL)
|
||||||
if !errors.Is(tt.wantErr, err) {
|
if !errors.Is(tt.wantErr, err) {
|
||||||
@ -494,3 +499,292 @@ func TestClient_GetMemberID(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListMembers(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Endpoints []string
|
||||||
|
newEtcdClient func(endpoints []string) (etcdClient, error)
|
||||||
|
listMembersFunc func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error)
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
want []Member
|
||||||
|
wantError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "PeerURLs are empty",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []Member{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PeerURLs are non-empty",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Name: "member1",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member1:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
Name: "member2",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []Member{
|
||||||
|
{
|
||||||
|
Name: "member1",
|
||||||
|
PeerURL: "https://member1:2380",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "member2",
|
||||||
|
PeerURL: "https://member2:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "PeerURLs has multiple urls",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Name: "member1",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member1:2380",
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []Member{
|
||||||
|
{
|
||||||
|
Name: "member1",
|
||||||
|
PeerURL: "https://member1:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ListMembers return error",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Name: "member1",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member1:2380",
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
listMembersFunc: func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: nil,
|
||||||
|
wantError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Client{
|
||||||
|
Endpoints: tt.fields.Endpoints,
|
||||||
|
newEtcdClient: tt.fields.newEtcdClient,
|
||||||
|
listMembersFunc: tt.fields.listMembersFunc,
|
||||||
|
}
|
||||||
|
if c.listMembersFunc == nil {
|
||||||
|
c.listMembersFunc = func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
|
return c.listMembers(&wait.Backoff{Steps: 1})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
got, err := c.ListMembers()
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("ListMembers() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if (err != nil) != (tt.wantError) {
|
||||||
|
t.Errorf("ListMembers() error = %v, wantError %v", err, tt.wantError)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsLearner(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
Endpoints []string
|
||||||
|
newEtcdClient func(endpoints []string) (etcdClient, error)
|
||||||
|
listMembersFunc func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error)
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
memberID uint64
|
||||||
|
want bool
|
||||||
|
wantError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "The specified member is not a learner",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Name: "member1",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member1:2380",
|
||||||
|
},
|
||||||
|
IsLearner: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
memberID: 1,
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "The specified member is a learner",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
ID: 1,
|
||||||
|
Name: "member1",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member1:2380",
|
||||||
|
},
|
||||||
|
IsLearner: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 2,
|
||||||
|
Name: "member2",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
memberID: 1,
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "The specified member does not exist",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
memberID: 3,
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Learner ID is empty",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
Name: "member2",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
IsLearner: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "ListMembers returns an error",
|
||||||
|
fields: fields{
|
||||||
|
Endpoints: []string{},
|
||||||
|
newEtcdClient: func(endpoints []string) (etcdClient, error) {
|
||||||
|
f := &fakeEtcdClient{
|
||||||
|
members: []*pb.Member{
|
||||||
|
{
|
||||||
|
Name: "member2",
|
||||||
|
PeerURLs: []string{
|
||||||
|
"https://member2:2380",
|
||||||
|
},
|
||||||
|
IsLearner: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
},
|
||||||
|
listMembersFunc: func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
|
return nil, errNotImplemented
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
wantError: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
c := &Client{
|
||||||
|
Endpoints: tt.fields.Endpoints,
|
||||||
|
newEtcdClient: tt.fields.newEtcdClient,
|
||||||
|
listMembersFunc: tt.fields.listMembersFunc,
|
||||||
|
}
|
||||||
|
if c.listMembersFunc == nil {
|
||||||
|
c.listMembersFunc = func(backoff *wait.Backoff) (*clientv3.MemberListResponse, error) {
|
||||||
|
f, _ := c.newEtcdClient([]string{})
|
||||||
|
resp, _ := f.MemberList(context.TODO())
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
got, err := c.isLearner(tt.memberID)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("isLearner() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if (err != nil) != (tt.wantError) {
|
||||||
|
t.Errorf("isLearner() error = %v, wantError %v", err, tt.wantError)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user