From ee08770bfbcf6b9a296a314e700f62a0df167903 Mon Sep 17 00:00:00 2001 From: Marek Siarkowicz Date: Mon, 16 May 2022 11:55:02 +0200 Subject: [PATCH] tests: Make common framework context aware --- tests/common/alarm_test.go | 7 ++- tests/common/compact_test.go | 7 ++- tests/common/defrag_test.go | 7 ++- tests/common/endpoint_test.go | 19 ++++--- tests/common/kv_test.go | 25 ++++++--- tests/common/lease_test.go | 31 +++++++---- tests/common/role_test.go | 31 +++++++---- tests/common/txn_test.go | 13 +++-- tests/common/user_test.go | 31 +++++++---- tests/framework/e2e.go | 3 +- tests/framework/integration.go | 80 +++++++++++++--------------- tests/framework/interface.go | 3 +- tests/framework/testutils/execute.go | 17 +++++- tests/framework/unit.go | 3 +- 14 files changed, 174 insertions(+), 103 deletions(-) diff --git a/tests/common/alarm_test.go b/tests/common/alarm_test.go index 9873743c2..9f0ace141 100644 --- a/tests/common/alarm_test.go +++ b/tests/common/alarm_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "os" "strings" "testing" @@ -27,9 +28,11 @@ import ( func TestAlarm(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 1, QuotaBackendBytes: int64(13 * os.Getpagesize())}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1, QuotaBackendBytes: int64(13 * os.Getpagesize())}) defer clus.Close() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { // test small put still works smallbuf := strings.Repeat("a", 64) if err := clus.Client().Put("1st_test", smallbuf, config.PutOptions{}); err != nil { diff --git a/tests/common/compact_test.go b/tests/common/compact_test.go index d21d206aa..2b1031dae 100644 --- a/tests/common/compact_test.go +++ b/tests/common/compact_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "strings" "testing" "time" @@ -42,9 +43,11 @@ func TestCompact(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) defer clus.Close() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + 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 { if err := clus.Client().Put(kvs[i].Key, kvs[i].Val, config.PutOptions{}); err != nil { diff --git a/tests/common/defrag_test.go b/tests/common/defrag_test.go index 2c7db2b7c..295149312 100644 --- a/tests/common/defrag_test.go +++ b/tests/common/defrag_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "testing" "time" @@ -24,9 +25,11 @@ import ( func TestDefragOnline(t *testing.T) { testRunner.BeforeTest(t) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() options := config.DefragOption{Timeout: 10 * time.Second} - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) + testutils.ExecuteUntil(ctx, t, func() { defer clus.Close() var kvs = []testutils.KV{{Key: "key", Val: "val1"}, {Key: "key", Val: "val2"}, {Key: "key", Val: "val3"}} for i := range kvs { diff --git a/tests/common/endpoint_test.go b/tests/common/endpoint_test.go index 371e85fbb..d1ba6da18 100644 --- a/tests/common/endpoint_test.go +++ b/tests/common/endpoint_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "testing" "time" @@ -24,9 +25,11 @@ import ( func TestEndpointStatus(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) defer clus.Close() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := clus.Client().Status() if err != nil { t.Fatalf("get endpoint status error: %v", err) @@ -36,9 +39,11 @@ func TestEndpointStatus(t *testing.T) { func TestEndpointHashKV(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) defer clus.Close() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := clus.Client().HashKV(0) if err != nil { t.Fatalf("get endpoint hashkv error: %v", err) @@ -48,9 +53,11 @@ func TestEndpointHashKV(t *testing.T) { func TestEndpointHealth(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) defer clus.Close() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { if err := clus.Client().Health(); err != nil { t.Fatalf("get endpoint health error: %v", err) } diff --git a/tests/common/kv_test.go b/tests/common/kv_test.go index aab344fc3..ef2540ced 100644 --- a/tests/common/kv_test.go +++ b/tests/common/kv_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "testing" "time" @@ -28,11 +29,13 @@ func TestKVPut(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { key, value := "foo", "bar" if err := cc.Put(key, value, config.PutOptions{}); err != nil { @@ -60,11 +63,13 @@ func TestKVGet(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { var ( kvs = []string{"a", "b", "c", "c", "c", "foo", "foo/abc", "fop"} wantKvs = []string{"a", "b", "c", "foo", "foo/abc", "fop"} @@ -118,10 +123,12 @@ func TestKVDelete(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { kvs := []string{"a", "b", "c", "c/abc", "d"} tests := []struct { deleteKey string @@ -212,14 +219,16 @@ func TestKVGetNoQuorum(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 3}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 3}) defer clus.Close() clus.Members()[0].Stop() clus.Members()[1].Stop() cc := clus.Members()[2].Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { key := "foo" _, err := cc.Get(key, tc.options) gotError := err != nil diff --git a/tests/common/lease_test.go b/tests/common/lease_test.go index e3fd4d6ec..0281b3cfe 100644 --- a/tests/common/lease_test.go +++ b/tests/common/lease_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "testing" "time" @@ -54,11 +55,13 @@ func TestLeaseGrantTimeToLive(t *testing.T) { } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { ttl := int64(10) leaseResp, err := cc.Grant(ttl) require.NoError(t, err) @@ -95,12 +98,14 @@ func TestLeaseGrantAndList(t *testing.T) { for _, nc := range nestedCases { t.Run(tc.name+"/"+nc.name, func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() t.Logf("Creating cluster...") - clus := testRunner.NewCluster(t, tc.config) + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() t.Logf("Created cluster and client") - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { createdLeases := []clientv3.LeaseID{} for i := 0; i < nc.leaseCount; i++ { leaseResp, err := cc.Grant(10) @@ -141,11 +146,13 @@ func TestLeaseGrantTimeToLiveExpired(t *testing.T) { for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { leaseResp, err := cc.Grant(2) require.NoError(t, err) @@ -176,11 +183,13 @@ func TestLeaseGrantKeepAliveOnce(t *testing.T) { for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { leaseResp, err := cc.Grant(2) require.NoError(t, err) @@ -203,11 +212,13 @@ func TestLeaseGrantRevoke(t *testing.T) { for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { leaseResp, err := cc.Grant(20) require.NoError(t, err) diff --git a/tests/common/role_test.go b/tests/common/role_test.go index d2e7ada24..6b1382aa2 100644 --- a/tests/common/role_test.go +++ b/tests/common/role_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "strings" "testing" "time" @@ -29,11 +30,13 @@ func TestRoleAdd_Simple(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := cc.RoleAdd("root") if err != nil { t.Fatalf("want no error, but got (%v)", err) @@ -45,10 +48,12 @@ func TestRoleAdd_Simple(t *testing.T) { func TestRoleAdd_Error(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 1}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1}) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := cc.RoleAdd("test-role") if err != nil { t.Fatalf("want no error, but got (%v)", err) @@ -66,10 +71,12 @@ func TestRoleAdd_Error(t *testing.T) { func TestRootRole(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 1}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1}) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := cc.RoleAdd("root") if err != nil { t.Fatalf("want no error, but got (%v)", err) @@ -94,10 +101,12 @@ func TestRootRole(t *testing.T) { func TestRoleGrantRevokePermission(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 1}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1}) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := cc.RoleAdd("role1") if err != nil { t.Fatalf("want no error, but got (%v)", err) @@ -127,10 +136,12 @@ func TestRoleGrantRevokePermission(t *testing.T) { func TestRoleDelete(t *testing.T) { testRunner.BeforeTest(t) - clus := testRunner.NewCluster(t, config.ClusterConfig{ClusterSize: 1}) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, config.ClusterConfig{ClusterSize: 1}) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { _, err := cc.RoleAdd("role1") if err != nil { t.Fatalf("want no error, but got (%v)", err) diff --git a/tests/common/txn_test.go b/tests/common/txn_test.go index 5003ac5f6..79497224e 100644 --- a/tests/common/txn_test.go +++ b/tests/common/txn_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "fmt" "testing" "time" @@ -55,10 +56,12 @@ func TestTxnSucc(t *testing.T) { } for _, cfg := range clusterTestCases { t.Run(cfg.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, cfg.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, cfg.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { if err := cc.Put("key1", "value1", config.PutOptions{}); err != nil { t.Fatalf("could not create key:%s, value:%s", "key1", "value1") } @@ -97,10 +100,12 @@ func TestTxnFail(t *testing.T) { } for _, cfg := range clusterTestCases { t.Run(cfg.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, cfg.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, cfg.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { if err := cc.Put("key1", "value1", config.PutOptions{}); err != nil { t.Fatalf("could not create key:%s, value:%s", "key1", "value1") } diff --git a/tests/common/user_test.go b/tests/common/user_test.go index 49d8ea5fe..b48a8224e 100644 --- a/tests/common/user_test.go +++ b/tests/common/user_test.go @@ -15,6 +15,7 @@ package common import ( + "context" "testing" "time" @@ -63,11 +64,13 @@ func TestUserAdd_Simple(t *testing.T) { for _, tc := range clusterTestCases { for _, nc := range tcs { t.Run(tc.name+"/"+nc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { resp, err := cc.UserAdd(nc.username, nc.password, config.UserAddOptions{NoPassword: nc.noPassword}) if nc.expectedError != "" { if err != nil { @@ -95,11 +98,13 @@ func TestUserAdd_DuplicateUserNotAllowed(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { user := "barb" password := "rhubarb" @@ -122,11 +127,13 @@ func TestUserList(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { // No Users Yet resp, err := cc.UserList() if err != nil { @@ -161,11 +168,13 @@ func TestUserDelete(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { user := "barb" password := "rhubarb" @@ -211,11 +220,13 @@ func TestUserChangePassword(t *testing.T) { testRunner.BeforeTest(t) for _, tc := range clusterTestCases { t.Run(tc.name, func(t *testing.T) { - clus := testRunner.NewCluster(t, tc.config) + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + clus := testRunner.NewCluster(ctx, t, tc.config) defer clus.Close() cc := clus.Client() - testutils.ExecuteWithTimeout(t, 10*time.Second, func() { + testutils.ExecuteUntil(ctx, t, func() { user := "barb" password := "rhubarb" newPassword := "potato" diff --git a/tests/framework/e2e.go b/tests/framework/e2e.go index 01528aed0..4f8ec81da 100644 --- a/tests/framework/e2e.go +++ b/tests/framework/e2e.go @@ -15,6 +15,7 @@ package framework import ( + "context" "os" "testing" @@ -38,7 +39,7 @@ func (e e2eRunner) BeforeTest(t testing.TB) { e2e.BeforeTest(t) } -func (e e2eRunner) NewCluster(t testing.TB, cfg config.ClusterConfig) Cluster { +func (e e2eRunner) NewCluster(ctx context.Context, t testing.TB, cfg config.ClusterConfig) Cluster { e2eConfig := e2e.EtcdProcessClusterConfig{ InitialToken: "new", ClusterSize: cfg.ClusterSize, diff --git a/tests/framework/integration.go b/tests/framework/integration.go index 01de255c7..83a1ba136 100644 --- a/tests/framework/integration.go +++ b/tests/framework/integration.go @@ -42,7 +42,7 @@ func (e integrationRunner) BeforeTest(t testing.TB) { integration.BeforeTest(t) } -func (e integrationRunner) NewCluster(t testing.TB, cfg config.ClusterConfig) Cluster { +func (e integrationRunner) NewCluster(ctx context.Context, t testing.TB, cfg config.ClusterConfig) Cluster { var err error var integrationCfg integration.ClusterConfig integrationCfg.Size = cfg.ClusterSize @@ -58,6 +58,7 @@ func (e integrationRunner) NewCluster(t testing.TB, cfg config.ClusterConfig) Cl return &integrationCluster{ Cluster: integration.NewCluster(t, &integrationCfg), t: t, + ctx: ctx, } } @@ -80,23 +81,25 @@ func tlsInfo(t testing.TB, cfg config.TLSConfig) (*transport.TLSInfo, error) { type integrationCluster struct { *integration.Cluster - t testing.TB + t testing.TB + ctx context.Context } func (c *integrationCluster) Members() (ms []Member) { for _, m := range c.Cluster.Members { - ms = append(ms, integrationMember{m, c.t}) + ms = append(ms, integrationMember{Member: m, t: c.t, ctx: c.ctx}) } return ms } type integrationMember struct { *integration.Member - t testing.TB + t testing.TB + ctx context.Context } func (m integrationMember) Client() Client { - return integrationClient{m.Member.Client} + return integrationClient{Client: m.Member.Client, ctx: m.ctx} } func (m integrationMember) Start() error { @@ -117,15 +120,16 @@ func (c *integrationCluster) Client() Client { if err != nil { c.t.Fatal(err) } - return integrationClient{cc} + return integrationClient{Client: cc, ctx: c.ctx} } type integrationClient struct { *clientv3.Client + ctx context.Context } func (c integrationClient) Get(key string, o config.GetOptions) (*clientv3.GetResponse, error) { - ctx := context.Background() + ctx := c.ctx if o.Timeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, o.Timeout) @@ -164,7 +168,7 @@ func (c integrationClient) Put(key, value string, opts config.PutOptions) error if opts.LeaseID != 0 { clientOpts = append(clientOpts, clientv3.WithLease(opts.LeaseID)) } - _, err := c.Client.Put(context.Background(), key, value, clientOpts...) + _, err := c.Client.Put(c.ctx, key, value, clientOpts...) return err } @@ -179,11 +183,11 @@ func (c integrationClient) Delete(key string, o config.DeleteOptions) (*clientv3 if o.End != "" { clientOpts = append(clientOpts, clientv3.WithRange(o.End)) } - return c.Client.Delete(context.Background(), key, clientOpts...) + return c.Client.Delete(c.ctx, key, clientOpts...) } func (c integrationClient) Compact(rev int64, o config.CompactOption) (*clientv3.CompactResponse, error) { - ctx := context.Background() + ctx := c.ctx if o.Timeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, o.Timeout) @@ -197,18 +201,18 @@ func (c integrationClient) Compact(rev int64, o config.CompactOption) (*clientv3 } func (c integrationClient) AlarmList() (*clientv3.AlarmResponse, error) { - return c.Client.AlarmList(context.Background()) + return c.Client.AlarmList(c.ctx) } func (c integrationClient) AlarmDisarm(alarmMember *clientv3.AlarmMember) (*clientv3.AlarmResponse, error) { - return c.Client.AlarmDisarm(context.Background(), alarmMember) + return c.Client.AlarmDisarm(c.ctx, alarmMember) } func (c integrationClient) Status() ([]*clientv3.StatusResponse, error) { endpoints := c.Client.Endpoints() var resp []*clientv3.StatusResponse for _, ep := range endpoints { - status, err := c.Client.Status(context.Background(), ep) + status, err := c.Client.Status(c.ctx, ep) if err != nil { return nil, err } @@ -221,7 +225,7 @@ func (c integrationClient) HashKV(rev int64) ([]*clientv3.HashKVResponse, error) endpoints := c.Client.Endpoints() var resp []*clientv3.HashKVResponse for _, ep := range endpoints { - hashKV, err := c.Client.HashKV(context.Background(), ep, rev) + hashKV, err := c.Client.HashKV(c.ctx, ep, rev) if err != nil { return nil, err } @@ -232,7 +236,7 @@ func (c integrationClient) HashKV(rev int64) ([]*clientv3.HashKVResponse, error) func (c integrationClient) Health() error { cli := healthpb.NewHealthClient(c.Client.ActiveConnection()) - resp, err := cli.Check(context.TODO(), &healthpb.HealthCheckRequest{}) + resp, err := cli.Check(c.ctx, &healthpb.HealthCheckRequest{}) if err != nil { return err } @@ -243,7 +247,7 @@ func (c integrationClient) Health() error { } func (c integrationClient) Defragment(o config.DefragOption) error { - ctx := context.Background() + ctx := c.ctx if o.Timeout != 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, o.Timeout) @@ -259,87 +263,75 @@ func (c integrationClient) Defragment(o config.DefragOption) error { } func (c integrationClient) Grant(ttl int64) (*clientv3.LeaseGrantResponse, error) { - ctx := context.Background() - return c.Client.Grant(ctx, ttl) + return c.Client.Grant(c.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...) + return c.Client.TimeToLive(c.ctx, id, leaseOpts...) } func (c integrationClient) LeaseList() (*clientv3.LeaseLeasesResponse, error) { - ctx := context.Background() - - return c.Client.Leases(ctx) + return c.Client.Leases(c.ctx) } func (c integrationClient) LeaseKeepAliveOnce(id clientv3.LeaseID) (*clientv3.LeaseKeepAliveResponse, error) { - ctx := context.Background() - - return c.Client.KeepAliveOnce(ctx, id) + return c.Client.KeepAliveOnce(c.ctx, id) } func (c integrationClient) LeaseRevoke(id clientv3.LeaseID) (*clientv3.LeaseRevokeResponse, error) { - ctx := context.Background() - - return c.Client.Revoke(ctx, id) + return c.Client.Revoke(c.ctx, id) } func (c integrationClient) UserAdd(name, password string, opts config.UserAddOptions) (*clientv3.AuthUserAddResponse, error) { - ctx := context.Background() - return c.Client.UserAddWithOptions(ctx, name, password, &clientv3.UserAddOptions{ + return c.Client.UserAddWithOptions(c.ctx, name, password, &clientv3.UserAddOptions{ NoPassword: opts.NoPassword, }) } func (c integrationClient) UserList() (*clientv3.AuthUserListResponse, error) { - ctx := context.Background() - return c.Client.UserList(ctx) + return c.Client.UserList(c.ctx) } func (c integrationClient) UserDelete(name string) (*clientv3.AuthUserDeleteResponse, error) { - ctx := context.Background() - return c.Client.UserDelete(ctx, name) + return c.Client.UserDelete(c.ctx, name) } func (c integrationClient) UserChangePass(user, newPass string) error { - _, err := c.Client.UserChangePassword(context.Background(), user, newPass) + _, err := c.Client.UserChangePassword(c.ctx, user, newPass) return err } func (c integrationClient) RoleAdd(name string) (*clientv3.AuthRoleAddResponse, error) { - return c.Client.RoleAdd(context.Background(), name) + return c.Client.RoleAdd(c.ctx, name) } func (c integrationClient) RoleGrantPermission(name string, key, rangeEnd string, permType clientv3.PermissionType) (*clientv3.AuthRoleGrantPermissionResponse, error) { - return c.Client.RoleGrantPermission(context.Background(), name, key, rangeEnd, permType) + return c.Client.RoleGrantPermission(c.ctx, name, key, rangeEnd, permType) } func (c integrationClient) RoleGet(role string) (*clientv3.AuthRoleGetResponse, error) { - return c.Client.RoleGet(context.Background(), role) + return c.Client.RoleGet(c.ctx, role) } func (c integrationClient) RoleList() (*clientv3.AuthRoleListResponse, error) { - return c.Client.RoleList(context.Background()) + return c.Client.RoleList(c.ctx) } func (c integrationClient) RoleRevokePermission(role string, key, rangeEnd string) (*clientv3.AuthRoleRevokePermissionResponse, error) { - return c.Client.RoleRevokePermission(context.Background(), role, key, rangeEnd) + return c.Client.RoleRevokePermission(c.ctx, role, key, rangeEnd) } func (c integrationClient) RoleDelete(role string) (*clientv3.AuthRoleDeleteResponse, error) { - return c.Client.RoleDelete(context.Background(), role) + return c.Client.RoleDelete(c.ctx, role) } func (c integrationClient) Txn(compares, ifSucess, ifFail []string, o config.TxnOptions) (*clientv3.TxnResponse, error) { - txn := c.Client.Txn(context.Background()) + txn := c.Client.Txn(c.ctx) cmps := []clientv3.Cmp{} for _, c := range compares { cmp, err := etcdctlcmd.ParseCompare(c) diff --git a/tests/framework/interface.go b/tests/framework/interface.go index 03390f9dd..dc0565ad2 100644 --- a/tests/framework/interface.go +++ b/tests/framework/interface.go @@ -15,6 +15,7 @@ package framework import ( + "context" "testing" clientv3 "go.etcd.io/etcd/client/v3" @@ -24,7 +25,7 @@ import ( type testRunner interface { TestMain(m *testing.M) BeforeTest(testing.TB) - NewCluster(testing.TB, config.ClusterConfig) Cluster + NewCluster(context.Context, testing.TB, config.ClusterConfig) Cluster } type Cluster interface { diff --git a/tests/framework/testutils/execute.go b/tests/framework/testutils/execute.go index 2c6564afd..d9c3d3358 100644 --- a/tests/framework/testutils/execute.go +++ b/tests/framework/testutils/execute.go @@ -15,6 +15,7 @@ package testutils import ( + "context" "fmt" "testing" "time" @@ -23,6 +24,14 @@ import ( ) func ExecuteWithTimeout(t *testing.T, timeout time.Duration, f func()) { + ctx, cancel := context.WithTimeout(context.Background(), timeout) + defer cancel() + ExecuteUntil(ctx, t, f) +} + +func ExecuteUntil(ctx context.Context, t *testing.T, f func()) { + deadline, deadlineSet := ctx.Deadline() + timeout := time.Until(deadline) donec := make(chan struct{}) go func() { defer close(donec) @@ -30,8 +39,12 @@ func ExecuteWithTimeout(t *testing.T, timeout time.Duration, f func()) { }() select { - case <-time.After(timeout): - testutil.FatalStack(t, fmt.Sprintf("test timed out after %v", timeout)) + case <-ctx.Done(): + msg := ctx.Err().Error() + if deadlineSet { + msg = fmt.Sprintf("test timed out after %v, err: %v", timeout, msg) + } + testutil.FatalStack(t, msg) case <-donec: } } diff --git a/tests/framework/unit.go b/tests/framework/unit.go index 45b10ff41..27114373c 100644 --- a/tests/framework/unit.go +++ b/tests/framework/unit.go @@ -15,6 +15,7 @@ package framework import ( + "context" "flag" "fmt" "os" @@ -39,7 +40,7 @@ func (e unitRunner) TestMain(m *testing.M) { func (e unitRunner) BeforeTest(t testing.TB) { } -func (e unitRunner) NewCluster(t testing.TB, cfg config.ClusterConfig) Cluster { +func (e unitRunner) NewCluster(ctx context.Context, t testing.TB, cfg config.ClusterConfig) Cluster { testutil.SkipTestIfShortMode(t, "Cannot create clusters in --short tests") return nil }