@@ -29,12 +29,13 @@ import (
29
29
"github.com/google/go-cmp/cmp"
30
30
"github.com/google/go-cmp/cmp/cmpopts"
31
31
"github.com/stretchr/testify/assert"
32
+ "github.com/stretchr/testify/require"
33
+
32
34
v1 "k8s.io/api/core/v1"
33
35
"k8s.io/apimachinery/pkg/api/meta"
34
36
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35
37
"k8s.io/apimachinery/pkg/util/sets"
36
38
"k8s.io/apimachinery/pkg/util/wait"
37
- fcache "k8s.io/client-go/tools/cache/testing"
38
39
testingclock "k8s.io/utils/clock/testing"
39
40
)
40
41
@@ -123,7 +124,7 @@ func isRegistered(i SharedInformer, h ResourceEventHandlerRegistration) bool {
123
124
func TestIndexer (t * testing.T ) {
124
125
assert := assert .New (t )
125
126
// source simulates an apiserver object endpoint.
126
- source := fcache . NewFakeControllerSource ( )
127
+ source := newFakeControllerSource ( t )
127
128
pod1 := & v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" , Labels : map [string ]string {"a" : "a-val" , "b" : "b-val1" }}}
128
129
pod2 := & v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod2" , Labels : map [string ]string {"b" : "b-val2" }}}
129
130
pod3 := & v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod3" , Labels : map [string ]string {"a" : "a-val2" }}}
@@ -197,7 +198,7 @@ func TestIndexer(t *testing.T) {
197
198
198
199
func TestListenerResyncPeriods (t * testing.T ) {
199
200
// source simulates an apiserver object endpoint.
200
- source := fcache . NewFakeControllerSource ( )
201
+ source := newFakeControllerSource ( t )
201
202
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
202
203
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod2" }})
203
204
@@ -284,7 +285,7 @@ func TestListenerResyncPeriods(t *testing.T) {
284
285
285
286
func TestResyncCheckPeriod (t * testing.T ) {
286
287
// source simulates an apiserver object endpoint.
287
- source := fcache . NewFakeControllerSource ( )
288
+ source := newFakeControllerSource ( t )
288
289
289
290
// create the shared informer and resync every 12 hours
290
291
informer := NewSharedInformer (source , & v1.Pod {}, 12 * time .Hour ).(* sharedIndexInformer )
@@ -356,7 +357,7 @@ func TestResyncCheckPeriod(t *testing.T) {
356
357
357
358
// verify that https://github.com/kubernetes/kubernetes/issues/59822 is fixed
358
359
func TestSharedInformerInitializationRace (t * testing.T ) {
359
- source := fcache . NewFakeControllerSource ( )
360
+ source := newFakeControllerSource ( t )
360
361
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
361
362
listener := newTestListener ("raceListener" , 0 )
362
363
@@ -371,7 +372,7 @@ func TestSharedInformerInitializationRace(t *testing.T) {
371
372
// resync and no resync see the expected state.
372
373
func TestSharedInformerWatchDisruption (t * testing.T ) {
373
374
// source simulates an apiserver object endpoint.
374
- source := fcache . NewFakeControllerSource ( )
375
+ source := newFakeControllerSource ( t )
375
376
376
377
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" , UID : "pod1" , ResourceVersion : "1" }})
377
378
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod2" , UID : "pod2" , ResourceVersion : "2" }})
@@ -446,7 +447,7 @@ func TestSharedInformerWatchDisruption(t *testing.T) {
446
447
}
447
448
448
449
func TestSharedInformerErrorHandling (t * testing.T ) {
449
- source := fcache . NewFakeControllerSource ( )
450
+ source := newFakeControllerSource ( t )
450
451
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
451
452
source .ListError = fmt .Errorf ("Access Denied" )
452
453
@@ -474,7 +475,7 @@ func TestSharedInformerErrorHandling(t *testing.T) {
474
475
// TestSharedInformerStartRace is a regression test to ensure there is no race between
475
476
// Run and SetWatchErrorHandler, and Run and SetTransform.
476
477
func TestSharedInformerStartRace (t * testing.T ) {
477
- source := fcache . NewFakeControllerSource ( )
478
+ source := newFakeControllerSource ( t )
478
479
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
479
480
stop := make (chan struct {})
480
481
go func () {
@@ -500,7 +501,7 @@ func TestSharedInformerStartRace(t *testing.T) {
500
501
501
502
func TestSharedInformerTransformer (t * testing.T ) {
502
503
// source simulates an apiserver object endpoint.
503
- source := fcache . NewFakeControllerSource ( )
504
+ source := newFakeControllerSource ( t )
504
505
505
506
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" , UID : "pod1" , ResourceVersion : "1" }})
506
507
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod2" , UID : "pod2" , ResourceVersion : "2" }})
@@ -531,7 +532,7 @@ func TestSharedInformerTransformer(t *testing.T) {
531
532
}
532
533
533
534
func TestSharedInformerRemoveHandler (t * testing.T ) {
534
- source := fcache . NewFakeControllerSource ( )
535
+ source := newFakeControllerSource ( t )
535
536
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
536
537
537
538
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second )
@@ -569,12 +570,12 @@ func TestSharedInformerRemoveHandler(t *testing.T) {
569
570
}
570
571
571
572
func TestSharedInformerRemoveForeignHandler (t * testing.T ) {
572
- source := fcache . NewFakeControllerSource ( )
573
+ source := newFakeControllerSource ( t )
573
574
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
574
575
575
576
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
576
577
577
- source2 := fcache . NewFakeControllerSource ( )
578
+ source2 := newFakeControllerSource ( t )
578
579
source2 .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
579
580
580
581
informer2 := NewSharedInformer (source2 , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -651,7 +652,7 @@ func TestSharedInformerRemoveForeignHandler(t *testing.T) {
651
652
}
652
653
653
654
func TestSharedInformerMultipleRegistration (t * testing.T ) {
654
- source := fcache . NewFakeControllerSource ( )
655
+ source := newFakeControllerSource ( t )
655
656
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
656
657
657
658
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -719,7 +720,7 @@ func TestSharedInformerMultipleRegistration(t *testing.T) {
719
720
}
720
721
721
722
func TestRemovingRemovedSharedInformer (t * testing.T ) {
722
- source := fcache . NewFakeControllerSource ( )
723
+ source := newFakeControllerSource ( t )
723
724
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
724
725
725
726
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -751,7 +752,7 @@ func TestRemovingRemovedSharedInformer(t *testing.T) {
751
752
// listeners without tripping it up. There are not really many assertions in this
752
753
// test. Meant to be run with -race to find race conditions
753
754
func TestSharedInformerHandlerAbuse (t * testing.T ) {
754
- source := fcache . NewFakeControllerSource ( )
755
+ source := newFakeControllerSource ( t )
755
756
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
756
757
757
758
ctx , cancel := context .WithCancel (context .Background ())
@@ -865,7 +866,7 @@ func TestSharedInformerHandlerAbuse(t *testing.T) {
865
866
}
866
867
867
868
func TestStateSharedInformer (t * testing.T ) {
868
- source := fcache . NewFakeControllerSource ( )
869
+ source := newFakeControllerSource ( t )
869
870
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
870
871
871
872
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -914,7 +915,7 @@ func TestStateSharedInformer(t *testing.T) {
914
915
}
915
916
916
917
func TestAddOnStoppedSharedInformer (t * testing.T ) {
917
- source := fcache . NewFakeControllerSource ( )
918
+ source := newFakeControllerSource ( t )
918
919
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
919
920
920
921
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -947,7 +948,7 @@ func TestAddOnStoppedSharedInformer(t *testing.T) {
947
948
}
948
949
949
950
func TestRemoveOnStoppedSharedInformer (t * testing.T ) {
950
- source := fcache . NewFakeControllerSource ( )
951
+ source := newFakeControllerSource ( t )
951
952
source .Add (& v1.Pod {ObjectMeta : metav1.ObjectMeta {Name : "pod1" }})
952
953
953
954
informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second ).(* sharedIndexInformer )
@@ -976,7 +977,7 @@ func TestRemoveOnStoppedSharedInformer(t *testing.T) {
976
977
977
978
func TestRemoveWhileActive (t * testing.T ) {
978
979
// source simulates an apiserver object endpoint.
979
- source := fcache . NewFakeControllerSource ( )
980
+ source := newFakeControllerSource ( t )
980
981
981
982
// create the shared informer and resync every 12 hours
982
983
informer := NewSharedInformer (source , & v1.Pod {}, 0 ).(* sharedIndexInformer )
@@ -1012,7 +1013,7 @@ func TestRemoveWhileActive(t *testing.T) {
1012
1013
1013
1014
func TestAddWhileActive (t * testing.T ) {
1014
1015
// source simulates an apiserver object endpoint.
1015
- source := fcache . NewFakeControllerSource ( )
1016
+ source := newFakeControllerSource ( t )
1016
1017
1017
1018
// create the shared informer and resync every 12 hours
1018
1019
informer := NewSharedInformer (source , & v1.Pod {}, 0 ).(* sharedIndexInformer )
@@ -1072,3 +1073,52 @@ func TestAddWhileActive(t *testing.T) {
1072
1073
return
1073
1074
}
1074
1075
}
1076
+
1077
+ // TestShutdown depends on goleak.VerifyTestMain in main_test.go to verify that
1078
+ // all goroutines really have stopped in the different scenarios.
1079
+ func TestShutdown (t * testing.T ) {
1080
+ t .Run ("no-context" , func (t * testing.T ) {
1081
+ source := newFakeControllerSource (t )
1082
+ stop := make (chan struct {})
1083
+ defer close (stop )
1084
+
1085
+ informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second )
1086
+ handler , err := informer .AddEventHandler (ResourceEventHandlerFuncs {
1087
+ AddFunc : func (_ any ) {},
1088
+ })
1089
+ require .NoError (t , err )
1090
+ defer func () {
1091
+ assert .NoError (t , informer .RemoveEventHandler (handler ))
1092
+ }()
1093
+ go informer .Run (stop )
1094
+ require .Eventually (t , informer .HasSynced , time .Minute , time .Millisecond , "informer has synced" )
1095
+ })
1096
+
1097
+ t .Run ("no-context-later" , func (t * testing.T ) {
1098
+ source := newFakeControllerSource (t )
1099
+ stop := make (chan struct {})
1100
+ defer close (stop )
1101
+
1102
+ informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second )
1103
+ go informer .Run (stop )
1104
+ require .Eventually (t , informer .HasSynced , time .Minute , time .Millisecond , "informer has synced" )
1105
+
1106
+ handler , err := informer .AddEventHandler (ResourceEventHandlerFuncs {
1107
+ AddFunc : func (_ any ) {},
1108
+ })
1109
+ require .NoError (t , err )
1110
+ assert .NoError (t , informer .RemoveEventHandler (handler ))
1111
+ })
1112
+
1113
+ t .Run ("no-run" , func (t * testing.T ) {
1114
+ source := newFakeControllerSource (t )
1115
+ informer := NewSharedInformer (source , & v1.Pod {}, 1 * time .Second )
1116
+ _ , err := informer .AddEventHandler (ResourceEventHandlerFuncs {
1117
+ AddFunc : func (_ any ) {},
1118
+ })
1119
+ require .NoError (t , err )
1120
+
1121
+ // At this point, neither informer nor handler have any goroutines running
1122
+ // and it doesn't matter that nothing gets stopped or removed.
1123
+ })
1124
+ }
0 commit comments