diff --git a/tests/common/kv_test.go b/tests/common/kv_test.go index b6a37fe50..54bda9915 100644 --- a/tests/common/kv_test.go +++ b/tests/common/kv_test.go @@ -33,7 +33,7 @@ func TestKVPut(t *testing.T) { if err := cc.Put(key, value); err != nil { t.Fatalf("count not put key %q, err: %s", key, err) } - resp, err := cc.Get(key, testutils.WithSerializable()) + resp, err := cc.Get(key, testutils.GetOptions{Serializable: true}) if err != nil { t.Fatalf("count not get key %q, err: %s", key, err) } diff --git a/tests/framework/e2e.go b/tests/framework/e2e.go index 094628a37..7b7769ec9 100644 --- a/tests/framework/e2e.go +++ b/tests/framework/e2e.go @@ -19,9 +19,7 @@ import ( "testing" "go.etcd.io/etcd/client/pkg/v3/testutil" - clientv3 "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/tests/v3/framework/e2e" - "go.etcd.io/etcd/tests/v3/framework/testutils" ) type e2eRunner struct{} @@ -58,11 +56,3 @@ func (c *e2eCluster) Client() Client { type e2eClient struct { *e2e.EtcdctlV3 } - -func (c e2eClient) Get(key string, opts ...testutils.GetOption) (*clientv3.GetResponse, error) { - o := testutils.GetOptions{} - for _, opt := range opts { - opt(&o) - } - return c.EtcdctlV3.Get(key, o) -} diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index b0a53afd1..90dd4856d 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -44,15 +44,64 @@ func (ctl *EtcdctlV3) Get(key string, o testutils.GetOptions) (*clientv3.GetResp if o.Serializable { args = append(args, "--consistency", "s") } - cmd, err := SpawnCmd(append(args, "get", key, "-w", "json"), nil) + args = append(args, "get", key, "-w", "json") + if o.End != "" { + args = append(args, o.End) + } + if o.Revision != 0 { + args = append(args, fmt.Sprintf("--rev=%d", o.Revision)) + } + if o.Prefix { + args = append(args, "--prefix") + } + if o.Limit != 0 { + args = append(args, fmt.Sprintf("--limit=%d", o.Limit)) + } + if o.FromKey { + args = append(args, "--from-key") + } + if o.CountOnly { + args = append(args, "-w", "fields", "--count-only") + } else { + args = append(args, "-w", "json") + } + switch o.SortBy { + case clientv3.SortByCreateRevision: + args = append(args, "--sort-by=CREATE") + case clientv3.SortByModRevision: + args = append(args, "--sort-by=MODIFY") + case clientv3.SortByValue: + args = append(args, "--sort-by=VALUE") + case clientv3.SortByVersion: + args = append(args, "--sort-by=VERSION") + case clientv3.SortByKey: + // nothing + default: + return nil, fmt.Errorf("bad sort target %v", o.SortBy) + } + switch o.Order { + case clientv3.SortAscend: + args = append(args, "--order=ASCEND") + case clientv3.SortDescend: + args = append(args, "--order=DESCEND") + case clientv3.SortNone: + // nothing + default: + return nil, fmt.Errorf("bad sort order %v", o.Order) + } + cmd, err := SpawnCmd(args, nil) if err != nil { return nil, err } + var resp clientv3.GetResponse + if o.CountOnly { + _, err := cmd.Expect("Count") + return &resp, err + } line, err := cmd.Expect("kvs") if err != nil { return nil, err } - var resp clientv3.GetResponse err = json.Unmarshal([]byte(line), &resp) return &resp, err } diff --git a/tests/framework/integration.go b/tests/framework/integration.go index b37111aa4..c628d7080 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -63,15 +63,32 @@ type integrationClient struct { *clientv3.Client } -func (c integrationClient) Get(key string, opts ...testutils.GetOption) (*clientv3.GetResponse, error) { - o := testutils.GetOptions{} - for _, opt := range opts { - opt(&o) - } +func (c integrationClient) Get(key string, o testutils.GetOptions) (*clientv3.GetResponse, error) { clientOpts := []clientv3.OpOption{} + if o.Revision != 0 { + clientOpts = append(clientOpts, clientv3.WithRev(int64(o.Revision))) + } + if o.End != "" { + clientOpts = append(clientOpts, clientv3.WithRange(o.End)) + } if o.Serializable { clientOpts = append(clientOpts, clientv3.WithSerializable()) } + if o.Prefix { + clientOpts = append(clientOpts, clientv3.WithPrefix()) + } + if o.Limit != 0 { + clientOpts = append(clientOpts, clientv3.WithLimit(int64(o.Limit))) + } + if o.FromKey { + clientOpts = append(clientOpts, clientv3.WithFromKey()) + } + if o.CountOnly { + clientOpts = append(clientOpts, clientv3.WithCountOnly()) + } + if o.SortBy != clientv3.SortByKey || o.Order != clientv3.SortNone { + clientOpts = append(clientOpts, clientv3.WithSort(o.SortBy, o.Order)) + } return c.Client.Get(context.Background(), key, clientOpts...) } diff --git a/tests/framework/interface.go b/tests/framework/interface.go index 9eb9e34c2..b430106c6 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -34,5 +34,5 @@ type Cluster interface { type Client interface { Put(key, value string) error - Get(key string, opts ...testutils.GetOption) (*clientv3.GetResponse, error) + Get(key string, opts testutils.GetOptions) (*clientv3.GetResponse, error) } diff --git a/tests/framework/testutils/options.go b/tests/framework/testutils/options.go index 49cfb8d09..0ec7e56de 100644 --- a/tests/framework/testutils/options.go +++ b/tests/framework/testutils/options.go @@ -14,14 +14,16 @@ package testutils +import clientv3 "go.etcd.io/etcd/client/v3" + type GetOptions struct { + Revision int + End string + CountOnly bool Serializable bool -} - -type GetOption func(*GetOptions) - -func WithSerializable() GetOption { - return func(options *GetOptions) { - options.Serializable = true - } + Prefix bool + FromKey bool + Limit int + Order clientv3.SortOrder + SortBy clientv3.SortTarget }