clientv3/integration: test client puts at most once on bad connection
@@ -895,3 +895,40 @@ func TestKVGetResetLoneEndpoint(t *testing.T) {
case <-donec:
}
}
+
+// TestKVPutAtMostOnce ensures that a Put will only occur at most once
+// in the presence of network errors.
+func TestKVPutAtMostOnce(t *testing.T) {
+ defer testutil.AfterTest(t)
+ clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
+ defer clus.Terminate(t)
+
+ if _, err := clus.Client(0).Put(context.TODO(), "k", "1"); err != nil {
+ t.Fatal(err)
+ }
+
+ for i := 0; i < 10; i++ {
+ clus.Members[0].DropConnections()
+ donec := make(chan struct{})
+ go func() {
+ defer close(donec)
+ for i := 0; i < 10; i++ {
+ clus.Members[0].DropConnections()
+ time.Sleep(5 * time.Millisecond)
+ }
+ }()
+ _, err := clus.Client(0).Put(context.TODO(), "k", "v")
+ <-donec
+ if err != nil {
+ break
+ }
+ }
+
+ resp, err := clus.Client(0).Get(context.TODO(), "k")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if resp.Kvs[0].Version > 11 {
+ t.Fatalf("expected version <= 10, got %+v", resp.Kvs[0])
+ }
+}
