diff --git a/tests/integration/client/client_test.go b/tests/integration/client/client_test.go deleted file mode 100644 index 132118b9a..000000000 --- a/tests/integration/client/client_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2016 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 integration - -import ( - "context" - "fmt" - "net/http" - "net/http/httptest" - "os" - "strings" - "sync/atomic" - "testing" - - "go.etcd.io/etcd/client/v2" - integration2 "go.etcd.io/etcd/tests/v3/framework/integration" -) - -// TestV2NoRetryEOF tests destructive api calls won't retry on a disconnection. -func TestV2NoRetryEOF(t *testing.T) { - integration2.BeforeTest(t) - // generate an EOF response; specify address so appears first in sorted ep list - lEOF := integration2.NewListenerWithAddr(t, fmt.Sprintf("127.0.0.1:%05d", os.Getpid())) - defer lEOF.Close() - tries := uint32(0) - go func() { - for { - conn, err := lEOF.Accept() - if err != nil { - return - } - atomic.AddUint32(&tries, 1) - conn.Close() - } - }() - eofURL := integration2.URLScheme + "://" + lEOF.Addr().String() - cli := integration2.MustNewHTTPClient(t, []string{eofURL, eofURL}, nil) - kapi := client.NewKeysAPI(cli) - for i, f := range noRetryList(kapi) { - startTries := atomic.LoadUint32(&tries) - if err := f(); err == nil { - t.Errorf("#%d: expected EOF error, got nil", i) - } - endTries := atomic.LoadUint32(&tries) - if startTries+1 != endTries { - t.Errorf("#%d: expected 1 try, got %d", i, endTries-startTries) - } - } -} - -// TestV2NoRetryNoLeader tests destructive api calls won't retry if given an error code. -func TestV2NoRetryNoLeader(t *testing.T) { - integration2.BeforeTest(t) - lHTTP := integration2.NewListenerWithAddr(t, fmt.Sprintf("127.0.0.1:%05d", os.Getpid())) - eh := &errHandler{errCode: http.StatusServiceUnavailable} - srv := httptest.NewUnstartedServer(eh) - defer lHTTP.Close() - defer srv.Close() - srv.Listener = lHTTP - go srv.Start() - lHTTPURL := integration2.URLScheme + "://" + lHTTP.Addr().String() - - cli := integration2.MustNewHTTPClient(t, []string{lHTTPURL, lHTTPURL}, nil) - kapi := client.NewKeysAPI(cli) - // test error code - for i, f := range noRetryList(kapi) { - reqs := eh.reqs - if err := f(); err == nil || !strings.Contains(err.Error(), "no leader") { - t.Errorf("#%d: expected \"no leader\", got %v", i, err) - } - if eh.reqs != reqs+1 { - t.Errorf("#%d: expected 1 request, got %d", i, eh.reqs-reqs) - } - } -} - -// TestV2RetryRefuse tests destructive api calls will retry if a connection is refused. -func TestV2RetryRefuse(t *testing.T) { - integration2.BeforeTest(t) - cl := integration2.NewClusterV3(t, &integration2.ClusterConfig{Size: 1}) - defer cl.Terminate(t) - // test connection refused; expect no error failover - cli := integration2.MustNewHTTPClient(t, []string{integration2.URLScheme + "://refuseconn:123", cl.URL(0)}, nil) - kapi := client.NewKeysAPI(cli) - if _, err := kapi.Set(context.Background(), "/delkey", "def", nil); err != nil { - t.Fatal(err) - } - for i, f := range noRetryList(kapi) { - if err := f(); err != nil { - t.Errorf("#%d: unexpected retry failure (%v)", i, err) - } - } -} - -type errHandler struct { - errCode int - reqs int -} - -func (eh *errHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { - req.Body.Close() - eh.reqs++ - w.WriteHeader(eh.errCode) -} - -func noRetryList(kapi client.KeysAPI) []func() error { - return []func() error{ - func() error { - opts := &client.SetOptions{PrevExist: client.PrevNoExist} - _, err := kapi.Set(context.Background(), "/setkey", "bar", opts) - return err - }, - func() error { - _, err := kapi.Delete(context.Background(), "/delkey", nil) - return err - }, - } -} diff --git a/tests/integration/client/doc.go b/tests/integration/client/doc.go deleted file mode 100644 index e9c58d67f..000000000 --- a/tests/integration/client/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2016 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 integration implements tests built upon embedded etcd, focusing on -// the correctness of the etcd v2 client. -package integration diff --git a/tests/integration/client/main_test.go b/tests/integration/client/main_test.go deleted file mode 100644 index e78320583..000000000 --- a/tests/integration/client/main_test.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package integration - -import ( - "testing" - - "go.etcd.io/etcd/client/pkg/v3/testutil" -) - -func TestMain(m *testing.M) { - testutil.MustTestMainWithLeakDetection(m) -} diff --git a/tests/integration/cluster_test.go b/tests/integration/cluster_test.go index 9bc985de6..5a8730170 100644 --- a/tests/integration/cluster_test.go +++ b/tests/integration/cluster_test.go @@ -163,18 +163,27 @@ func testDecreaseClusterSize(t *testing.T, size int) { func TestForceNewCluster(t *testing.T) { integration.BeforeTest(t) c := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3, UseBridge: true}) - cc := integration.MustNewHTTPClient(t, []string{c.Members[0].URL()}, nil) - kapi := client.NewKeysAPI(cc) + defer c.Terminate(t) + ctx, cancel := context.WithTimeout(context.Background(), integration.RequestTimeout) - resp, err := kapi.Create(ctx, "/foo", "bar") + resp, err := c.Members[0].Client.Put(ctx, "/foo", "bar") if err != nil { t.Fatalf("unexpected create error: %v", err) } cancel() // ensure create has been applied in this machine ctx, cancel = context.WithTimeout(context.Background(), integration.RequestTimeout) - if _, err = kapi.Watcher("/foo", &client.WatcherOptions{AfterIndex: resp.Node.ModifiedIndex - 1}).Next(ctx); err != nil { - t.Fatalf("unexpected watch error: %v", err) + watch := c.Members[0].Client.Watcher.Watch(ctx, "/foo", clientv3.WithRev(resp.Header.Revision-1)) + for resp := range watch { + if len(resp.Events) != 0 { + break + } + if resp.Err() != nil { + t.Fatalf("unexpected watch error: %q", resp.Err()) + } + if resp.Canceled { + t.Fatalf("watch cancelled") + } } cancel() @@ -186,16 +195,22 @@ func TestForceNewCluster(t *testing.T) { if err != nil { t.Fatalf("unexpected ForceRestart error: %v", err) } - defer c.Members[0].Terminate(t) c.WaitMembersForLeader(t, c.Members[:1]) // use new http client to init new connection - cc = integration.MustNewHTTPClient(t, []string{c.Members[0].URL()}, nil) - kapi = client.NewKeysAPI(cc) // ensure force restart keep the old data, and new Cluster can make progress ctx, cancel = context.WithTimeout(context.Background(), integration.RequestTimeout) - if _, err := kapi.Watcher("/foo", &client.WatcherOptions{AfterIndex: resp.Node.ModifiedIndex - 1}).Next(ctx); err != nil { - t.Fatalf("unexpected watch error: %v", err) + watch = c.Members[0].Client.Watcher.Watch(ctx, "/foo", clientv3.WithRev(resp.Header.Revision-1)) + for resp := range watch { + if len(resp.Events) != 0 { + break + } + if resp.Err() != nil { + t.Fatalf("unexpected watch error: %q", resp.Err()) + } + if resp.Canceled { + t.Fatalf("watch cancelled") + } } cancel() clusterMustProgress(t, c.Members[:1]) @@ -338,10 +353,8 @@ func TestIssue3699(t *testing.T) { c.WaitMembersForLeader(t, c.Members) // try to participate in Cluster - cc := integration.MustNewHTTPClient(t, []string{c.URL(0)}, c.Cfg.ClientTLS) - kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), integration.RequestTimeout) - if _, err := kapi.Set(ctx, "/foo", "bar", nil); err != nil { + if _, err := c.Members[0].Client.Put(ctx, "/foo", "bar"); err != nil { t.Fatalf("unexpected error on Set (%v)", err) } cancel() diff --git a/tests/integration/member_test.go b/tests/integration/member_test.go index 2fb834ff0..0ac006e50 100644 --- a/tests/integration/member_test.go +++ b/tests/integration/member_test.go @@ -18,11 +18,9 @@ import ( "context" "fmt" "os" - "reflect" "testing" "github.com/stretchr/testify/assert" - "go.etcd.io/etcd/client/v2" "go.etcd.io/etcd/tests/v3/framework/integration" ) @@ -90,16 +88,14 @@ func TestSnapshotAndRestartMember(t *testing.T) { m.SnapshotCount = 100 m.Launch() defer m.Terminate(t) + defer m.Client.Close() m.WaitOK(t) - resps := make([]*client.Response, 120) var err error for i := 0; i < 120; i++ { - cc := integration.MustNewHTTPClient(t, []string{m.URL()}, nil) - kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), integration.RequestTimeout) key := fmt.Sprintf("foo%d", i) - resps[i], err = kapi.Create(ctx, "/"+key, "bar") + _, err = m.Client.Put(ctx, "/"+key, "bar") if err != nil { t.Fatalf("#%d: create on %s error: %v", i, m.URL(), err) } @@ -110,18 +106,16 @@ func TestSnapshotAndRestartMember(t *testing.T) { m.WaitOK(t) for i := 0; i < 120; i++ { - cc := integration.MustNewHTTPClient(t, []string{m.URL()}, nil) - kapi := client.NewKeysAPI(cc) ctx, cancel := context.WithTimeout(context.Background(), integration.RequestTimeout) key := fmt.Sprintf("foo%d", i) - resp, err := kapi.Get(ctx, "/"+key, nil) + resp, err := m.Client.Get(ctx, "/"+key) if err != nil { t.Fatalf("#%d: get on %s error: %v", i, m.URL(), err) } cancel() - if !reflect.DeepEqual(resp.Node, resps[i].Node) { - t.Errorf("#%d: node = %v, want %v", i, resp.Node, resps[i].Node) + if len(resp.Kvs) != 1 || string(resp.Kvs[0].Value) != "bar" { + t.Errorf("#%d: got = %v, want %v", i, resp.Kvs[0], "bar") } } }