Browse Source

Merge pull request #8790 from gyuho/blackhole-immutable

clientv3/integration: add blackhole tests for range RPCs
Gyu-Ho Lee 8 years ago
parent
commit
63d0ac0fe6
1 changed files with 43 additions and 8 deletions
  1. 43 8
      clientv3/integration/black_hole_test.go

+ 43 - 8
clientv3/integration/black_hole_test.go

@@ -22,6 +22,7 @@ import (
 	"time"
 	"time"
 
 
 	"github.com/coreos/etcd/clientv3"
 	"github.com/coreos/etcd/clientv3"
+	"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
 	"github.com/coreos/etcd/integration"
 	"github.com/coreos/etcd/integration"
 	"github.com/coreos/etcd/pkg/testutil"
 	"github.com/coreos/etcd/pkg/testutil"
 )
 )
@@ -103,30 +104,61 @@ func TestBalancerUnderBlackholeKeepAliveWatch(t *testing.T) {
 }
 }
 
 
 func TestBalancerUnderBlackholeNoKeepAlivePut(t *testing.T) {
 func TestBalancerUnderBlackholeNoKeepAlivePut(t *testing.T) {
-	testBalancerUnderBlackholeNoKeepAliveMutable(t, func(cli *clientv3.Client, ctx context.Context) error {
+	testBalancerUnderBlackholeNoKeepAlive(t, func(cli *clientv3.Client, ctx context.Context) error {
 		_, err := cli.Put(ctx, "foo", "bar")
 		_, err := cli.Put(ctx, "foo", "bar")
+		if err == context.DeadlineExceeded || err == rpctypes.ErrTimeout {
+			return errExpected
+		}
 		return err
 		return err
 	})
 	})
 }
 }
 
 
 func TestBalancerUnderBlackholeNoKeepAliveDelete(t *testing.T) {
 func TestBalancerUnderBlackholeNoKeepAliveDelete(t *testing.T) {
-	testBalancerUnderBlackholeNoKeepAliveMutable(t, func(cli *clientv3.Client, ctx context.Context) error {
+	testBalancerUnderBlackholeNoKeepAlive(t, func(cli *clientv3.Client, ctx context.Context) error {
 		_, err := cli.Delete(ctx, "foo")
 		_, err := cli.Delete(ctx, "foo")
+		if err == context.DeadlineExceeded || err == rpctypes.ErrTimeout {
+			return errExpected
+		}
 		return err
 		return err
 	})
 	})
 }
 }
 
 
 func TestBalancerUnderBlackholeNoKeepAliveTxn(t *testing.T) {
 func TestBalancerUnderBlackholeNoKeepAliveTxn(t *testing.T) {
-	testBalancerUnderBlackholeNoKeepAliveMutable(t, func(cli *clientv3.Client, ctx context.Context) error {
+	testBalancerUnderBlackholeNoKeepAlive(t, func(cli *clientv3.Client, ctx context.Context) error {
 		_, err := cli.Txn(ctx).
 		_, err := cli.Txn(ctx).
 			If(clientv3.Compare(clientv3.Version("foo"), "=", 0)).
 			If(clientv3.Compare(clientv3.Version("foo"), "=", 0)).
 			Then(clientv3.OpPut("foo", "bar")).
 			Then(clientv3.OpPut("foo", "bar")).
 			Else(clientv3.OpPut("foo", "baz")).Commit()
 			Else(clientv3.OpPut("foo", "baz")).Commit()
+		if err == context.DeadlineExceeded || err == rpctypes.ErrTimeout {
+			return errExpected
+		}
+		return err
+	})
+}
+
+func TestBalancerUnderBlackholeNoKeepAliveLinearizableGet(t *testing.T) {
+	testBalancerUnderBlackholeNoKeepAlive(t, func(cli *clientv3.Client, ctx context.Context) error {
+		_, err := cli.Get(ctx, "a")
+		if err == context.DeadlineExceeded || err == rpctypes.ErrTimeout {
+			return errExpected
+		}
 		return err
 		return err
 	})
 	})
 }
 }
 
 
-func testBalancerUnderBlackholeNoKeepAliveMutable(t *testing.T, op func(*clientv3.Client, context.Context) error) {
+func TestBalancerUnderBlackholeNoKeepAliveSerializableGet(t *testing.T) {
+	testBalancerUnderBlackholeNoKeepAlive(t, func(cli *clientv3.Client, ctx context.Context) error {
+		_, err := cli.Get(ctx, "a", clientv3.WithSerializable())
+		if err == context.DeadlineExceeded {
+			return errExpected
+		}
+		return err
+	})
+}
+
+// testBalancerUnderBlackholeNoKeepAlive ensures that first request to blackholed endpoint
+// fails due to context timeout, but succeeds on next try, with endpoint switch.
+func testBalancerUnderBlackholeNoKeepAlive(t *testing.T, op func(*clientv3.Client, context.Context) error) {
 	defer testutil.AfterTest(t)
 	defer testutil.AfterTest(t)
 
 
 	clus := integration.NewClusterV3(t, &integration.ClusterConfig{
 	clus := integration.NewClusterV3(t, &integration.ClusterConfig{
@@ -158,18 +190,21 @@ func testBalancerUnderBlackholeNoKeepAliveMutable(t *testing.T, op func(*clientv
 	clus.Members[0].Blackhole()
 	clus.Members[0].Blackhole()
 
 
 	// fail first due to blackhole, retry should succeed
 	// fail first due to blackhole, retry should succeed
-	// TODO: first mutable operation can succeed
+	// TODO: first operation can succeed
 	// when gRPC supports better retry on non-delivered request
 	// when gRPC supports better retry on non-delivered request
 	for i := 0; i < 2; i++ {
 	for i := 0; i < 2; i++ {
 		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
 		err = op(cli, ctx)
 		err = op(cli, ctx)
 		cancel()
 		cancel()
+		if err == nil {
+			break
+		}
 		if i == 0 {
 		if i == 0 {
-			if err != context.DeadlineExceeded {
-				t.Fatalf("#%d: err = %v, want %v", i, err, context.DeadlineExceeded)
+			if err != errExpected {
+				t.Errorf("#%d: expected %v, got %v", i, errExpected, err)
 			}
 			}
 		} else if err != nil {
 		} else if err != nil {
-			t.Errorf("#%d: mutable operation failed with error %v", i, err)
+			t.Errorf("#%d: failed with error %v", i, err)
 		}
 		}
 	}
 	}
 }
 }