From a5335847386ed5b4b729bf24c5a3b3e58f995d09 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 12:50:50 +0000 Subject: [PATCH 01/10] tests/framework: add basic lease operations --- tests/framework/config/client.go | 4 ++++ tests/framework/e2e/etcdctl.go | 36 +++++++++++++++++++++++++++++++- tests/framework/integration.go | 16 ++++++++++++++ tests/framework/interface.go | 3 ++- 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/tests/framework/config/client.go b/tests/framework/config/client.go index 6160d841d..c63dd5995 100644 --- a/tests/framework/config/client.go +++ b/tests/framework/config/client.go @@ -46,3 +46,7 @@ type CompactOption struct { type DefragOption struct { Timeout time.Duration } + +type LeaseOption struct { + WithAttachedKeys bool +} diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index f11bdcead..aae7a406e 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -17,6 +17,7 @@ package e2e import ( "encoding/json" "fmt" + "strconv" "strings" clientv3 "go.etcd.io/etcd/client/v3" @@ -185,7 +186,6 @@ func (ctl *EtcdctlV3) Status() ([]*clientv3.StatusResponse, error) { if err != nil { return nil, err } - var epStatus []*struct { Endpoint string Status *clientv3.StatusResponse @@ -241,7 +241,41 @@ func (ctl *EtcdctlV3) Health() error { lines[i] = "is healthy" } return SpawnWithExpects(args, map[string]string{}, lines...) +} +func (ctl *EtcdctlV3) Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) { + args := ctl.cmdArgs() + args = append(args, "lease", "grant", strconv.FormatInt(ttl, 10), "-w", "json") + cmd, err := SpawnCmd(args, nil) + if err != nil { + return nil, err + } + var resp clientv3.LeaseGrantResponse + line, err := cmd.Expect("ID") + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(line), &resp) + return &resp, err +} + +func (ctl *EtcdctlV3) TimeToLive(id clientv3.LeaseID, o config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) { + args := ctl.cmdArgs() + args = append(args, "lease", "timetolive", strconv.FormatInt(int64(id), 16), "-w", "json") + if o.WithAttachedKeys { + args = append(args, "--keys") + } + cmd, err := SpawnCmd(args, nil) + if err != nil { + return nil, err + } + var resp clientv3.LeaseTimeToLiveResponse + line, err := cmd.Expect("id") + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(line), &resp) + return &resp, err } func (ctl *EtcdctlV3) Defragment(o config.DefragOption) error { diff --git a/tests/framework/integration.go b/tests/framework/integration.go index 94c1925b7..b0a7cd17a 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -212,3 +212,19 @@ func (c integrationClient) Defragment(o config.DefragOption) error { } return nil } + +func (c integrationClient) Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) { + ctx := context.Background() + return c.Client.Grant(ctx, ttl) +} + +func (c integrationClient) TimeToLive(id clientv3.LeaseID, o config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) { + ctx := context.Background() + + leaseOpts := []clientv3.LeaseOption{} + if o.WithAttachedKeys { + leaseOpts = append(leaseOpts, clientv3.WithAttachedKeys()) + } + + return c.Client.TimeToLive(ctx, id, leaseOpts...) +} diff --git a/tests/framework/interface.go b/tests/framework/interface.go index db4b3b980..7ee691d99 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -37,9 +37,10 @@ type Client interface { 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) - Status() ([]*clientv3.StatusResponse, error) HashKV(rev int64) ([]*clientv3.HashKVResponse, error) Health() error Defragment(opts config.DefragOption) error + Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) + TimeToLive(id clientv3.LeaseID, opts config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) } From 6b7be72a4330e9ca3176c2c5401fbceac4ccf655 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 12:51:29 +0000 Subject: [PATCH 02/10] tests: migrate TestCtlV3LeaseGrantTimeToLive.* to common --- tests/common/lease_test.go | 71 ++++++++++++++++++++++++++++++++++ tests/e2e/ctl_v3_lease_test.go | 40 ------------------- 2 files changed, 71 insertions(+), 40 deletions(-) create mode 100644 tests/common/lease_test.go diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go new file mode 100644 index 000000000..df2c60a17 --- /dev/null +++ b/tests/common/lease_test.go @@ -0,0 +1,71 @@ +// 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 ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "go.etcd.io/etcd/tests/v3/framework/config" + "go.etcd.io/etcd/tests/v3/framework/testutils" +) + +func TestLeaseGrantTimeToLive(t *testing.T) { + testRunner.BeforeTest(t) + + tcs := []struct { + name string + config config.ClusterConfig + }{ + { + name: "NoTLS", + config: config.ClusterConfig{ClusterSize: 1}, + }, + { + name: "PeerTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.ManualTLS}, + }, + { + name: "PeerAutoTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.AutoTLS}, + }, + { + name: "ClientTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.ManualTLS}, + }, + { + name: "ClientAutoTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.AutoTLS}, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, tc.config) + defer clus.Close() + cc := clus.Client() + + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + ttl := int64(10) + leaseResp, err := cc.Grant(ttl) + require.NoError(t, err) + + ttlResp, err := cc.TimeToLive(leaseResp.ID, config.LeaseOption{}) + require.NoError(t, err) + require.Equal(t, ttl, ttlResp.GrantedTTL) + }) + }) + } +} diff --git a/tests/e2e/ctl_v3_lease_test.go b/tests/e2e/ctl_v3_lease_test.go index d13309bc5..f1388c5a5 100644 --- a/tests/e2e/ctl_v3_lease_test.go +++ b/tests/e2e/ctl_v3_lease_test.go @@ -24,20 +24,6 @@ import ( "go.etcd.io/etcd/tests/v3/framework/e2e" ) -func TestCtlV3LeaseGrantTimeToLive(t *testing.T) { testCtl(t, leaseTestGrantTimeToLive) } -func TestCtlV3LeaseGrantTimeToLiveNoTLS(t *testing.T) { - testCtl(t, leaseTestGrantTimeToLive, withCfg(*e2e.NewConfigNoTLS())) -} -func TestCtlV3LeaseGrantTimeToLiveClientTLS(t *testing.T) { - testCtl(t, leaseTestGrantTimeToLive, withCfg(*e2e.NewConfigClientTLS())) -} -func TestCtlV3LeaseGrantTimeToLiveClientAutoTLS(t *testing.T) { - testCtl(t, leaseTestGrantTimeToLive, withCfg(*e2e.NewConfigClientAutoTLS())) -} -func TestCtlV3LeaseGrantTimeToLivePeerTLS(t *testing.T) { - testCtl(t, leaseTestGrantTimeToLive, withCfg(*e2e.NewConfigPeerTLS())) -} - func TestCtlV3LeaseGrantLeases(t *testing.T) { testCtl(t, leaseTestGrantLeaseListed) } func TestCtlV3LeaseGrantLeasesNoTLS(t *testing.T) { testCtl(t, leaseTestGrantLeaseListed, withCfg(*e2e.NewConfigNoTLS())) @@ -108,32 +94,6 @@ func TestCtlV3LeaseRevokePeerTLS(t *testing.T) { testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigPeerTLS())) } -func leaseTestGrantTimeToLive(cx ctlCtx) { - id, err := ctlV3LeaseGrant(cx, 10) - if err != nil { - cx.t.Fatalf("leaseTestGrantTimeToLive: ctlV3LeaseGrant error (%v)", err) - } - - cmdArgs := append(cx.PrefixArgs(), "lease", "timetolive", id, "--keys") - proc, err := e2e.SpawnCmd(cmdArgs, cx.envMap) - if err != nil { - cx.t.Fatalf("leaseTestGrantTimeToLive: error (%v)", err) - } - line, err := proc.Expect(" granted with TTL(") - if err != nil { - cx.t.Fatalf("leaseTestGrantTimeToLive: error (%v)", err) - } - if err = proc.Close(); err != nil { - cx.t.Fatalf("leaseTestGrantTimeToLive: error (%v)", err) - } - if !strings.Contains(line, ", attached keys") { - cx.t.Fatalf("leaseTestGrantTimeToLive: expected 'attached keys', got %q", line) - } - if !strings.Contains(line, id) { - cx.t.Fatalf("leaseTestGrantTimeToLive: expected leaseID %q, got %q", id, line) - } -} - func leaseTestGrantLeaseListed(cx ctlCtx) { err := leaseTestGrantLeasesList(cx) if err != nil { From 68e6493977ccd7ab6d7fe180e6af3748dc9fc79c Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 15:00:29 +0000 Subject: [PATCH 03/10] tests/framework: add Client.LeaseList --- tests/framework/e2e/etcdctl.go | 17 ++++++++++++++++- tests/framework/integration.go | 6 ++++++ tests/framework/interface.go | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index aae7a406e..f0714aeb7 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -279,7 +279,6 @@ func (ctl *EtcdctlV3) TimeToLive(id clientv3.LeaseID, o config.LeaseOption) (*cl } func (ctl *EtcdctlV3) Defragment(o config.DefragOption) error { - args := append(ctl.cmdArgs(), "defrag") if o.Timeout != 0 { args = append(args, fmt.Sprintf("--command-timeout=%s", o.Timeout)) @@ -291,3 +290,19 @@ func (ctl *EtcdctlV3) Defragment(o config.DefragOption) error { _, err := SpawnWithExpectLines(args, map[string]string{}, lines...) return err } + +func (ctl *EtcdctlV3) LeaseList() (*clientv3.LeaseLeasesResponse, error) { + args := ctl.cmdArgs() + args = append(args, "lease", "list", "-w", "json") + cmd, err := SpawnCmd(args, nil) + if err != nil { + return nil, err + } + var resp clientv3.LeaseLeasesResponse + line, err := cmd.Expect("id") + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(line), &resp) + return &resp, err +} diff --git a/tests/framework/integration.go b/tests/framework/integration.go index b0a7cd17a..6a5eac295 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -228,3 +228,9 @@ func (c integrationClient) TimeToLive(id clientv3.LeaseID, o config.LeaseOption) return c.Client.TimeToLive(ctx, id, leaseOpts...) } + +func (c integrationClient) LeaseList() (*clientv3.LeaseLeasesResponse, error) { + ctx := context.Background() + + return c.Client.Leases(ctx) +} diff --git a/tests/framework/interface.go b/tests/framework/interface.go index 7ee691d99..c4fa9bda1 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -43,4 +43,5 @@ type Client interface { Defragment(opts config.DefragOption) error Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) TimeToLive(id clientv3.LeaseID, opts config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) + LeaseList() (*clientv3.LeaseLeasesResponse, error) } From b7beaf9c62e5472b7168a0a565af289f73a143f2 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 15:03:36 +0000 Subject: [PATCH 04/10] tests: migrate TestCtlV3LeaseGrantLeases.* to common --- tests/common/lease_test.go | 78 ++++++++++++++++++++++++++++++++++ tests/e2e/ctl_v3_auth_test.go | 18 ++++++++ tests/e2e/ctl_v3_lease_test.go | 39 ----------------- 3 files changed, 96 insertions(+), 39 deletions(-) diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go index df2c60a17..5676fbf24 100644 --- a/tests/common/lease_test.go +++ b/tests/common/lease_test.go @@ -19,6 +19,7 @@ import ( "time" "github.com/stretchr/testify/require" + clientv3 "go.etcd.io/etcd/client/v3" "go.etcd.io/etcd/tests/v3/framework/config" "go.etcd.io/etcd/tests/v3/framework/testutils" ) @@ -69,3 +70,80 @@ func TestLeaseGrantTimeToLive(t *testing.T) { }) } } + +func TestLeaseGrantAndList(t *testing.T) { + testRunner.BeforeTest(t) + + tcs := []struct { + name string + config config.ClusterConfig + }{ + { + name: "NoTLS", + config: config.ClusterConfig{ClusterSize: 1}, + }, + { + name: "PeerTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.ManualTLS}, + }, + { + name: "PeerAutoTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.AutoTLS}, + }, + { + name: "ClientTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.ManualTLS}, + }, + { + name: "ClientAutoTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.AutoTLS}, + }, + } + for _, tc := range tcs { + nestedCases := []struct { + name string + leaseCount int + }{ + { + name: "no_leases", + leaseCount: 0, + }, + { + name: "one_lease", + leaseCount: 1, + }, + { + name: "many_leases", + leaseCount: 3, + }, + } + + for _, nc := range nestedCases { + t.Run(tc.name+"/"+nc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, tc.config) + defer clus.Close() + cc := clus.Client() + + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + createdLeases := []clientv3.LeaseID{} + for i := 0; i < nc.leaseCount; i++ { + leaseResp, err := cc.Grant(10) + require.NoError(t, err) + createdLeases = append(createdLeases, leaseResp.ID) + } + + resp, err := cc.LeaseList() + require.NoError(t, err) + require.Len(t, resp.Leases, nc.leaseCount) + + returnedLeases := make([]clientv3.LeaseID, 0, nc.leaseCount) + for _, status := range resp.Leases { + returnedLeases = append(returnedLeases, status.ID) + } + + require.ElementsMatch(t, createdLeases, returnedLeases) + }) + }) + } + } +} diff --git a/tests/e2e/ctl_v3_auth_test.go b/tests/e2e/ctl_v3_auth_test.go index fd15a9e61..8fd640972 100644 --- a/tests/e2e/ctl_v3_auth_test.go +++ b/tests/e2e/ctl_v3_auth_test.go @@ -862,6 +862,24 @@ func authLeaseTestLeaseGrantLeases(cx ctlCtx) { } } +func leaseTestGrantLeasesList(cx ctlCtx) error { + id, err := ctlV3LeaseGrant(cx, 10) + if err != nil { + return fmt.Errorf("ctlV3LeaseGrant error (%v)", err) + } + + cmdArgs := append(cx.PrefixArgs(), "lease", "list") + proc, err := e2e.SpawnCmd(cmdArgs, cx.envMap) + if err != nil { + return fmt.Errorf("lease list failed (%v)", err) + } + _, err = proc.Expect(id) + if err != nil { + return fmt.Errorf("lease id not in returned list (%v)", err) + } + return proc.Close() +} + func authLeaseTestLeaseRevoke(cx ctlCtx) { cx.user, cx.pass = "root", "root" authSetupTestUser(cx) diff --git a/tests/e2e/ctl_v3_lease_test.go b/tests/e2e/ctl_v3_lease_test.go index f1388c5a5..4772ef215 100644 --- a/tests/e2e/ctl_v3_lease_test.go +++ b/tests/e2e/ctl_v3_lease_test.go @@ -24,20 +24,6 @@ import ( "go.etcd.io/etcd/tests/v3/framework/e2e" ) -func TestCtlV3LeaseGrantLeases(t *testing.T) { testCtl(t, leaseTestGrantLeaseListed) } -func TestCtlV3LeaseGrantLeasesNoTLS(t *testing.T) { - testCtl(t, leaseTestGrantLeaseListed, withCfg(*e2e.NewConfigNoTLS())) -} -func TestCtlV3LeaseGrantLeasesClientTLS(t *testing.T) { - testCtl(t, leaseTestGrantLeaseListed, withCfg(*e2e.NewConfigClientTLS())) -} -func TestCtlV3LeaseGrantLeasesClientAutoTLS(t *testing.T) { - testCtl(t, leaseTestGrantLeaseListed, withCfg(*e2e.NewConfigClientAutoTLS())) -} -func TestCtlV3LeaseGrantLeasesPeerTLS(t *testing.T) { - testCtl(t, leaseTestGrantLeaseListed, withCfg(*e2e.NewConfigPeerTLS())) -} - func TestCtlV3LeaseTestTimeToLiveExpired(t *testing.T) { testCtl(t, leaseTestTimeToLiveExpired) } func TestCtlV3LeaseTestTimeToLiveExpiredNoTLS(t *testing.T) { testCtl(t, leaseTestTimeToLiveExpired, withCfg(*e2e.NewConfigNoTLS())) @@ -94,31 +80,6 @@ func TestCtlV3LeaseRevokePeerTLS(t *testing.T) { testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigPeerTLS())) } -func leaseTestGrantLeaseListed(cx ctlCtx) { - err := leaseTestGrantLeasesList(cx) - if err != nil { - cx.t.Fatalf("leaseTestGrantLeasesList: (%v)", err) - } -} - -func leaseTestGrantLeasesList(cx ctlCtx) error { - id, err := ctlV3LeaseGrant(cx, 10) - if err != nil { - return fmt.Errorf("ctlV3LeaseGrant error (%v)", err) - } - - cmdArgs := append(cx.PrefixArgs(), "lease", "list") - proc, err := e2e.SpawnCmd(cmdArgs, cx.envMap) - if err != nil { - return fmt.Errorf("lease list failed (%v)", err) - } - _, err = proc.Expect(id) - if err != nil { - return fmt.Errorf("lease id not in returned list (%v)", err) - } - return proc.Close() -} - func leaseTestTimeToLiveExpired(cx ctlCtx) { err := leaseTestTimeToLiveExpire(cx, 3) if err != nil { From b50f10299b6f9aa9cef2ba5cf2dedd7fcb390841 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 15:26:08 +0000 Subject: [PATCH 05/10] tests/framework: Add PutOptions Put can take a leaseid to associate a value with a lease. This adds the ability for tests to make use of this. --- tests/common/compact_test.go | 2 +- tests/common/defrag_test.go | 2 +- tests/common/kv_test.go | 6 +++--- tests/e2e/ctl_v3_grpc_test.go | 3 ++- tests/framework/config/client.go | 4 ++++ tests/framework/e2e/etcdctl.go | 9 +++++++-- tests/framework/integration.go | 8 ++++++-- tests/framework/interface.go | 2 +- 8 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/common/compact_test.go b/tests/common/compact_test.go index 8effa94e1..d21d206aa 100644 --- a/tests/common/compact_test.go +++ b/tests/common/compact_test.go @@ -47,7 +47,7 @@ func TestCompact(t *testing.T) { 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 { + if err := clus.Client().Put(kvs[i].Key, kvs[i].Val, config.PutOptions{}); err != nil { t.Fatalf("compactTest #%d: put kv error (%v)", i, err) } } diff --git a/tests/common/defrag_test.go b/tests/common/defrag_test.go index 6cfce4c68..2c7db2b7c 100644 --- a/tests/common/defrag_test.go +++ b/tests/common/defrag_test.go @@ -30,7 +30,7 @@ func TestDefragOnline(t *testing.T) { defer clus.Close() 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 { + if err := clus.Client().Put(kvs[i].Key, kvs[i].Val, config.PutOptions{}); err != nil { t.Fatalf("compactTest #%d: put kv error (%v)", i, err) } } diff --git a/tests/common/kv_test.go b/tests/common/kv_test.go index 2a4eccacc..6f5849ee9 100644 --- a/tests/common/kv_test.go +++ b/tests/common/kv_test.go @@ -60,7 +60,7 @@ func TestKVPut(t *testing.T) { testutils.ExecuteWithTimeout(t, 10*time.Second, func() { key, value := "foo", "bar" - if err := cc.Put(key, value); err != nil { + if err := cc.Put(key, value, config.PutOptions{}); err != nil { t.Fatalf("count not put key %q, err: %s", key, err) } resp, err := cc.Get(key, config.GetOptions{Serializable: true}) @@ -123,7 +123,7 @@ func TestKVGet(t *testing.T) { ) for i := range kvs { - if err := cc.Put(kvs[i], "bar"); err != nil { + if err := cc.Put(kvs[i], "bar", config.PutOptions{}); err != nil { t.Fatalf("count not put key %q, err: %s", kvs[i], err) } } @@ -246,7 +246,7 @@ func TestKVDelete(t *testing.T) { } for _, tt := range tests { for i := range kvs { - if err := cc.Put(kvs[i], "bar"); err != nil { + if err := cc.Put(kvs[i], "bar", config.PutOptions{}); err != nil { t.Fatalf("count not put key %q, err: %s", kvs[i], err) } } diff --git a/tests/e2e/ctl_v3_grpc_test.go b/tests/e2e/ctl_v3_grpc_test.go index 8c8be2c69..878dd7948 100644 --- a/tests/e2e/ctl_v3_grpc_test.go +++ b/tests/e2e/ctl_v3_grpc_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "go.etcd.io/etcd/tests/v3/framework/config" "go.etcd.io/etcd/tests/v3/framework/e2e" "go.etcd.io/etcd/tests/v3/framework/testutils" ) @@ -100,7 +101,7 @@ func TestAuthority(t *testing.T) { endpoints := templateEndpoints(t, tc.clientURLPattern, epc) client := e2e.NewEtcdctl(cfg, endpoints) - err = client.Put("foo", "bar") + err = client.Put("foo", "bar", config.PutOptions{}) if err != nil { t.Fatal(err) } diff --git a/tests/framework/config/client.go b/tests/framework/config/client.go index c63dd5995..ef2ef9c27 100644 --- a/tests/framework/config/client.go +++ b/tests/framework/config/client.go @@ -32,6 +32,10 @@ type GetOptions struct { SortBy clientv3.SortTarget } +type PutOptions struct { + LeaseID clientv3.LeaseID +} + type DeleteOptions struct { Prefix bool FromKey bool diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index f0714aeb7..2d30a83e0 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -107,8 +107,13 @@ func (ctl *EtcdctlV3) Get(key string, o config.GetOptions) (*clientv3.GetRespons return &resp, err } -func (ctl *EtcdctlV3) Put(key, value string) error { - return SpawnWithExpect(ctl.cmdArgs("put", key, value), "OK") +func (ctl *EtcdctlV3) Put(key, value string, opts config.PutOptions) error { + args := ctl.cmdArgs() + args = append(args, "put", key, value) + if opts.LeaseID != 0 { + args = append(args, "--lease", strconv.FormatInt(int64(opts.LeaseID), 16)) + } + return SpawnWithExpect(args, "OK") } func (ctl *EtcdctlV3) Delete(key string, o config.DeleteOptions) (*clientv3.DeleteResponse, error) { diff --git a/tests/framework/integration.go b/tests/framework/integration.go index 6a5eac295..3c4cf2567 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -126,8 +126,12 @@ func (c integrationClient) Get(key string, o config.GetOptions) (*clientv3.GetRe return c.Client.Get(context.Background(), key, clientOpts...) } -func (c integrationClient) Put(key, value string) error { - _, err := c.Client.Put(context.Background(), key, value) +func (c integrationClient) Put(key, value string, opts config.PutOptions) error { + clientOpts := []clientv3.OpOption{} + if opts.LeaseID != 0 { + clientOpts = append(clientOpts, clientv3.WithLease(opts.LeaseID)) + } + _, err := c.Client.Put(context.Background(), key, value, clientOpts...) return err } diff --git a/tests/framework/interface.go b/tests/framework/interface.go index c4fa9bda1..08ead6a80 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -33,7 +33,7 @@ type Cluster interface { } type Client interface { - Put(key, value string) error + Put(key, value string, opts config.PutOptions) 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) From c12e03c8e64837eecf048b27dd7fcc9c4a8f7c89 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 15:27:51 +0000 Subject: [PATCH 06/10] tests: migrate TestCtlV3LeaseTestTimeToLiveExpired.* to common --- tests/common/lease_test.go | 60 ++++++++++++++++++++++++++++++++++ tests/e2e/ctl_v3_auth_test.go | 22 +++++++++++++ tests/e2e/ctl_v3_lease_test.go | 44 ------------------------- 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go index 5676fbf24..caeabf7da 100644 --- a/tests/common/lease_test.go +++ b/tests/common/lease_test.go @@ -147,3 +147,63 @@ func TestLeaseGrantAndList(t *testing.T) { } } } + +func TestLeaseGrantTimeToLiveExpired(t *testing.T) { + testRunner.BeforeTest(t) + + tcs := []struct { + name string + config config.ClusterConfig + }{ + { + name: "NoTLS", + config: config.ClusterConfig{ClusterSize: 1}, + }, + { + name: "PeerTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.ManualTLS}, + }, + { + name: "PeerAutoTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.AutoTLS}, + }, + { + name: "ClientTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.ManualTLS}, + }, + { + name: "ClientAutoTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.AutoTLS}, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, tc.config) + defer clus.Close() + cc := clus.Client() + + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + leaseResp, err := cc.Grant(2) + require.NoError(t, err) + + err = cc.Put("foo", "bar", config.PutOptions{LeaseID: leaseResp.ID}) + require.NoError(t, err) + + getResp, err := cc.Get("foo", config.GetOptions{}) + require.NoError(t, err) + require.Equal(t, int64(1), getResp.Count) + + time.Sleep(3 * time.Second) + + ttlResp, err := cc.TimeToLive(leaseResp.ID, config.LeaseOption{}) + require.NoError(t, err) + require.Equal(t, int64(-1), ttlResp.TTL) + + getResp, err = cc.Get("foo", config.GetOptions{}) + require.NoError(t, err) + // Value should expire with the lease + require.Equal(t, int64(0), getResp.Count) + }) + }) + } +} diff --git a/tests/e2e/ctl_v3_auth_test.go b/tests/e2e/ctl_v3_auth_test.go index 8fd640972..6c75f5b06 100644 --- a/tests/e2e/ctl_v3_auth_test.go +++ b/tests/e2e/ctl_v3_auth_test.go @@ -853,6 +853,28 @@ func authLeaseTestTimeToLiveExpired(cx ctlCtx) { } } +func leaseTestTimeToLiveExpire(cx ctlCtx, ttl int) error { + leaseID, err := ctlV3LeaseGrant(cx, ttl) + if err != nil { + return fmt.Errorf("ctlV3LeaseGrant error (%v)", err) + } + + if err = ctlV3Put(cx, "key", "val", leaseID); err != nil { + return fmt.Errorf("ctlV3Put error (%v)", err) + } + // eliminate false positive + time.Sleep(time.Duration(ttl+1) * time.Second) + cmdArgs := append(cx.PrefixArgs(), "lease", "timetolive", leaseID) + exp := fmt.Sprintf("lease %s already expired", leaseID) + if err = e2e.SpawnWithExpectWithEnv(cmdArgs, cx.envMap, exp); err != nil { + return fmt.Errorf("lease not properly expired: (%v)", err) + } + if err := ctlV3Get(cx, []string{"key"}); err != nil { + return fmt.Errorf("ctlV3Get error (%v)", err) + } + return nil +} + func authLeaseTestLeaseGrantLeases(cx ctlCtx) { cx.user, cx.pass = "root", "root" authSetupTestUser(cx) diff --git a/tests/e2e/ctl_v3_lease_test.go b/tests/e2e/ctl_v3_lease_test.go index 4772ef215..0c1173cd2 100644 --- a/tests/e2e/ctl_v3_lease_test.go +++ b/tests/e2e/ctl_v3_lease_test.go @@ -19,25 +19,10 @@ import ( "strconv" "strings" "testing" - "time" "go.etcd.io/etcd/tests/v3/framework/e2e" ) -func TestCtlV3LeaseTestTimeToLiveExpired(t *testing.T) { testCtl(t, leaseTestTimeToLiveExpired) } -func TestCtlV3LeaseTestTimeToLiveExpiredNoTLS(t *testing.T) { - testCtl(t, leaseTestTimeToLiveExpired, withCfg(*e2e.NewConfigNoTLS())) -} -func TestCtlV3LeaseTestTimeToLiveExpiredClientTLS(t *testing.T) { - testCtl(t, leaseTestTimeToLiveExpired, withCfg(*e2e.NewConfigClientTLS())) -} -func TestCtlV3LeaseTestTimeToLiveExpiredClientAutoTLS(t *testing.T) { - testCtl(t, leaseTestTimeToLiveExpired, withCfg(*e2e.NewConfigClientAutoTLS())) -} -func TestCtlV3LeaseTestTimeToLiveExpiredPeerTLS(t *testing.T) { - testCtl(t, leaseTestTimeToLiveExpired, withCfg(*e2e.NewConfigPeerTLS())) -} - func TestCtlV3LeaseKeepAlive(t *testing.T) { testCtl(t, leaseTestKeepAlive) } func TestCtlV3LeaseKeepAliveNoTLS(t *testing.T) { testCtl(t, leaseTestKeepAlive, withCfg(*e2e.NewConfigNoTLS())) @@ -80,35 +65,6 @@ func TestCtlV3LeaseRevokePeerTLS(t *testing.T) { testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigPeerTLS())) } -func leaseTestTimeToLiveExpired(cx ctlCtx) { - err := leaseTestTimeToLiveExpire(cx, 3) - if err != nil { - cx.t.Fatalf("leaseTestTimeToLiveExpire: (%v)", err) - } -} - -func leaseTestTimeToLiveExpire(cx ctlCtx, ttl int) error { - leaseID, err := ctlV3LeaseGrant(cx, ttl) - if err != nil { - return fmt.Errorf("ctlV3LeaseGrant error (%v)", err) - } - - if err = ctlV3Put(cx, "key", "val", leaseID); err != nil { - return fmt.Errorf("ctlV3Put error (%v)", err) - } - // eliminate false positive - time.Sleep(time.Duration(ttl+1) * time.Second) - cmdArgs := append(cx.PrefixArgs(), "lease", "timetolive", leaseID) - exp := fmt.Sprintf("lease %s already expired", leaseID) - if err = e2e.SpawnWithExpectWithEnv(cmdArgs, cx.envMap, exp); err != nil { - return fmt.Errorf("lease not properly expired: (%v)", err) - } - if err := ctlV3Get(cx, []string{"key"}); err != nil { - return fmt.Errorf("ctlV3Get error (%v)", err) - } - return nil -} - func leaseTestKeepAlive(cx ctlCtx) { // put with TTL 10 seconds and keep-alive leaseID, err := ctlV3LeaseGrant(cx, 10) From 353b011f5943cdeb1e427f77972dd55e7b187e75 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 16:00:05 +0000 Subject: [PATCH 07/10] tests/framework: Add Client.LeaseKeepAliveOnce --- tests/framework/e2e/etcdctl.go | 16 ++++++++++++++++ tests/framework/integration.go | 6 ++++++ tests/framework/interface.go | 1 + 3 files changed, 23 insertions(+) diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index 2d30a83e0..aa315ddf0 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -311,3 +311,19 @@ func (ctl *EtcdctlV3) LeaseList() (*clientv3.LeaseLeasesResponse, error) { err = json.Unmarshal([]byte(line), &resp) return &resp, err } + +func (ctl *EtcdctlV3) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKeepAliveResponse, error) { + args := ctl.cmdArgs() + args = append(args, "lease", "keep-alive", strconv.FormatInt(int64(id), 16), "--once", "-w", "json") + cmd, err := SpawnCmd(args, nil) + if err != nil { + return nil, err + } + var resp clientv3.LeaseKeepAliveResponse + line, err := cmd.Expect("ID") + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(line), &resp) + return &resp, err +} diff --git a/tests/framework/integration.go b/tests/framework/integration.go index 3c4cf2567..e5c8c01a4 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -238,3 +238,9 @@ func (c integrationClient) LeaseList() (*clientv3.LeaseLeasesResponse, error) { return c.Client.Leases(ctx) } + +func (c integrationClient) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKeepAliveResponse, error) { + ctx := context.Background() + + return c.Client.KeepAliveOnce(ctx, id) +} diff --git a/tests/framework/interface.go b/tests/framework/interface.go index 08ead6a80..ca7fb18de 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -44,4 +44,5 @@ type Client interface { Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) TimeToLive(id clientv3.LeaseID, opts config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) LeaseList() (*clientv3.LeaseLeasesResponse, error) + LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKeepAliveResponse, error) } From 36279e0797dbd2df4d658c20caceb4c2746e293e Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 16:00:44 +0000 Subject: [PATCH 08/10] tests: migrate TestCtlV3LeaseKeepAliveOnce.* to common --- tests/common/lease_test.go | 52 ++++++++++++++++++++++++++++++++++ tests/e2e/ctl_v3_lease_test.go | 45 ----------------------------- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go index caeabf7da..98e382ceb 100644 --- a/tests/common/lease_test.go +++ b/tests/common/lease_test.go @@ -207,3 +207,55 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) { }) } } + +func TestLeaseGrantKeepAliveOnce(t *testing.T) { + testRunner.BeforeTest(t) + + tcs := []struct { + name string + config config.ClusterConfig + }{ + { + name: "NoTLS", + config: config.ClusterConfig{ClusterSize: 1}, + }, + { + name: "PeerTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.ManualTLS}, + }, + { + name: "PeerAutoTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.AutoTLS}, + }, + { + name: "ClientTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.ManualTLS}, + }, + { + name: "ClientAutoTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.AutoTLS}, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, tc.config) + defer clus.Close() + cc := clus.Client() + + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + leaseResp, err := cc.Grant(2) + require.NoError(t, err) + + _, err = cc.LeaseKeepAliveOnce(leaseResp.ID) + require.NoError(t, err) + + time.Sleep(2 * time.Second) // Wait for the original lease to expire + + ttlResp, err := cc.TimeToLive(leaseResp.ID, config.LeaseOption{}) + require.NoError(t, err) + // We still have a lease! + require.Greater(t, int64(2), ttlResp.TTL) + }) + }) + } +} diff --git a/tests/e2e/ctl_v3_lease_test.go b/tests/e2e/ctl_v3_lease_test.go index 0c1173cd2..905351c93 100644 --- a/tests/e2e/ctl_v3_lease_test.go +++ b/tests/e2e/ctl_v3_lease_test.go @@ -37,20 +37,6 @@ func TestCtlV3LeaseKeepAlivePeerTLS(t *testing.T) { testCtl(t, leaseTestKeepAlive, withCfg(*e2e.NewConfigPeerTLS())) } -func TestCtlV3LeaseKeepAliveOnce(t *testing.T) { testCtl(t, leaseTestKeepAliveOnce) } -func TestCtlV3LeaseKeepAliveOnceNoTLS(t *testing.T) { - testCtl(t, leaseTestKeepAliveOnce, withCfg(*e2e.NewConfigNoTLS())) -} -func TestCtlV3LeaseKeepAliveOnceClientTLS(t *testing.T) { - testCtl(t, leaseTestKeepAliveOnce, withCfg(*e2e.NewConfigClientTLS())) -} -func TestCtlV3LeaseKeepAliveOnceClientAutoTLS(t *testing.T) { - testCtl(t, leaseTestKeepAliveOnce, withCfg(*e2e.NewConfigClientAutoTLS())) -} -func TestCtlV3LeaseKeepAliveOncePeerTLS(t *testing.T) { - testCtl(t, leaseTestKeepAliveOnce, withCfg(*e2e.NewConfigPeerTLS())) -} - func TestCtlV3LeaseRevoke(t *testing.T) { testCtl(t, leaseTestRevoked) } func TestCtlV3LeaseRevokeNoTLS(t *testing.T) { testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigNoTLS())) @@ -82,23 +68,6 @@ func leaseTestKeepAlive(cx ctlCtx) { } } -func leaseTestKeepAliveOnce(cx ctlCtx) { - // put with TTL 10 seconds and keep-alive once - leaseID, err := ctlV3LeaseGrant(cx, 10) - if err != nil { - cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseGrant error (%v)", err) - } - if err := ctlV3Put(cx, "key", "val", leaseID); err != nil { - cx.t.Fatalf("leaseTestKeepAlive: ctlV3Put error (%v)", err) - } - if err := ctlV3LeaseKeepAliveOnce(cx, leaseID); err != nil { - cx.t.Fatalf("leaseTestKeepAlive: ctlV3LeaseKeepAliveOnce error (%v)", err) - } - if err := ctlV3Get(cx, []string{"key"}, kv{"key", "val"}); err != nil { - cx.t.Fatalf("leaseTestKeepAlive: ctlV3Get error (%v)", err) - } -} - func leaseTestRevoked(cx ctlCtx) { err := leaseTestRevoke(cx) if err != nil { @@ -161,20 +130,6 @@ func ctlV3LeaseKeepAlive(cx ctlCtx, leaseID string) error { return proc.Stop() } -func ctlV3LeaseKeepAliveOnce(cx ctlCtx, leaseID string) error { - cmdArgs := append(cx.PrefixArgs(), "lease", "keep-alive", "--once", leaseID) - - proc, err := e2e.SpawnCmd(cmdArgs, nil) - if err != nil { - return err - } - - if _, err = proc.Expect(fmt.Sprintf("lease %s keepalived with TTL(", leaseID)); err != nil { - return err - } - return proc.Stop() -} - func ctlV3LeaseRevoke(cx ctlCtx, leaseID string) error { cmdArgs := append(cx.PrefixArgs(), "lease", "revoke", leaseID) return e2e.SpawnWithExpectWithEnv(cmdArgs, cx.envMap, fmt.Sprintf("lease %s revoked", leaseID)) From ab3353582d0f4b3f89da53fe2974d01f623cc226 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 16:21:12 +0000 Subject: [PATCH 09/10] tests/framework: Add Client.LeaseRevoke --- tests/framework/e2e/etcdctl.go | 16 ++++++++++++++++ tests/framework/integration.go | 6 ++++++ tests/framework/interface.go | 1 + 3 files changed, 23 insertions(+) diff --git a/tests/framework/e2e/etcdctl.go b/tests/framework/e2e/etcdctl.go index aa315ddf0..546c9c305 100644 --- a/tests/framework/e2e/etcdctl.go +++ b/tests/framework/e2e/etcdctl.go @@ -327,3 +327,19 @@ func (ctl *EtcdctlV3) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKe err = json.Unmarshal([]byte(line), &resp) return &resp, err } + +func (ctl *EtcdctlV3) LeaseRevoke(id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) { + args := ctl.cmdArgs() + args = append(args, "lease", "revoke", strconv.FormatInt(int64(id), 16), "-w", "json") + cmd, err := SpawnCmd(args, nil) + if err != nil { + return nil, err + } + var resp clientv3.LeaseRevokeResponse + line, err := cmd.Expect("header") + if err != nil { + return nil, err + } + err = json.Unmarshal([]byte(line), &resp) + return &resp, err +} diff --git a/tests/framework/integration.go b/tests/framework/integration.go index e5c8c01a4..28bb41422 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -244,3 +244,9 @@ func (c integrationClient) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.Le return c.Client.KeepAliveOnce(ctx, id) } + +func (c integrationClient) LeaseRevoke(id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) { + ctx := context.Background() + + return c.Client.Revoke(ctx, id) +} diff --git a/tests/framework/interface.go b/tests/framework/interface.go index ca7fb18de..cde4c8a3a 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -45,4 +45,5 @@ type Client interface { TimeToLive(id clientv3.LeaseID, opts config.LeaseOption) (*clientv3.LeaseTimeToLiveResponse, error) LeaseList() (*clientv3.LeaseLeasesResponse, error) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKeepAliveResponse, error) + LeaseRevoke(id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) } From 87740f6c7be7ca6fba8764a9bbf7d835387e1770 Mon Sep 17 00:00:00 2001 From: Danielle Lancashire Date: Wed, 16 Mar 2022 16:21:43 +0000 Subject: [PATCH 10/10] tests: Migrate TestCtlV3LeaseRevoke.* to common --- tests/common/lease_test.go | 61 ++++++++++++++++++++++++++++++++++ tests/e2e/ctl_v3_lease_test.go | 39 ---------------------- 2 files changed, 61 insertions(+), 39 deletions(-) diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go index 98e382ceb..e64f3b86e 100644 --- a/tests/common/lease_test.go +++ b/tests/common/lease_test.go @@ -259,3 +259,64 @@ func TestLeaseGrantKeepAliveOnce(t *testing.T) { }) } } + +func TestLeaseGrantRevoke(t *testing.T) { + testRunner.BeforeTest(t) + + tcs := []struct { + name string + config config.ClusterConfig + }{ + { + name: "NoTLS", + config: config.ClusterConfig{ClusterSize: 1}, + }, + { + name: "PeerTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.ManualTLS}, + }, + { + name: "PeerAutoTLS", + config: config.ClusterConfig{ClusterSize: 3, PeerTLS: config.AutoTLS}, + }, + { + name: "ClientTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.ManualTLS}, + }, + { + name: "ClientAutoTLS", + config: config.ClusterConfig{ClusterSize: 1, ClientTLS: config.AutoTLS}, + }, + } + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + clus := testRunner.NewCluster(t, tc.config) + defer clus.Close() + cc := clus.Client() + + testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + leaseResp, err := cc.Grant(20) + require.NoError(t, err) + + err = cc.Put("foo", "bar", config.PutOptions{LeaseID: leaseResp.ID}) + require.NoError(t, err) + + getResp, err := cc.Get("foo", config.GetOptions{}) + require.NoError(t, err) + require.Equal(t, int64(1), getResp.Count) + + _, err = cc.LeaseRevoke(leaseResp.ID) + require.NoError(t, err) + + ttlResp, err := cc.TimeToLive(leaseResp.ID, config.LeaseOption{}) + require.NoError(t, err) + require.Equal(t, int64(-1), ttlResp.TTL) + + getResp, err = cc.Get("foo", config.GetOptions{}) + require.NoError(t, err) + // Value should expire with the lease + require.Equal(t, int64(0), getResp.Count) + }) + }) + } +} diff --git a/tests/e2e/ctl_v3_lease_test.go b/tests/e2e/ctl_v3_lease_test.go index 905351c93..6ac44c44f 100644 --- a/tests/e2e/ctl_v3_lease_test.go +++ b/tests/e2e/ctl_v3_lease_test.go @@ -37,20 +37,6 @@ func TestCtlV3LeaseKeepAlivePeerTLS(t *testing.T) { testCtl(t, leaseTestKeepAlive, withCfg(*e2e.NewConfigPeerTLS())) } -func TestCtlV3LeaseRevoke(t *testing.T) { testCtl(t, leaseTestRevoked) } -func TestCtlV3LeaseRevokeNoTLS(t *testing.T) { - testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigNoTLS())) -} -func TestCtlV3LeaseRevokeClientTLS(t *testing.T) { - testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigClientTLS())) -} -func TestCtlV3LeaseRevokeClientAutoTLS(t *testing.T) { - testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigClientAutoTLS())) -} -func TestCtlV3LeaseRevokePeerTLS(t *testing.T) { - testCtl(t, leaseTestRevoked, withCfg(*e2e.NewConfigPeerTLS())) -} - func leaseTestKeepAlive(cx ctlCtx) { // put with TTL 10 seconds and keep-alive leaseID, err := ctlV3LeaseGrant(cx, 10) @@ -68,31 +54,6 @@ func leaseTestKeepAlive(cx ctlCtx) { } } -func leaseTestRevoked(cx ctlCtx) { - err := leaseTestRevoke(cx) - if err != nil { - cx.t.Fatalf("leaseTestRevoke: (%v)", err) - } -} - -func leaseTestRevoke(cx ctlCtx) error { - // put with TTL 10 seconds and revoke - leaseID, err := ctlV3LeaseGrant(cx, 10) - if err != nil { - return fmt.Errorf("ctlV3LeaseGrant error (%v)", err) - } - if err := ctlV3Put(cx, "key", "val", leaseID); err != nil { - return fmt.Errorf("ctlV3Put error (%v)", err) - } - if err := ctlV3LeaseRevoke(cx, leaseID); err != nil { - return fmt.Errorf("ctlV3LeaseRevoke error (%v)", err) - } - if err := ctlV3Get(cx, []string{"key"}); err != nil { // expect no output - return fmt.Errorf("ctlV3Get error (%v)", err) - } - return nil -} - func ctlV3LeaseGrant(cx ctlCtx, ttl int) (string, error) { cmdArgs := append(cx.PrefixArgs(), "lease", "grant", strconv.Itoa(ttl)) proc, err := e2e.SpawnCmd(cmdArgs, cx.envMap)