@@ -28,6 +28,7 @@ import (
28
28
29
29
"github.com/google/go-cmp/cmp"
30
30
"github.com/stretchr/testify/assert"
31
+ "github.com/stretchr/testify/mock"
31
32
"github.com/stretchr/testify/require"
32
33
33
34
"k8s.io/apimachinery/pkg/types"
@@ -82,9 +83,10 @@ func getEventsFromChannel(ch <-chan *PodLifecycleEvent) []*PodLifecycleEvent {
82
83
return events
83
84
}
84
85
85
- func createTestContainer (ID string , state kubecontainer.State ) * kubecontainer.Container {
86
+ func createTestContainer (id string , state kubecontainer.State ) * kubecontainer.Container {
86
87
return & kubecontainer.Container {
87
- ID : kubecontainer.ContainerID {Type : testContainerRuntimeType , ID : ID },
88
+ ID : kubecontainer.ContainerID {Type : testContainerRuntimeType , ID : id },
89
+ Name : id ,
88
90
State : state ,
89
91
}
90
92
}
@@ -317,14 +319,14 @@ func testReportMissingPods(t *testing.T, numRelists int) {
317
319
}
318
320
319
321
func newTestGenericPLEGWithRuntimeMock (runtimeMock kubecontainer.Runtime ) * GenericPLEG {
320
- pleg := & GenericPLEG {
321
- relistDuration : & RelistDuration { RelistPeriod : time . Hour , RelistThreshold : 2 * time . Hour },
322
- runtime : runtimeMock ,
323
- eventChannel : make (chan * PodLifecycleEvent , 1000 ),
324
- podRecords : make ( podRecords ) ,
325
- cache : kubecontainer .NewCache (),
326
- clock : clock .RealClock {},
327
- }
322
+ pleg := NewGenericPLEG (
323
+ klog. Logger { },
324
+ runtimeMock ,
325
+ make (chan * PodLifecycleEvent , 1000 ),
326
+ & RelistDuration { RelistPeriod : time . Hour , RelistThreshold : 2 * time . Hour } ,
327
+ kubecontainer .NewCache (),
328
+ clock.RealClock {},
329
+ ).( * GenericPLEG )
328
330
return pleg
329
331
}
330
332
@@ -738,42 +740,46 @@ kubelet_running_pods 2
738
740
}
739
741
740
742
func TestWatchConditions (t * testing.T ) {
741
- pods := []* containertest.FakePod {{
742
- Pod : & kubecontainer.Pod {
743
- Name : "running-pod" ,
744
- ID : "running" ,
745
- Sandboxes : []* kubecontainer.Container {
746
- createTestContainer ("s" , kubecontainer .ContainerStateRunning ),
747
- },
748
- Containers : []* kubecontainer.Container {
749
- createTestContainer ("c" , kubecontainer .ContainerStateRunning ),
750
- },
743
+ pods := []* kubecontainer.Pod {{
744
+ Name : "running-pod" ,
745
+ ID : "running" ,
746
+ Sandboxes : []* kubecontainer.Container {
747
+ createTestContainer ("s" , kubecontainer .ContainerStateRunning ),
748
+ },
749
+ Containers : []* kubecontainer.Container {
750
+ createTestContainer ("c" , kubecontainer .ContainerStateRunning ),
751
751
},
752
752
}, {
753
- Pod : & kubecontainer.Pod {
754
- Name : "terminating-pod" ,
755
- ID : "terminating" ,
756
- Sandboxes : []* kubecontainer.Container {
757
- createTestContainer ("s" , kubecontainer .ContainerStateExited ),
758
- },
753
+ Name : "running-pod-2" ,
754
+ ID : "running-2" ,
755
+ Sandboxes : []* kubecontainer.Container {
756
+ createTestContainer ("s" , kubecontainer .ContainerStateRunning ),
757
+ },
758
+ Containers : []* kubecontainer.Container {
759
+ createTestContainer ("c-exited" , kubecontainer .ContainerStateExited ),
760
+ createTestContainer ("c-running" , kubecontainer .ContainerStateRunning ),
759
761
},
760
762
}, {
761
- Pod : & kubecontainer.Pod {
762
- Name : "reinspect-pod" ,
763
- ID : "reinspect" ,
764
- Sandboxes : []* kubecontainer.Container {
765
- createTestContainer ("s" , kubecontainer .ContainerStateRunning ),
766
- },
763
+ Name : "terminating-pod" ,
764
+ ID : "terminating" ,
765
+ Sandboxes : []* kubecontainer.Container {
766
+ createTestContainer ("s" , kubecontainer .ContainerStateExited ),
767
+ },
768
+ }, {
769
+ Name : "reinspect-pod" ,
770
+ ID : "reinspect" ,
771
+ Sandboxes : []* kubecontainer.Container {
772
+ createTestContainer ("s" , kubecontainer .ContainerStateRunning ),
767
773
},
768
774
}}
769
775
initialPods := pods
770
- initialPods = append (initialPods , & containertest. FakePod { Pod : & kubecontainer.Pod {
776
+ initialPods = append (initialPods , & kubecontainer.Pod {
771
777
Name : "terminated-pod" ,
772
778
ID : "terminated" ,
773
779
Sandboxes : []* kubecontainer.Container {
774
780
createTestContainer ("s" , kubecontainer .ContainerStateExited ),
775
781
},
776
- }} )
782
+ })
777
783
778
784
alwaysComplete := func (_ * kubecontainer.PodStatus ) bool {
779
785
return true
@@ -790,13 +796,32 @@ func TestWatchConditions(t *testing.T) {
790
796
return true
791
797
}
792
798
799
+ // resettingCond decrements the version before it completes.
800
+ var resettingCond = func (_ * kubecontainer.PodStatus ) bool {
801
+ versioned := pleg .watchConditions ["running" ]["resetting" ]
802
+ versioned .version = 0
803
+ pleg .watchConditions ["running" ]["resetting" ] = versioned
804
+ return true
805
+ }
806
+
807
+ // makeContainerCond returns a RunningContainerWatchCondition that asserts the expected container status
808
+ makeContainerCond := func (expectedContainerName string , complete bool ) WatchCondition {
809
+ return RunningContainerWatchCondition (expectedContainerName , func (status * kubecontainer.Status ) bool {
810
+ if status .Name != expectedContainerName {
811
+ panic (fmt .Sprintf ("unexpected container name: got %q, want %q" , status .Name , expectedContainerName ))
812
+ }
813
+ return complete
814
+ })
815
+ }
816
+
793
817
testCases := []struct {
794
- name string
795
- podUID types.UID
796
- watchConditions map [string ]WatchCondition
797
- expectEvaluated bool // Whether the watch conditions should be evaluated
798
- expectRemoved bool // Whether podUID should be present in the watch conditions map
799
- expectWatchConditions map [string ]versionedWatchCondition // The expected watch conditions for the podUIDa (only key & version checked)
818
+ name string
819
+ podUID types.UID
820
+ watchConditions map [string ]WatchCondition
821
+ incrementInitialVersion bool // Whether to call SetPodWatchCondition multiple times to increment the version
822
+ expectEvaluated bool // Whether the watch conditions should be evaluated
823
+ expectRemoved bool // Whether podUID should be present in the watch conditions map
824
+ expectWatchConditions map [string ]versionedWatchCondition // The expected watch conditions for the podUID (only key & version checked)
800
825
}{{
801
826
name : "no watch conditions" ,
802
827
podUID : "running" ,
@@ -813,6 +838,31 @@ func TestWatchConditions(t *testing.T) {
813
838
"watching" : {version : 0 },
814
839
"updating" : {version : 1 },
815
840
},
841
+ }, {
842
+ name : "conditions with incremented versions" ,
843
+ podUID : "running" ,
844
+ incrementInitialVersion : true ,
845
+ watchConditions : map [string ]WatchCondition {
846
+ "completing" : alwaysComplete ,
847
+ "watching" : neverComplete ,
848
+ "updating" : updatingCond ,
849
+ },
850
+ expectEvaluated : true ,
851
+ expectWatchConditions : map [string ]versionedWatchCondition {
852
+ "watching" : {version : 1 },
853
+ "updating" : {version : 2 },
854
+ },
855
+ }, {
856
+ name : "completed watch condition with older version" ,
857
+ podUID : "running" ,
858
+ incrementInitialVersion : true ,
859
+ watchConditions : map [string ]WatchCondition {
860
+ "resetting" : resettingCond ,
861
+ },
862
+ expectEvaluated : true ,
863
+ expectWatchConditions : map [string ]versionedWatchCondition {
864
+ "resetting" : {version : 0 },
865
+ },
816
866
}, {
817
867
name : "non-existent pod" ,
818
868
podUID : "non-existent" ,
@@ -839,22 +889,75 @@ func TestWatchConditions(t *testing.T) {
839
889
expectWatchConditions : map [string ]versionedWatchCondition {
840
890
"watching" : {version : 0 },
841
891
},
892
+ }, {
893
+ name : "single container conditions" ,
894
+ podUID : "running" ,
895
+ watchConditions : map [string ]WatchCondition {
896
+ "completing" : makeContainerCond ("c" , true ),
897
+ "watching" : makeContainerCond ("c" , false ),
898
+ },
899
+ expectEvaluated : true ,
900
+ expectWatchConditions : map [string ]versionedWatchCondition {
901
+ "watching" : {version : 0 },
902
+ },
903
+ }, {
904
+ name : "multi-container conditions" ,
905
+ podUID : "running-2" ,
906
+ watchConditions : map [string ]WatchCondition {
907
+ "completing:exited" : makeContainerCond ("c-exited" , true ),
908
+ "watching:exited" : makeContainerCond ("c-exited" , false ),
909
+ "completing:running" : makeContainerCond ("c-running" , true ),
910
+ "watching:running" : makeContainerCond ("c-running" , false ),
911
+ "completing:dne" : makeContainerCond ("c-dne" , true ),
912
+ "watching:dne" : makeContainerCond ("c-dne" , false ),
913
+ },
914
+ expectEvaluated : true ,
915
+ expectWatchConditions : map [string ]versionedWatchCondition {
916
+ "watching:running" : {version : 0 },
917
+ },
842
918
}}
843
919
844
920
for _ , test := range testCases {
845
921
t .Run (test .name , func (t * testing.T ) {
846
- testPleg := newTestGenericPLEG ()
847
- pleg = testPleg .pleg
848
- runtime := testPleg .runtime
849
- runtime .AllPodList = initialPods
850
- pleg .Relist () // Setup initial pod records.
922
+ runtimeMock := containertest .NewMockRuntime (t )
923
+ pleg = newTestGenericPLEGWithRuntimeMock (runtimeMock )
924
+
925
+ // Mock pod statuses
926
+ for _ , pod := range initialPods {
927
+ podStatus := & kubecontainer.PodStatus {
928
+ ID : pod .ID ,
929
+ Name : pod .Name ,
930
+ Namespace : pod .Namespace ,
931
+ }
932
+ for _ , c := range pod .Containers {
933
+ podStatus .ContainerStatuses = append (podStatus .ContainerStatuses , & kubecontainer.Status {
934
+ ID : c .ID ,
935
+ Name : c .Name ,
936
+ State : c .State ,
937
+ })
938
+ }
939
+ runtimeMock .EXPECT ().
940
+ GetPodStatus (mock .Anything , pod .ID , pod .Name , pod .Namespace ).
941
+ Return (podStatus , nil ).Maybe ()
942
+ }
851
943
852
- runtime .AllPodList = pods // Doesn't have "terminated" pod.
944
+ // Setup initial pod records.
945
+ runtimeMock .EXPECT ().GetPods (mock .Anything , true ).Return (initialPods , nil ).Once ()
946
+ pleg .Relist ()
853
947
pleg .podsToReinspect ["reinspect" ] = nil
854
948
949
+ // Remove "terminated" pod.
950
+ runtimeMock .EXPECT ().GetPods (mock .Anything , true ).Return (pods , nil ).Once ()
951
+
855
952
var evaluatedConditions []string
856
953
for key , condition := range test .watchConditions {
857
954
wrappedCondition := func (status * kubecontainer.PodStatus ) bool {
955
+ defer func () {
956
+ if r := recover (); r != nil {
957
+ require .Fail (t , "condition error" , r )
958
+ }
959
+ }()
960
+ assert .Equal (t , test .podUID , status .ID , "podUID" )
858
961
if ! test .expectEvaluated {
859
962
assert .Fail (t , "conditions should not be evaluated" )
860
963
} else {
@@ -863,6 +966,10 @@ func TestWatchConditions(t *testing.T) {
863
966
return condition (status )
864
967
}
865
968
pleg .SetPodWatchCondition (test .podUID , key , wrappedCondition )
969
+ if test .incrementInitialVersion {
970
+ // Set the watch condition a second time to increment the version.
971
+ pleg .SetPodWatchCondition (test .podUID , key , wrappedCondition )
972
+ }
866
973
}
867
974
pleg .Relist ()
868
975
0 commit comments