mirror of
https://github.com/kubernetes/client-go.git
synced 2025-06-26 15:12:06 +00:00
Fix stale object causing a panic on DELETE event
Kubernetes-commit: 1f4f78ac414b7a1666e908670c5e447015bdc6b9
This commit is contained in:
parent
224c1c6ff4
commit
a35bc8fe7a
@ -127,7 +127,7 @@ func NewIndexerInformerWatcher(lw cache.ListerWatcher, objType runtime.Object) (
|
||||
// We have no means of passing the additional information down using
|
||||
// watch API based on watch.Event but the caller can filter such
|
||||
// objects by checking if metadata.deletionTimestamp is set
|
||||
obj = staleObj
|
||||
obj = staleObj.Obj
|
||||
}
|
||||
|
||||
e.push(watch.Event{
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
@ -276,3 +277,88 @@ func TestNewInformerWatcher(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TestInformerWatcherDeletedFinalStateUnknown tests the code path when `DeleteFunc`
|
||||
// in `NewIndexerInformerWatcher` receives a `cache.DeletedFinalStateUnknown`
|
||||
// object from the underlying `DeltaFIFO`. The triggering condition is described
|
||||
// at https://github.com/kubernetes/kubernetes/blob/dc39ab2417bfddcec37be4011131c59921fdbe98/staging/src/k8s.io/client-go/tools/cache/delta_fifo.go#L736-L739.
|
||||
//
|
||||
// Code from @liggitt
|
||||
func TestInformerWatcherDeletedFinalStateUnknown(t *testing.T) {
|
||||
listCalls := 0
|
||||
watchCalls := 0
|
||||
lw := &cache.ListWatch{
|
||||
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
|
||||
retval := &corev1.SecretList{}
|
||||
if listCalls == 0 {
|
||||
// Return a list with items in it
|
||||
retval.ResourceVersion = "1"
|
||||
retval.Items = []corev1.Secret{{ObjectMeta: metav1.ObjectMeta{Name: "secret1", Namespace: "ns1", ResourceVersion: "123"}}}
|
||||
} else {
|
||||
// Return empty lists after the first call
|
||||
retval.ResourceVersion = "2"
|
||||
}
|
||||
listCalls++
|
||||
return retval, nil
|
||||
},
|
||||
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
|
||||
w := watch.NewFake()
|
||||
if options.ResourceVersion == "1" {
|
||||
go func() {
|
||||
// Close with a "Gone" error when trying to start a watch from the first list
|
||||
w.Error(&apierrors.NewGone("gone").ErrStatus)
|
||||
w.Stop()
|
||||
}()
|
||||
}
|
||||
watchCalls++
|
||||
return w, nil
|
||||
},
|
||||
}
|
||||
_, _, w, done := NewIndexerInformerWatcher(lw, &corev1.Secret{})
|
||||
|
||||
// Expect secret add
|
||||
select {
|
||||
case event, ok := <-w.ResultChan():
|
||||
if !ok {
|
||||
t.Fatal("unexpected close")
|
||||
}
|
||||
if event.Type != watch.Added {
|
||||
t.Fatalf("expected Added event, got %#v", event)
|
||||
}
|
||||
if event.Object.(*corev1.Secret).ResourceVersion != "123" {
|
||||
t.Fatalf("expected added Secret with rv=123, got %#v", event.Object)
|
||||
}
|
||||
case <-time.After(time.Second * 10):
|
||||
t.Fatal("timeout")
|
||||
}
|
||||
|
||||
// Expect secret delete because the relist was missing the secret
|
||||
select {
|
||||
case event, ok := <-w.ResultChan():
|
||||
if !ok {
|
||||
t.Fatal("unexpected close")
|
||||
}
|
||||
if event.Type != watch.Deleted {
|
||||
t.Fatalf("expected Deleted event, got %#v", event)
|
||||
}
|
||||
if event.Object.(*corev1.Secret).ResourceVersion != "123" {
|
||||
t.Fatalf("expected deleted Secret with rv=123, got %#v", event.Object)
|
||||
}
|
||||
case <-time.After(time.Second * 10):
|
||||
t.Fatal("timeout")
|
||||
}
|
||||
|
||||
w.Stop()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Second * 10):
|
||||
t.Fatal("timeout")
|
||||
}
|
||||
|
||||
if listCalls < 2 {
|
||||
t.Fatalf("expected at least 2 list calls, got %d", listCalls)
|
||||
}
|
||||
if watchCalls < 1 {
|
||||
t.Fatalf("expected at least 1 watch call, got %d", watchCalls)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user