Fix RunUntil and stop leaking watch channel on etcd error
This commit is contained in:
78
pkg/client/cache/reflector_test.go
vendored
78
pkg/client/cache/reflector_test.go
vendored
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||
)
|
||||
|
||||
@@ -37,6 +38,60 @@ func (t *testLW) Watch(resourceVersion string) (watch.Interface, error) {
|
||||
return t.WatchFunc(resourceVersion)
|
||||
}
|
||||
|
||||
func TestCloseWatchChannelOnError(t *testing.T) {
|
||||
r := NewReflector(&testLW{}, &api.Pod{}, NewStore(MetaNamespaceKeyFunc), 0)
|
||||
pod := &api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}}
|
||||
fw := watch.NewFake()
|
||||
r.listerWatcher = &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil
|
||||
},
|
||||
}
|
||||
go r.listAndWatch(util.NeverStop)
|
||||
fw.Error(pod)
|
||||
select {
|
||||
case _, ok := <-fw.ResultChan():
|
||||
if ok {
|
||||
t.Errorf("Watch channel left open after cancellation")
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Errorf("the cancellation is at least 99 milliseconds late")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunUntil(t *testing.T) {
|
||||
stopCh := make(chan struct{})
|
||||
store := NewStore(MetaNamespaceKeyFunc)
|
||||
r := NewReflector(&testLW{}, &api.Pod{}, store, 0)
|
||||
fw := watch.NewFake()
|
||||
r.listerWatcher = &testLW{
|
||||
WatchFunc: func(rv string) (watch.Interface, error) {
|
||||
return fw, nil
|
||||
},
|
||||
ListFunc: func() (runtime.Object, error) {
|
||||
return &api.PodList{ListMeta: api.ListMeta{ResourceVersion: "1"}}, nil
|
||||
},
|
||||
}
|
||||
r.RunUntil(stopCh)
|
||||
// Synchronously add a dummy pod into the watch channel so we
|
||||
// know the RunUntil go routine is in the watch handler.
|
||||
fw.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: "bar"}})
|
||||
stopCh <- struct{}{}
|
||||
select {
|
||||
case _, ok := <-fw.ResultChan():
|
||||
if ok {
|
||||
t.Errorf("Watch channel left open after stopping the watch")
|
||||
}
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
t.Errorf("the cancellation is at least 99 milliseconds late")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflector_resyncChan(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, time.Millisecond)
|
||||
@@ -57,7 +112,7 @@ func TestReflector_watchHandlerError(t *testing.T) {
|
||||
fw.Stop()
|
||||
}()
|
||||
var resumeRV string
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch)
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, util.NeverStop)
|
||||
if err == nil {
|
||||
t.Errorf("unexpected non-error")
|
||||
}
|
||||
@@ -77,7 +132,7 @@ func TestReflector_watchHandler(t *testing.T) {
|
||||
fw.Stop()
|
||||
}()
|
||||
var resumeRV string
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch)
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, util.NeverStop)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %v", err)
|
||||
}
|
||||
@@ -126,12 +181,25 @@ func TestReflector_watchHandlerTimeout(t *testing.T) {
|
||||
var resumeRV string
|
||||
exit := make(chan time.Time, 1)
|
||||
exit <- time.Now()
|
||||
err := g.watchHandler(fw, &resumeRV, exit)
|
||||
err := g.watchHandler(fw, &resumeRV, exit, util.NeverStop)
|
||||
if err != errorResyncRequested {
|
||||
t.Errorf("expected timeout error, but got %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflectorStopWatch(t *testing.T) {
|
||||
s := NewStore(MetaNamespaceKeyFunc)
|
||||
g := NewReflector(&testLW{}, &api.Pod{}, s, 0)
|
||||
fw := watch.NewFake()
|
||||
var resumeRV string
|
||||
stopWatch := make(chan struct{}, 1)
|
||||
stopWatch <- struct{}{}
|
||||
err := g.watchHandler(fw, &resumeRV, neverExitWatch, stopWatch)
|
||||
if err != errorStopRequested {
|
||||
t.Errorf("expected stop error, got %q", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReflector_listAndWatch(t *testing.T) {
|
||||
createdFakes := make(chan *watch.FakeWatcher)
|
||||
|
||||
@@ -157,7 +225,7 @@ func TestReflector_listAndWatch(t *testing.T) {
|
||||
}
|
||||
s := NewFIFO(MetaNamespaceKeyFunc)
|
||||
r := NewReflector(lw, &api.Pod{}, s, 0)
|
||||
go r.listAndWatch()
|
||||
go r.listAndWatch(util.NeverStop)
|
||||
|
||||
ids := []string{"foo", "bar", "baz", "qux", "zoo"}
|
||||
var fw *watch.FakeWatcher
|
||||
@@ -274,6 +342,6 @@ func TestReflector_listAndWatchWithErrors(t *testing.T) {
|
||||
},
|
||||
}
|
||||
r := NewReflector(lw, &api.Pod{}, s, 0)
|
||||
r.listAndWatch()
|
||||
r.listAndWatch(util.NeverStop)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user