From 34cd8ae1a2474aaa5c0b879d0ca110267061459a Mon Sep 17 00:00:00 2001 From: kkkkun Date: Thu, 10 Mar 2022 17:01:47 +0800 Subject: [PATCH] tests: Migrate compact tests to common framework --- tests/common/compact_test.go | 87 +++++++++++++++++++++++++++ tests/framework/config/client.go | 10 ++- tests/framework/e2e/etcdctl.go | 14 +++++ tests/framework/integration.go | 14 +++++ tests/framework/interface.go | 1 + tests/framework/testutils/helpters.go | 15 ++++- 6 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 tests/common/compact_test.go diff --git a/tests/common/compact_test.go b/tests/common/compact_test.go new file mode 100644 index 00000000000..8effa94e127 --- /dev/null +++ b/tests/common/compact_test.go @@ -0,0 +1,87 @@ +// Copyright 2022 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package common + +import ( + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "go.etcd.io/etcd/tests/v3/framework/config" + "go.etcd.io/etcd/tests/v3/framework/testutils" +) + +func TestCompact(t *testing.T) { + + testRunner.BeforeTest(t) + tcs := []struct { + name string + options config.CompactOption + }{ + { + name: "NoPhysical", + options: config.CompactOption{Physical: false, Timeout: 10 * time.Second}, + }, + { + name: "Physical", + options: config.CompactOption{Physical: true, Timeout: 10 * time.Second}, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + defer clus.Close() + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + var kvs = []testutils.KV{{Key: "key", Val: "val1"}, {Key: "key", Val: "val2"}, {Key: "key", Val: "val3"}} + for i := range kvs { + if err := clus.Client().Put(kvs[i].Key, kvs[i].Val); err != nil { + t.Fatalf("compactTest #%d: put kv error (%v)", i, err) + } + } + get, err := clus.Client().Get("key", config.GetOptions{Revision: 3}) + if err != nil { + t.Fatalf("compactTest: Get kv by revision error (%v)", err) + } + + getkvs := testutils.KeyValuesFromGetResponse(get) + assert.Equal(t, kvs[1:2], getkvs) + + _, err = clus.Client().Compact(4, tc.options) + if err != nil { + t.Fatalf("compactTest: Compact error (%v)", err) + } + + get, err = clus.Client().Get("key", config.GetOptions{Revision: 3}) + if err != nil { + if !strings.Contains(err.Error(), "required revision has been compacted") { + t.Fatalf("compactTest: Get compact key error (%v)", err) + } + } else { + t.Fatalf("expected '...has been compacted' error, got ") + } + + _, err = clus.Client().Compact(2, tc.options) + if err != nil { + if !strings.Contains(err.Error(), "required revision has been compacted") { + t.Fatal(err) + } + } else { + t.Fatalf("expected '...has been compacted' error, got ") + } + }) + }) + } +} diff --git a/tests/framework/config/client.go b/tests/framework/config/client.go index e4ad1a46cd5..c41565b4718 100644 --- a/tests/framework/config/client.go +++ b/tests/framework/config/client.go @@ -14,7 +14,10 @@ package config -import clientv3 "go.etcd.io/etcd/client/v3" +import ( + clientv3 "go.etcd.io/etcd/client/v3" + "time" +) type GetOptions struct { Revision int @@ -33,3 +36,8 @@ type DeleteOptions struct { FromKey bool End string } + +type CompactOption struct { + Physical bool + Timeout time.Duration +} diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index 3846b79a5bd..f807c7fe67d 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -162,3 +162,17 @@ func (ctl *EtcdctlV3) flags() map[string]string { fmap["endpoints"] = strings.Join(ctl.endpoints, ",") return fmap } + +func (ctl *EtcdctlV3) Compact(rev int64, o config.CompactOption) (*clientv3.CompactResponse, error) { + args := ctl.cmdArgs() + args = append(args, "compact", fmt.Sprint(rev)) + + if o.Timeout != 0 { + args = append(args, fmt.Sprintf("--command-timeout=%s", o.Timeout)) + } + if o.Physical { + args = append(args, "--physical") + } + + return nil, SpawnWithExpect(args, fmt.Sprintf("compacted revision %v", rev)) +} diff --git a/tests/framework/integration.go b/tests/framework/integration.go index baf260f932e..18aabed5a33 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -141,3 +141,17 @@ func (c integrationClient) Delete(key string, o config.DeleteOptions) (*clientv3 } return c.Client.Delete(context.Background(), key, clientOpts...) } + +func (c integrationClient) Compact(rev int64, o config.CompactOption) (*clientv3.CompactResponse, error) { + ctx := context.Background() + if o.Timeout != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, o.Timeout) + defer cancel() + } + clientOpts := []clientv3.CompactOption{} + if o.Physical { + clientOpts = append(clientOpts, clientv3.WithCompactPhysical()) + } + return c.Client.Compact(ctx, rev, clientOpts...) +} diff --git a/tests/framework/interface.go b/tests/framework/interface.go index 4a5225dc176..5c1ac01145a 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -36,4 +36,5 @@ type Client interface { Put(key, value string) error Get(key string, opts config.GetOptions) (*clientv3.GetResponse, error) Delete(key string, opts config.DeleteOptions) (*clientv3.DeleteResponse, error) + Compact(rev int64, opts config.CompactOption) (*clientv3.CompactResponse, error) } diff --git a/tests/framework/testutils/helpters.go b/tests/framework/testutils/helpters.go index ecc165a8685..c508bd27491 100644 --- a/tests/framework/testutils/helpters.go +++ b/tests/framework/testutils/helpters.go @@ -14,7 +14,13 @@ package testutils -import clientv3 "go.etcd.io/etcd/client/v3" +import ( + clientv3 "go.etcd.io/etcd/client/v3" +) + +type KV struct { + Key, Val string +} func KeysFromGetResponse(resp *clientv3.GetResponse) (kvs []string) { for _, kv := range resp.Kvs { @@ -22,3 +28,10 @@ func KeysFromGetResponse(resp *clientv3.GetResponse) (kvs []string) { } return kvs } + +func KeyValuesFromGetResponse(resp *clientv3.GetResponse) (kvs []KV) { + for _, kv := range resp.Kvs { + kvs = append(kvs, KV{Key: string(kv.Key), Val: string(kv.Value)}) + } + return kvs +}