@@ -13,6 +13,7 @@ import (
1313 dpmocks "github.com/Azure/azure-container-networking/npm/pkg/dataplane/mocks"
1414 gomock "github.com/golang/mock/gomock"
1515 "github.com/stretchr/testify/assert"
16+ "github.com/stretchr/testify/require"
1617 corev1 "k8s.io/api/core/v1"
1718 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1819 "k8s.io/apimachinery/pkg/runtime"
@@ -85,7 +86,7 @@ func (f *podFixture) newPodController(_ chan struct{}) {
8586 // f.kubeInformer.Start(stopCh)
8687}
8788
88- func createPod (name , ns , rv , podIP string , labels map [string ]string , isHostNewtwork bool , podPhase corev1.PodPhase ) * corev1.Pod {
89+ func createPod (name , ns , rv , podIP string , labels map [string ]string , isHostNetwork bool , podPhase corev1.PodPhase ) * corev1.Pod {
8990 return & corev1.Pod {
9091 ObjectMeta : metav1.ObjectMeta {
9192 Name : name ,
@@ -94,7 +95,7 @@ func createPod(name, ns, rv, podIP string, labels map[string]string, isHostNewtw
9495 ResourceVersion : rv ,
9596 },
9697 Spec : corev1.PodSpec {
97- HostNetwork : isHostNewtwork ,
98+ HostNetwork : isHostNetwork ,
9899 Containers : []corev1.Container {
99100 {
100101 Ports : []corev1.ContainerPort {
@@ -734,6 +735,88 @@ func TestHasValidPodIP(t *testing.T) {
734735 }
735736}
736737
738+ func TestIsCompletePod (t * testing.T ) {
739+ var zeroGracePeriod int64
740+ var defaultGracePeriod int64 = 30
741+
742+ type podState struct {
743+ phase corev1.PodPhase
744+ deletionTimestamp * metav1.Time
745+ deletionGracePeriodSeconds * int64
746+ }
747+
748+ tests := []struct {
749+ name string
750+ podState podState
751+ expectedCompletedPod bool
752+ }{
753+
754+ {
755+ name : "pod is in running status" ,
756+ podState : podState {
757+ phase : corev1 .PodRunning ,
758+ deletionTimestamp : nil ,
759+ deletionGracePeriodSeconds : nil ,
760+ },
761+ expectedCompletedPod : false ,
762+ },
763+ {
764+ name : "pod is in completely terminating states after graceful shutdown period" ,
765+ podState : podState {
766+ phase : corev1 .PodRunning ,
767+ deletionTimestamp : & metav1.Time {},
768+ deletionGracePeriodSeconds : & zeroGracePeriod ,
769+ },
770+ expectedCompletedPod : true ,
771+ },
772+ {
773+ name : "pod is in terminating states, but in graceful shutdown period" ,
774+ podState : podState {
775+ phase : corev1 .PodRunning ,
776+ deletionTimestamp : & metav1.Time {},
777+ deletionGracePeriodSeconds : & defaultGracePeriod ,
778+ },
779+ expectedCompletedPod : false ,
780+ },
781+ {
782+ name : "pod is in PodSucceeded status" ,
783+ podState : podState {
784+ phase : corev1 .PodSucceeded ,
785+ deletionTimestamp : nil ,
786+ deletionGracePeriodSeconds : nil ,
787+ },
788+ expectedCompletedPod : true ,
789+ },
790+ {
791+ name : "pod is in PodFailed status" ,
792+ podState : podState {
793+ phase : corev1 .PodSucceeded ,
794+ deletionTimestamp : nil ,
795+ deletionGracePeriodSeconds : nil ,
796+ },
797+ expectedCompletedPod : true ,
798+ },
799+ }
800+
801+ for _ , tt := range tests {
802+ tt := tt
803+ t .Run (tt .name , func (t * testing.T ) {
804+ t .Parallel ()
805+ corev1Pod := & corev1.Pod {
806+ ObjectMeta : metav1.ObjectMeta {
807+ DeletionTimestamp : tt .podState .deletionTimestamp ,
808+ DeletionGracePeriodSeconds : tt .podState .deletionGracePeriodSeconds ,
809+ },
810+ Status : corev1.PodStatus {
811+ Phase : tt .podState .phase ,
812+ },
813+ }
814+ isPodCompleted := isCompletePod (corev1Pod )
815+ require .Equal (t , tt .expectedCompletedPod , isPodCompleted )
816+ })
817+ }
818+ }
819+
737820// Extra unit test which is not quite related to PodController,
738821// but help to understand how workqueue works to make event handler logic lock-free.
739822// If the same key are queued into workqueue in multiple times,
@@ -768,3 +851,71 @@ func TestWorkQueue(t *testing.T) {
768851 }
769852 }
770853}
854+
855+ func TestNPMPodNoUpdate (t * testing.T ) {
856+ type podInfo struct {
857+ podName string
858+ ns string
859+ rv string
860+ podIP string
861+ labels map [string ]string
862+ isHostNetwork bool
863+ podPhase corev1.PodPhase
864+ }
865+
866+ labels := map [string ]string {
867+ "app" : "test-pod" ,
868+ }
869+
870+ tests := []struct {
871+ name string
872+ podInfo
873+ updatingNPMPod bool
874+ expectedNoUpdate bool
875+ }{
876+ {
877+ "Required update of NPMPod given Pod" ,
878+ podInfo {
879+ podName : "test-pod-1" ,
880+ ns : "test-namespace" ,
881+ rv : "0" ,
882+ podIP : "1.2.3.4" ,
883+ labels : labels ,
884+ isHostNetwork : NonHostNetwork ,
885+ podPhase : corev1 .PodRunning ,
886+ },
887+ false ,
888+ false ,
889+ },
890+ {
891+ "No required update of NPMPod given Pod" ,
892+ podInfo {
893+ podName : "test-pod-2" ,
894+ ns : "test-namespace" ,
895+ rv : "0" ,
896+ podIP : "1.2.3.4" ,
897+ labels : labels ,
898+ isHostNetwork : NonHostNetwork ,
899+ podPhase : corev1 .PodRunning ,
900+ },
901+ true ,
902+ true ,
903+ },
904+ }
905+
906+ for _ , tt := range tests {
907+ tt := tt
908+ t .Run (tt .name , func (t * testing.T ) {
909+ t .Parallel ()
910+ corev1Pod := createPod (tt .podName , tt .ns , tt .rv , tt .podIP , tt .labels , tt .isHostNetwork , tt .podPhase )
911+ npmPod := newNpmPod (corev1Pod )
912+ if tt .updatingNPMPod {
913+ npmPod .appendLabels (corev1Pod .Labels , appendToExistingLabels )
914+ npmPod .updateNpmPodAttributes (corev1Pod )
915+ npmPod .appendContainerPorts (corev1Pod )
916+ }
917+ noUpdate := npmPod .noUpdate (corev1Pod )
918+ require .Equal (t , tt .expectedNoUpdate , noUpdate )
919+ })
920+ }
921+ }
0 commit comments