Bladeren bron

e2e: add Get tests

Gyu-Ho Lee 9 jaren geleden
bovenliggende
commit
dc0061e4db
1 gewijzigde bestanden met toevoegingen van 100 en 40 verwijderingen
  1. 100 40
      e2e/etcdctlv3_test.go

+ 100 - 40
e2e/etcdctlv3_test.go

@@ -25,35 +25,40 @@ import (
 	"github.com/coreos/etcd/pkg/testutil"
 )
 
-func TestCtlV3Put(t *testing.T)              { testCtl(t, putTest) }
-func TestCtlV3PutTimeout(t *testing.T)       { testCtl(t, putTest, withDialTimeout(0)) }
-func TestCtlV3PutTimeoutQuorum(t *testing.T) { testCtl(t, putTest, withDialTimeout(0), withQuorum()) }
-func TestCtlV3PutAutoTLS(t *testing.T)       { testCtl(t, putTest, withCfg(configAutoTLS)) }
-func TestCtlV3PutPeerTLS(t *testing.T)       { testCtl(t, putTest, withCfg(configPeerTLS)) }
-func TestCtlV3PutClientTLS(t *testing.T)     { testCtl(t, putTest, withCfg(configClientTLS)) }
-
-func TestCtlV3Watch(t *testing.T)        { testCtl(t, watchTest) }
-func TestCtlV3WatchAutoTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configAutoTLS)) }
-func TestCtlV3WatchPeerTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configPeerTLS)) }
-
-// TODO: Watch with client TLS is not working
-// func TestCtlV3WatchClientTLS(t *testing.T) {
-// 	testCtl(t, watchTest, withCfg(configClientTLS))
-// }
-
-func TestCtlV3WatchInteractive(t *testing.T) { testCtl(t, watchTest, withInteractive()) }
-func TestCtlV3WatchInteractiveAutoTLS(t *testing.T) {
-	testCtl(t, watchTest, withInteractive(), withCfg(configAutoTLS))
+func TestCtlV3Put(t *testing.T)          { testCtl(t, putTest) }
+func TestCtlV3PutNoTLS(t *testing.T)     { testCtl(t, putTest, withCfg(configNoTLS)) }
+func TestCtlV3PutClientTLS(t *testing.T) { testCtl(t, putTest, withCfg(configClientTLS)) }
+func TestCtlV3PutPeerTLS(t *testing.T)   { testCtl(t, putTest, withCfg(configPeerTLS)) }
+
+func TestCtlV3PutTimeout(t *testing.T) { testCtl(t, putTest, withDialTimeout(0)) }
+
+func TestCtlV3Get(t *testing.T)          { testCtl(t, getTest) }
+func TestCtlV3GetNoTLS(t *testing.T)     { testCtl(t, getTest, withCfg(configNoTLS)) }
+func TestCtlV3GetClientTLS(t *testing.T) { testCtl(t, getTest, withCfg(configClientTLS)) }
+func TestCtlV3GetPeerTLS(t *testing.T)   { testCtl(t, getTest, withCfg(configPeerTLS)) }
+
+func TestCtlV3GetPrefix(t *testing.T)      { testCtl(t, getTest, withPrefix()) }
+func TestCtlV3GetPrefixLimit(t *testing.T) { testCtl(t, getTest, withPrefix(), withLimit(2)) }
+func TestCtlV3GetQuorum(t *testing.T)      { testCtl(t, getTest, withQuorum()) }
+
+func TestCtlV3Watch(t *testing.T)          { testCtl(t, watchTest) }
+func TestCtlV3WatchNoTLS(t *testing.T)     { testCtl(t, watchTest, withCfg(configNoTLS)) }
+func TestCtlV3WatchClientTLS(t *testing.T) { testCtl(t, watchTest, withCfg(configClientTLS)) }
+func TestCtlV3WatchPeerTLS(t *testing.T)   { testCtl(t, watchTest, withCfg(configPeerTLS)) }
+
+func TestCtlV3WatchInteractive(t *testing.T) {
+	testCtl(t, watchTest, withInteractive())
+}
+func TestCtlV3WatchInteractiveNoTLS(t *testing.T) {
+	testCtl(t, watchTest, withInteractive(), withCfg(configNoTLS))
+}
+func TestCtlV3WatchInteractiveClientTLS(t *testing.T) {
+	testCtl(t, watchTest, withInteractive(), withCfg(configClientTLS))
 }
 func TestCtlV3WatchInteractivePeerTLS(t *testing.T) {
 	testCtl(t, watchTest, withInteractive(), withCfg(configPeerTLS))
 }
 
-// TODO: Watch with client TLS is not working
-// func TestCtlV3WatchInteractiveClientTLS(t *testing.T) {
-// 	testCtl(t, watchTest, withInteractive(), withCfg(configClientTLS))
-// }
-
 type ctlCtx struct {
 	t   *testing.T
 	cfg etcdProcessClusterConfig
@@ -62,9 +67,12 @@ type ctlCtx struct {
 	errc        chan error
 	dialTimeout time.Duration
 
-	quorum        bool
+	prefix        bool
+	quorum        bool // if true, set up 3-node cluster and linearizable read
 	interactive   bool
 	watchRevision int
+
+	limit int
 }
 
 type ctlOption func(*ctlCtx)
@@ -83,6 +91,10 @@ func withDialTimeout(timeout time.Duration) ctlOption {
 	return func(cx *ctlCtx) { cx.dialTimeout = timeout }
 }
 
+func withPrefix() ctlOption {
+	return func(cx *ctlCtx) { cx.prefix = true }
+}
+
 func withQuorum() ctlOption {
 	return func(cx *ctlCtx) { cx.quorum = true }
 }
@@ -95,6 +107,10 @@ func withWatchRevision(rev int) ctlOption {
 	return func(cx *ctlCtx) { cx.watchRevision = rev }
 }
 
+func withLimit(limit int) ctlOption {
+	return func(cx *ctlCtx) { cx.limit = limit }
+}
+
 func setupCtlV3Test(t *testing.T, cfg etcdProcessClusterConfig, quorum bool) *etcdProcessCluster {
 	mustEtcdctl(t)
 	if !quorum {
@@ -116,7 +132,7 @@ func testCtl(t *testing.T, testFunc func(ctlCtx), opts ...ctlOption) {
 	)
 	ret := ctlCtx{
 		t:             t,
-		cfg:           configNoTLS,
+		cfg:           configAutoTLS,
 		errc:          make(chan error, 1),
 		dialTimeout:   defaultDialTimeout,
 		watchRevision: defaultWatchRevision,
@@ -149,43 +165,71 @@ func testCtl(t *testing.T, testFunc func(ctlCtx), opts ...ctlOption) {
 }
 
 func putTest(cx ctlCtx) {
-	key, value := "foo", "bar"
-
 	defer close(cx.errc)
 
+	key, value := "foo", "bar"
+
 	if err := ctlV3Put(cx, key, value); err != nil {
 		if cx.dialTimeout > 0 && isGRPCTimedout(err) {
-			cx.errc <- fmt.Errorf("put error (%v)", err)
-			return
+			cx.t.Fatalf("putTest error (%v)", err)
 		}
 	}
-	if err := ctlV3Get(cx, key, value); err != nil {
+	if err := ctlV3Get(cx, key, kv{key, value}); err != nil {
 		if cx.dialTimeout > 0 && isGRPCTimedout(err) {
-			cx.errc <- fmt.Errorf("get error (%v)", err)
-			return
+			cx.t.Fatalf("putTest error (%v)", err)
 		}
 	}
 }
 
 func watchTest(cx ctlCtx) {
-	key, value := "foo", "bar"
-
 	defer close(cx.errc)
 
+	key, value := "foo", "bar"
+
 	go func() {
 		if err := ctlV3Put(cx, key, value); err != nil {
-			cx.t.Fatal(err)
+			cx.t.Fatalf("watchTest error (%v)", err)
 		}
 	}()
 
 	if err := ctlV3Watch(cx, key, value); err != nil {
 		if cx.dialTimeout > 0 && isGRPCTimedout(err) {
-			cx.errc <- fmt.Errorf("watch error (%v)", err)
-			return
+			cx.t.Fatalf("watchTest error (%v)", err)
 		}
 	}
 }
 
+func getTest(cx ctlCtx) {
+	defer close(cx.errc)
+
+	var (
+		kvs = []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}
+	)
+
+	for i := range kvs {
+		if err := ctlV3Put(cx, kvs[i].key, kvs[i].val); err != nil {
+			if cx.dialTimeout > 0 && isGRPCTimedout(err) {
+				cx.t.Fatalf("getTest error (%v)", err)
+			}
+		}
+	}
+
+	if cx.limit > 0 {
+		kvs = kvs[:cx.limit]
+	}
+	keyToGet := "key"
+	if !cx.prefix {
+		keyToGet = "key1"
+		kvs = kvs[:1]
+	}
+	// TODO: configure order, sort-by
+
+	if err := ctlV3Get(cx, keyToGet, kvs...); err != nil {
+		if cx.dialTimeout > 0 && isGRPCTimedout(err) {
+			cx.t.Fatalf("getTest error (%v)", err)
+		}
+	}
+}
 func ctlV3PrefixArgs(clus *etcdProcessCluster, dialTimeout time.Duration) []string {
 	if len(clus.proxies()) > 0 { // TODO: add proxy check as in v2
 		panic("v3 proxy not implemented")
@@ -211,12 +255,28 @@ func ctlV3Put(cx ctlCtx, key, value string) error {
 	return spawnWithExpect(cmdArgs, "OK")
 }
 
-func ctlV3Get(cx ctlCtx, key, value string) error {
+type kv struct {
+	key, val string
+}
+
+func ctlV3Get(cx ctlCtx, key string, kvs ...kv) error {
 	cmdArgs := append(ctlV3PrefixArgs(cx.epc, cx.dialTimeout), "get", key)
 	if !cx.quorum {
 		cmdArgs = append(cmdArgs, "--consistency", "s")
 	}
-	return spawnWithExpects(cmdArgs, key, value)
+	if cx.prefix {
+		cmdArgs = append(cmdArgs, "--prefix")
+	}
+	if cx.limit > 0 {
+		cmdArgs = append(cmdArgs, "--limit", strconv.Itoa(cx.limit))
+	}
+	// TODO: configure order, sort-by
+
+	var lines []string
+	for _, elem := range kvs {
+		lines = append(lines, elem.key, elem.val)
+	}
+	return spawnWithExpects(cmdArgs, lines...)
 }
 
 func ctlV3Watch(cx ctlCtx, key, value string) error {