Merge pull request #14615 from ahrtr/username_password

test: refactor the client interface
This commit is contained in:
Benjamin Wang 2022-10-24 19:25:25 +08:00 committed by GitHub
commit 3b8b432b23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 66 additions and 74 deletions

View File

@ -33,7 +33,7 @@ func TestAlarm(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1, QuotaBackendBytes: int64(13 * os.Getpagesize())})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
// test small put still works
smallbuf := strings.Repeat("a", 64)
@ -117,7 +117,7 @@ func TestAlarmlistOnMemberRestart(t *testing.T) {
SnapshotCount: 5,
})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
for i := 0; i < 6; i++ {

View File

@ -21,7 +21,6 @@ import (
"time"
"github.com/stretchr/testify/assert"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/testutils"
@ -49,7 +48,7 @@ func TestCompact(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
var kvs = []testutils.KV{{Key: "key", Val: "val1"}, {Key: "key", Val: "val2"}, {Key: "key", Val: "val3"}}
for i := range kvs {

View File

@ -19,7 +19,6 @@ import (
"testing"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/testutils"
@ -31,7 +30,7 @@ func TestDefragOnline(t *testing.T) {
defer cancel()
options := config.DefragOption{Timeout: 10 * time.Second}
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3})
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
defer clus.Close()
var kvs = []testutils.KV{{Key: "key", Val: "val1"}, {Key: "key", Val: "val2"}, {Key: "key", Val: "val3"}}

View File

@ -19,7 +19,6 @@ import (
"testing"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/testutils"
@ -31,7 +30,7 @@ func TestEndpointStatus(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.Status(ctx)
if err != nil {
@ -46,7 +45,7 @@ func TestEndpointHashKV(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.HashKV(ctx, 0)
if err != nil {
@ -61,7 +60,7 @@ func TestEndpointHealth(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
if err := cc.Health(ctx); err != nil {
t.Fatalf("get endpoint health error: %v", err)

View File

@ -34,7 +34,7 @@ func TestKVPut(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
key, value := "foo", "bar"
@ -68,7 +68,7 @@ func TestKVGet(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
var (
@ -128,7 +128,7 @@ func TestKVDelete(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
kvs := []string{"a", "b", "c", "c/abc", "d"}
tests := []struct {

View File

@ -60,7 +60,7 @@ func TestLeaseGrantTimeToLive(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
ttl := int64(10)
@ -104,7 +104,7 @@ func TestLeaseGrantAndList(t *testing.T) {
t.Logf("Creating cluster...")
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
t.Logf("Created cluster and client")
testutils.ExecuteUntil(ctx, t, func() {
var createdLeases []clientv3.LeaseID
@ -151,7 +151,7 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
leaseResp, err := cc.Grant(ctx, 2)
@ -188,7 +188,7 @@ func TestLeaseGrantKeepAliveOnce(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
leaseResp, err := cc.Grant(ctx, 2)
@ -217,7 +217,7 @@ func TestLeaseGrantRevoke(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
leaseResp, err := cc.Grant(ctx, 20)

View File

@ -35,7 +35,7 @@ func TestMemberList(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
resp, err := cc.MemberList(ctx)
@ -109,7 +109,7 @@ func TestMemberAdd(t *testing.T) {
c.DisableStrictReconfigCheck = !quorumTc.strictReconfigCheck
clus := testRunner.NewCluster(ctx, t, c)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
var addResp *clientv3.MemberAddResponse

View File

@ -35,7 +35,7 @@ func TestRoleAdd_Simple(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.RoleAdd(ctx, "root")
@ -53,7 +53,7 @@ func TestRoleAdd_Error(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.RoleAdd(ctx, "test-role")
if err != nil {
@ -76,7 +76,7 @@ func TestRootRole(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.RoleAdd(ctx, "root")
if err != nil {
@ -106,7 +106,7 @@ func TestRoleGrantRevokePermission(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.RoleAdd(ctx, "role1")
if err != nil {
@ -141,7 +141,7 @@ func TestRoleDelete(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1})
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
_, err := cc.RoleAdd(ctx, "role1")
if err != nil {

View File

@ -19,7 +19,6 @@ import (
"testing"
"time"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/testutils"
)
@ -34,7 +33,7 @@ func TestStatus(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
rs, err := cc.Status(ctx)

View File

@ -61,7 +61,7 @@ func TestTxnSucc(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, cfg.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
if err := cc.Put(ctx, "key1", "value1", config.PutOptions{}); err != nil {
t.Fatalf("could not create key:%s, value:%s", "key1", "value1")
@ -105,7 +105,7 @@ func TestTxnFail(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, cfg.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
if err := cc.Put(ctx, "key1", "value1", config.PutOptions{}); err != nil {
t.Fatalf("could not create key:%s, value:%s", "key1", "value1")

View File

@ -20,7 +20,6 @@ import (
"time"
"github.com/stretchr/testify/assert"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/testutils"
@ -70,7 +69,7 @@ func TestUserAdd_Simple(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
resp, err := cc.UserAdd(ctx, nc.username, nc.password, config.UserAddOptions{NoPassword: nc.noPassword})
@ -104,7 +103,7 @@ func TestUserAdd_DuplicateUserNotAllowed(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
user := "barb"
@ -133,7 +132,7 @@ func TestUserList(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
// No Users Yet
@ -174,7 +173,7 @@ func TestUserDelete(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
user := "barb"
@ -226,7 +225,7 @@ func TestUserChangePassword(t *testing.T) {
defer cancel()
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
user := "barb"

View File

@ -6,7 +6,6 @@ import (
"time"
"github.com/stretchr/testify/assert"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/testutils"
@ -22,7 +21,7 @@ func TestWatch(t *testing.T) {
clus := testRunner.NewCluster(ctx, t, tc.config)
defer clus.Close()
cc := framework.MustClient(clus.Client(clientv3.AuthConfig{}))
cc := framework.MustClient(clus.Client())
testutils.ExecuteUntil(ctx, t, func() {
tests := []struct {
puts []testutils.KV

View File

@ -20,6 +20,12 @@ import (
clientv3 "go.etcd.io/etcd/client/v3"
)
// ClientOption configures the client with additional parameter.
// For example, if Auth is enabled,
// 1. e2e test cases use e2e.WithAuth to return a ClientOption;
// 2. integration test, uses integration.WithAuth to return a ClientOption.
type ClientOption func(any)
type GetOptions struct {
Revision int
End string

View File

@ -22,11 +22,8 @@ import (
"time"
"go.etcd.io/etcd/client/pkg/v3/testutil"
clientv3 "go.etcd.io/etcd/client/v3"
"go.etcd.io/etcd/tests/v3/framework/config"
"go.etcd.io/etcd/tests/v3/framework/e2e"
"go.etcd.io/etcd/tests/v3/framework/integration"
"google.golang.org/grpc"
)
type e2eRunner struct{}
@ -90,22 +87,8 @@ type e2eCluster struct {
e2e.EtcdProcessCluster
}
func (c *e2eCluster) Client(cfg clientv3.AuthConfig) (Client, error) {
etcdctl := e2e.NewEtcdctl(c.Cfg, c.EndpointsV3())
if !cfg.Empty() {
// use integration test client to validate if permissions are authorized
_, err := integration.NewClient(c.t, clientv3.Config{
Endpoints: c.EndpointsV3(),
DialTimeout: 5 * time.Second,
DialOptions: []grpc.DialOption{grpc.WithBlock()},
Username: cfg.Username,
Password: cfg.Password,
})
if err != nil {
return nil, err
}
etcdctl = etcdctl.WithAuth(cfg.Username, cfg.Password)
}
func (c *e2eCluster) Client(opts ...config.ClientOption) (Client, error) {
etcdctl := e2e.NewEtcdctl(c.Cfg, c.EndpointsV3(), opts...)
return e2eClient{etcdctl}, nil
}
@ -131,7 +114,7 @@ func (c *e2eCluster) WaitLeader(t testing.TB) int {
// WaitMembersForLeader waits until given members agree on the same leader,
// and returns its 'index' in the 'membs' list
func (c *e2eCluster) WaitMembersForLeader(ctx context.Context, t testing.TB, membs []Member) int {
cc := MustClient(c.Client(clientv3.AuthConfig{}))
cc := MustClient(c.Client())
// ensure leader is up via linearizable get
for {

View File

@ -35,17 +35,25 @@ type EtcdctlV3 struct {
password string
}
func NewEtcdctl(cfg *EtcdProcessClusterConfig, endpoints []string) *EtcdctlV3 {
return &EtcdctlV3{
func NewEtcdctl(cfg *EtcdProcessClusterConfig, endpoints []string, opts ...config.ClientOption) *EtcdctlV3 {
ctl := &EtcdctlV3{
cfg: cfg,
endpoints: endpoints,
}
for _, opt := range opts {
opt(ctl)
}
return ctl
}
func (ctl *EtcdctlV3) WithAuth(userName, password string) *EtcdctlV3 {
ctl.userName = userName
ctl.password = password
return ctl
func WithAuth(userName, password string) config.ClientOption {
return func(c any) {
ctl := c.(*EtcdctlV3)
ctl.userName = userName
ctl.password = password
}
}
func (ctl *EtcdctlV3) DowngradeEnable(ctx context.Context, version string) error {

View File

@ -118,15 +118,8 @@ func (c *integrationCluster) Close() error {
return nil
}
func (c *integrationCluster) Client(cfg clientv3.AuthConfig) (Client, error) {
option := func(_ *clientv3.Config) {}
if !cfg.Empty() {
option = func(clientCfg *clientv3.Config) {
clientCfg.Username = cfg.Username
clientCfg.Password = cfg.Password
}
}
cc, err := c.ClusterClient(c.t, option)
func (c *integrationCluster) Client(opts ...config.ClientOption) (Client, error) {
cc, err := c.ClusterClient(c.t, opts...)
if err != nil {
return nil, err
}

View File

@ -1437,7 +1437,7 @@ func (c *Cluster) Endpoints() []string {
return endpoints
}
func (c *Cluster) ClusterClient(t testing.TB, opts ...func(*clientv3.Config)) (client *clientv3.Client, err error) {
func (c *Cluster) ClusterClient(t testing.TB, opts ...framecfg.ClientOption) (client *clientv3.Client, err error) {
cfg, err := c.newClientCfg()
if err != nil {
return nil, err
@ -1455,6 +1455,14 @@ func (c *Cluster) ClusterClient(t testing.TB, opts ...func(*clientv3.Config)) (c
return client, nil
}
func WithAuth(userName, password string) framecfg.ClientOption {
return func(c any) {
client := c.(*clientv3.Client)
client.Username = userName
client.Password = password
}
}
func (c *Cluster) newClientCfg() (*clientv3.Config, error) {
cfg := &clientv3.Config{
Endpoints: c.Endpoints(),

View File

@ -30,7 +30,7 @@ type testRunner interface {
type Cluster interface {
Members() []Member
Client(cfg clientv3.AuthConfig) (Client, error)
Client(opts ...config.ClientOption) (Client, error)
WaitLeader(t testing.TB) int
Close() error
Endpoints() []string