test: Remove usage of V2 Put API in tests

This commit is contained in:
Marek Siarkowicz 2022-01-18 16:37:00 +01:00
parent de30257d79
commit 7b365e48d3
5 changed files with 31 additions and 186 deletions

View File

@ -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
},
}
}

View File

@ -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

View File

@ -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)
}

View File

@ -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()

View File

@ -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")
}
}
}