Browse Source

Merge pull request #4430 from heyitsanthony/clientv3-test-kv-retry

clientv3/integration: test Get retry
Anthony Romano 10 years ago
parent
commit
7960bd8690
1 changed files with 88 additions and 0 deletions
  1. 88 0
      clientv3/integration/kv_test.go

+ 88 - 0
clientv3/integration/kv_test.go

@@ -18,6 +18,7 @@ import (
 	"bytes"
 	"bytes"
 	"reflect"
 	"reflect"
 	"testing"
 	"testing"
+	"time"
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3"
@@ -290,3 +291,90 @@ func TestKVCompact(t *testing.T) {
 		t.Fatalf("error got %v, want %v", err, v3rpc.ErrFutureRev)
 		t.Fatalf("error got %v, want %v", err, v3rpc.ErrFutureRev)
 	}
 	}
 }
 }
+
+// TestKVGetRetry ensures get will retry on disconnect.
+func TestKVGetRetry(t *testing.T) {
+	defer testutil.AfterTest(t)
+
+	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
+	defer clus.Terminate(t)
+
+	kv := clientv3.NewKV(clus.Client(0))
+
+	if _, err := kv.Put("foo", "bar", 0); err != nil {
+		t.Fatal(err)
+	}
+
+	clus.Members[0].Stop(t)
+	<-clus.Members[0].StopNotify()
+
+	donec := make(chan struct{})
+	go func() {
+		// Get will fail, but reconnect will trigger
+		gresp, gerr := kv.Get("foo", 0)
+		if gerr != nil {
+			t.Fatal(gerr)
+		}
+		wkvs := []*storagepb.KeyValue{
+			{
+				Key:            []byte("foo"),
+				Value:          []byte("bar"),
+				CreateRevision: 2,
+				ModRevision:    2,
+				Version:        1,
+			},
+		}
+		if !reflect.DeepEqual(gresp.Kvs, wkvs) {
+			t.Fatalf("bad get: got %v, want %v", gresp.Kvs, wkvs)
+		}
+		donec <- struct{}{}
+	}()
+
+	time.Sleep(100 * time.Millisecond)
+	clus.Members[0].Restart(t)
+
+	select {
+	case <-time.After(5 * time.Second):
+		t.Fatalf("timed out waiting for get")
+	case <-donec:
+	}
+}
+
+// TestKVPutFailGetRetry ensures a get will retry following a failed put.
+func TestKVPutFailGetRetry(t *testing.T) {
+	defer testutil.AfterTest(t)
+
+	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 3})
+	defer clus.Terminate(t)
+
+	kv := clientv3.NewKV(clus.Client(0))
+	clus.Members[0].Stop(t)
+	<-clus.Members[0].StopNotify()
+
+	_, err := kv.Put("foo", "bar", 0)
+	if err == nil {
+		t.Fatalf("got success on disconnected put, wanted error")
+	}
+
+	donec := make(chan struct{})
+	go func() {
+		// Get will fail, but reconnect will trigger
+		gresp, gerr := kv.Get("foo", 0)
+		if gerr != nil {
+			t.Fatal(gerr)
+		}
+		if len(gresp.Kvs) != 0 {
+			t.Fatalf("bad get kvs: got %+v, want empty", gresp.Kvs)
+		}
+		donec <- struct{}{}
+	}()
+
+	time.Sleep(100 * time.Millisecond)
+	clus.Members[0].Restart(t)
+
+	select {
+	case <-time.After(5 * time.Second):
+		t.Fatalf("timed out waiting for get")
+	case <-donec:
+	}
+}