Browse Source

store: test v2v3 store

Changes main store tests to use a timeout select instead of expecting
events to be immediately posted before returning.
Anthony Romano 8 years ago
parent
commit
75eb05a272
2 changed files with 104 additions and 29 deletions
  1. 62 29
      store/store_test.go
  2. 42 0
      store/store_v2v3_test.go

+ 62 - 29
store/store_test.go

@@ -16,6 +16,7 @@ package store_test
 
 import (
 	"testing"
+	"time"
 
 	etcdErr "github.com/coreos/etcd/error"
 	"github.com/coreos/etcd/pkg/testutil"
@@ -551,12 +552,15 @@ func TestStoreWatchCreate(t *testing.T) {
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	s.Create("/foo", false, "bar", false, store.TTLOptionSet{ExpireTime: store.Permanent})
 	eidx = 1
-	e := nbselect(c)
+	e := timeoutSelect(t, c)
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "create")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
-	e = nbselect(c)
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 }
 
 // Ensure that the store can watch for recursive key creation.
@@ -564,11 +568,12 @@ func TestStoreWatchRecursiveCreate(t *testing.T) {
 	s := newTestStore(t)
 	defer s.Close()
 	var eidx uint64 = 0
-	w, _ := s.Watch("/foo", true, false, 0)
+	w, err := s.Watch("/foo", true, false, 0)
+	testutil.AssertNil(t, err)
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 1
 	s.Create("/foo/bar", false, "baz", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "create")
 	testutil.AssertEqual(t, e.Node.Key, "/foo/bar")
@@ -584,7 +589,7 @@ func TestStoreWatchUpdate(t *testing.T) {
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.Update("/foo", "baz", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "update")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
@@ -596,11 +601,12 @@ func TestStoreWatchRecursiveUpdate(t *testing.T) {
 	defer s.Close()
 	var eidx uint64 = 1
 	s.Create("/foo/bar", false, "baz", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	w, _ := s.Watch("/foo", true, false, 0)
+	w, err := s.Watch("/foo", true, false, 0)
+	testutil.AssertNil(t, err)
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.Update("/foo/bar", "baz", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "update")
 	testutil.AssertEqual(t, e.Node.Key, "/foo/bar")
@@ -616,7 +622,7 @@ func TestStoreWatchDelete(t *testing.T) {
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.Delete("/foo", false, false)
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "delete")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
@@ -628,11 +634,12 @@ func TestStoreWatchRecursiveDelete(t *testing.T) {
 	defer s.Close()
 	var eidx uint64 = 1
 	s.Create("/foo/bar", false, "baz", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	w, _ := s.Watch("/foo", true, false, 0)
+	w, err := s.Watch("/foo", true, false, 0)
+	testutil.AssertNil(t, err)
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.Delete("/foo/bar", false, false)
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "delete")
 	testutil.AssertEqual(t, e.Node.Key, "/foo/bar")
@@ -648,7 +655,7 @@ func TestStoreWatchCompareAndSwap(t *testing.T) {
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.CompareAndSwap("/foo", "bar", 0, "baz", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "compareAndSwap")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
@@ -664,7 +671,7 @@ func TestStoreWatchRecursiveCompareAndSwap(t *testing.T) {
 	testutil.AssertEqual(t, w.StartIndex(), eidx)
 	eidx = 2
 	s.CompareAndSwap("/foo/bar", "baz", 0, "bat", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "compareAndSwap")
 	testutil.AssertEqual(t, e.Node.Key, "/foo/bar")
@@ -678,23 +685,29 @@ func TestStoreWatchStream(t *testing.T) {
 	w, _ := s.Watch("/foo", false, true, 0)
 	// first modification
 	s.Create("/foo", false, "bar", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "create")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
 	testutil.AssertEqual(t, *e.Node.Value, "bar")
-	e = nbselect(w.EventChan())
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 	// second modification
 	eidx = 2
 	s.Update("/foo", "baz", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e = nbselect(w.EventChan())
+	e = timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "update")
 	testutil.AssertEqual(t, e.Node.Key, "/foo")
 	testutil.AssertEqual(t, *e.Node.Value, "baz")
-	e = nbselect(w.EventChan())
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 }
 
 // Ensure that the store can watch for hidden keys as long as it's an exact path match.
@@ -704,12 +717,15 @@ func TestStoreWatchCreateWithHiddenKey(t *testing.T) {
 	var eidx uint64 = 1
 	w, _ := s.Watch("/_foo", false, false, 0)
 	s.Create("/_foo", false, "bar", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "create")
 	testutil.AssertEqual(t, e.Node.Key, "/_foo")
-	e = nbselect(w.EventChan())
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 }
 
 // Ensure that the store doesn't see hidden key creates without an exact path match in recursive mode.
@@ -722,11 +738,17 @@ func TestStoreWatchRecursiveCreateWithHiddenKey(t *testing.T) {
 	testutil.AssertNil(t, e)
 	w, _ = s.Watch("/foo", true, false, 0)
 	s.Create("/foo/_baz", true, "", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	e = nbselect(w.EventChan())
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 	s.Create("/foo/_baz/quux", false, "quux", false, store.TTLOptionSet{ExpireTime: store.Permanent})
-	e = nbselect(w.EventChan())
-	testutil.AssertNil(t, e)
+	select {
+	case e = <-w.EventChan():
+		testutil.AssertNil(t, e)
+	case <-time.After(100 * time.Millisecond):
+	}
 }
 
 // Ensure that the store doesn't see hidden key updates.
@@ -736,7 +758,7 @@ func TestStoreWatchUpdateWithHiddenKey(t *testing.T) {
 	s.Create("/_foo", false, "bar", false, store.TTLOptionSet{ExpireTime: store.Permanent})
 	w, _ := s.Watch("/_foo", false, false, 0)
 	s.Update("/_foo", "baz", store.TTLOptionSet{ExpireTime: store.Permanent})
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.Action, "update")
 	testutil.AssertEqual(t, e.Node.Key, "/_foo")
 	e = nbselect(w.EventChan())
@@ -762,7 +784,7 @@ func TestStoreWatchDeleteWithHiddenKey(t *testing.T) {
 	s.Create("/_foo", false, "bar", false, store.TTLOptionSet{ExpireTime: store.Permanent})
 	w, _ := s.Watch("/_foo", false, false, 0)
 	s.Delete("/_foo", false, false)
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "delete")
 	testutil.AssertEqual(t, e.Node.Key, "/_foo")
@@ -789,7 +811,7 @@ func TestStoreWatchRecursiveCreateDeeperThanHiddenKey(t *testing.T) {
 	w, _ := s.Watch("/_foo/bar", true, false, 0)
 	s.Create("/_foo/bar/baz", false, "baz", false, store.TTLOptionSet{ExpireTime: store.Permanent})
 
-	e := nbselect(w.EventChan())
+	e := timeoutSelect(t, w.EventChan())
 	testutil.AssertNotNil(t, e)
 	testutil.AssertEqual(t, e.EtcdIndex, eidx)
 	testutil.AssertEqual(t, e.Action, "create")
@@ -827,3 +849,14 @@ func nbselect(c <-chan *store.Event) *store.Event {
 		return nil
 	}
 }
+
+// Performs a non-blocking select on an event channel.
+func timeoutSelect(t *testing.T, c <-chan *store.Event) *store.Event {
+	select {
+	case e := <-c:
+		return e
+	case <-time.After(time.Second):
+		t.Errorf("timed out waiting on event")
+		return nil
+	}
+}

+ 42 - 0
store/store_v2v3_test.go

@@ -0,0 +1,42 @@
+// Copyright 2017 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.
+
+// +build v2v3
+
+package store_test
+
+import (
+	"testing"
+
+	"github.com/coreos/etcd/etcdserver/api/v2v3"
+	"github.com/coreos/etcd/integration"
+	"github.com/coreos/etcd/store"
+)
+
+type v2v3TestStore struct {
+	store.Store
+	clus *integration.ClusterV3
+	t    *testing.T
+}
+
+func (s *v2v3TestStore) Close() { s.clus.Terminate(s.t) }
+
+func newTestStore(t *testing.T, ns ...string) StoreCloser {
+	clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
+	return &v2v3TestStore{
+		v2v3.NewStore(clus.Client(0), "/v2/"),
+		clus,
+		t,
+	}
+}