mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
client-go/cache: fix missing delete event on replace without knownObjects
This fixes an issue where a relist could result in a DELETED delta with an object wrapped in a DeletedFinalStateUnknown object; and then on the next relist, it would wrap that object inside another DeletedFinalStateUnknown, leaving the user with a "double" layer of DeletedFinalStateUnknown's. Signed-off-by: Odin Ugedal <ougedal@palantir.com> Signed-off-by: Odin Ugedal <odin@uged.al>
This commit is contained in:
parent
25d77218ac
commit
0bf0546d9f
@ -613,6 +613,11 @@ func (f *DeltaFIFO) Replace(list []interface{}, _ string) error {
|
||||
var deletedObj interface{}
|
||||
if n := oldItem.Newest(); n != nil {
|
||||
deletedObj = n.Object
|
||||
|
||||
// if the previous object is a DeletedFinalStateUnknown, we have to extract the actual Object
|
||||
if d, ok := deletedObj.(DeletedFinalStateUnknown); ok {
|
||||
deletedObj = d.Obj
|
||||
}
|
||||
}
|
||||
queuedDeletions++
|
||||
if err := f.queueActionLocked(Deleted, DeletedFinalStateUnknown{k, deletedObj}); err != nil {
|
||||
|
@ -121,6 +121,108 @@ func TestDeltaFIFO_replaceWithDeleteDeltaIn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFOWithoutKnownObjects_ReplaceMakesDeletionsForObjectsInQueue(t *testing.T) {
|
||||
obj := mkFifoObj("foo", 2)
|
||||
objV2 := mkFifoObj("foo", 3)
|
||||
table := []struct {
|
||||
name string
|
||||
operations func(f *DeltaFIFO)
|
||||
expectedDeltas Deltas
|
||||
}{
|
||||
{
|
||||
name: "Added object should be deleted on Replace",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.Add(obj)
|
||||
f.Replace([]interface{}{}, "0")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Deleted, DeletedFinalStateUnknown{Key: "foo", Obj: obj}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Replaced object should have only a single Delete",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.emitDeltaTypeReplaced = true
|
||||
f.Add(obj)
|
||||
f.Replace([]interface{}{obj}, "0")
|
||||
f.Replace([]interface{}{}, "0")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Replaced, obj},
|
||||
{Deleted, DeletedFinalStateUnknown{Key: "foo", Obj: obj}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Deleted object should have only a single Delete",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.Add(obj)
|
||||
f.Delete(obj)
|
||||
f.Replace([]interface{}{}, "0")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Deleted, obj},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Synced objects should have a single delete",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.Add(obj)
|
||||
f.Replace([]interface{}{obj}, "0")
|
||||
f.Replace([]interface{}{obj}, "0")
|
||||
f.Replace([]interface{}{}, "0")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Sync, obj},
|
||||
{Sync, obj},
|
||||
{Deleted, DeletedFinalStateUnknown{Key: "foo", Obj: obj}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Added objects should have a single delete on multiple Replaces",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.Add(obj)
|
||||
f.Replace([]interface{}{}, "0")
|
||||
f.Replace([]interface{}{}, "1")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Deleted, DeletedFinalStateUnknown{Key: "foo", Obj: obj}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Added and deleted and added object should be deleted",
|
||||
operations: func(f *DeltaFIFO) {
|
||||
f.Add(obj)
|
||||
f.Delete(obj)
|
||||
f.Add(objV2)
|
||||
f.Replace([]interface{}{}, "0")
|
||||
},
|
||||
expectedDeltas: Deltas{
|
||||
{Added, obj},
|
||||
{Deleted, obj},
|
||||
{Added, objV2},
|
||||
{Deleted, DeletedFinalStateUnknown{Key: "foo", Obj: objV2}},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range table {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f := NewDeltaFIFOWithOptions(DeltaFIFOOptions{
|
||||
KeyFunction: testFifoObjectKeyFunc,
|
||||
})
|
||||
tt.operations(f)
|
||||
actualDeltas := Pop(f)
|
||||
if !reflect.DeepEqual(tt.expectedDeltas, actualDeltas) {
|
||||
t.Errorf("expected %#v, got %#v", tt.expectedDeltas, actualDeltas)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeltaFIFOWithKnownObjects_ReplaceMakesDeletionsForObjectsInQueue(t *testing.T) {
|
||||
obj := mkFifoObj("foo", 2)
|
||||
|
Loading…
Reference in New Issue
Block a user