@@ -12,6 +12,7 @@ import (
1212 "github.com/Azure/azure-container-networking/npm/util"
1313 testutils "github.com/Azure/azure-container-networking/test/utils"
1414 "github.com/stretchr/testify/assert"
15+ "github.com/stretchr/testify/require"
1516 corev1 "k8s.io/api/core/v1"
1617 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1718 "k8s.io/apimachinery/pkg/runtime"
@@ -86,7 +87,7 @@ func (f *podFixture) newPodController(stopCh chan struct{}) {
8687 // f.kubeInformer.Start(stopCh)
8788}
8889
89- func createPod (name , ns , rv , podIP string , labels map [string ]string , isHostNewtwork bool , podPhase corev1.PodPhase ) * corev1.Pod {
90+ func createPod (name , ns , rv , podIP string , labels map [string ]string , isHostNetwork bool , podPhase corev1.PodPhase ) * corev1.Pod {
9091 return & corev1.Pod {
9192 ObjectMeta : metav1.ObjectMeta {
9293 Name : name ,
@@ -95,7 +96,7 @@ func createPod(name, ns, rv, podIP string, labels map[string]string, isHostNewtw
9596 ResourceVersion : rv ,
9697 },
9798 Spec : corev1.PodSpec {
98- HostNetwork : isHostNewtwork ,
99+ HostNetwork : isHostNetwork ,
99100 Containers : []corev1.Container {
100101 {
101102 Ports : []corev1.ContainerPort {
@@ -690,6 +691,88 @@ func TestHasValidPodIP(t *testing.T) {
690691 }
691692}
692693
694+ func TestIsCompletePod (t * testing.T ) {
695+ var zeroGracePeriod int64
696+ var defaultGracePeriod int64 = 30
697+
698+ type podState struct {
699+ phase corev1.PodPhase
700+ deletionTimestamp * metav1.Time
701+ deletionGracePeriodSeconds * int64
702+ }
703+
704+ tests := []struct {
705+ name string
706+ podState podState
707+ expectedCompletedPod bool
708+ }{
709+
710+ {
711+ name : "pod is in running status" ,
712+ podState : podState {
713+ phase : corev1 .PodRunning ,
714+ deletionTimestamp : nil ,
715+ deletionGracePeriodSeconds : nil ,
716+ },
717+ expectedCompletedPod : false ,
718+ },
719+ {
720+ name : "pod is in completely terminating states after graceful shutdown period" ,
721+ podState : podState {
722+ phase : corev1 .PodRunning ,
723+ deletionTimestamp : & metav1.Time {},
724+ deletionGracePeriodSeconds : & zeroGracePeriod ,
725+ },
726+ expectedCompletedPod : true ,
727+ },
728+ {
729+ name : "pod is in terminating states, but in graceful shutdown period" ,
730+ podState : podState {
731+ phase : corev1 .PodRunning ,
732+ deletionTimestamp : & metav1.Time {},
733+ deletionGracePeriodSeconds : & defaultGracePeriod ,
734+ },
735+ expectedCompletedPod : false ,
736+ },
737+ {
738+ name : "pod is in PodSucceeded status" ,
739+ podState : podState {
740+ phase : corev1 .PodSucceeded ,
741+ deletionTimestamp : nil ,
742+ deletionGracePeriodSeconds : nil ,
743+ },
744+ expectedCompletedPod : true ,
745+ },
746+ {
747+ name : "pod is in PodFailed status" ,
748+ podState : podState {
749+ phase : corev1 .PodSucceeded ,
750+ deletionTimestamp : nil ,
751+ deletionGracePeriodSeconds : nil ,
752+ },
753+ expectedCompletedPod : true ,
754+ },
755+ }
756+
757+ for _ , tt := range tests {
758+ tt := tt
759+ t .Run (tt .name , func (t * testing.T ) {
760+ t .Parallel ()
761+ corev1Pod := & corev1.Pod {
762+ ObjectMeta : metav1.ObjectMeta {
763+ DeletionTimestamp : tt .podState .deletionTimestamp ,
764+ DeletionGracePeriodSeconds : tt .podState .deletionGracePeriodSeconds ,
765+ },
766+ Status : corev1.PodStatus {
767+ Phase : tt .podState .phase ,
768+ },
769+ }
770+ isPodCompleted := isCompletePod (corev1Pod )
771+ require .Equal (t , tt .expectedCompletedPod , isPodCompleted )
772+ })
773+ }
774+ }
775+
693776// Extra unit test which is not quite related to PodController,
694777// but help to understand how workqueue works to make event handler logic lock-free.
695778// If the same key are queued into workqueue in multiple times,
@@ -721,3 +804,71 @@ func TestWorkQueue(t *testing.T) {
721804 }
722805 }
723806}
807+
808+ func TestNPMPodNoUpdate (t * testing.T ) {
809+ type podInfo struct {
810+ podName string
811+ ns string
812+ rv string
813+ podIP string
814+ labels map [string ]string
815+ isHostNetwork bool
816+ podPhase corev1.PodPhase
817+ }
818+
819+ labels := map [string ]string {
820+ "app" : "test-pod" ,
821+ }
822+
823+ tests := []struct {
824+ name string
825+ podInfo
826+ updatingNPMPod bool
827+ expectedNoUpdate bool
828+ }{
829+ {
830+ "Required update of NPMPod given Pod" ,
831+ podInfo {
832+ podName : "test-pod-1" ,
833+ ns : "test-namespace" ,
834+ rv : "0" ,
835+ podIP : "1.2.3.4" ,
836+ labels : labels ,
837+ isHostNetwork : NonHostNetwork ,
838+ podPhase : corev1 .PodRunning ,
839+ },
840+ false ,
841+ false ,
842+ },
843+ {
844+ "No required update of NPMPod given Pod" ,
845+ podInfo {
846+ podName : "test-pod-2" ,
847+ ns : "test-namespace" ,
848+ rv : "0" ,
849+ podIP : "1.2.3.4" ,
850+ labels : labels ,
851+ isHostNetwork : NonHostNetwork ,
852+ podPhase : corev1 .PodRunning ,
853+ },
854+ true ,
855+ true ,
856+ },
857+ }
858+
859+ for _ , tt := range tests {
860+ tt := tt
861+ t .Run (tt .name , func (t * testing.T ) {
862+ t .Parallel ()
863+ corev1Pod := createPod (tt .podName , tt .ns , tt .rv , tt .podIP , tt .labels , tt .isHostNetwork , tt .podPhase )
864+ npmPod := newNpmPod (corev1Pod )
865+ if tt .updatingNPMPod {
866+ npmPod .appendLabels (corev1Pod .Labels , AppendToExistingLabels )
867+ npmPod .updateNpmPodAttributes (corev1Pod )
868+ npmPod .appendContainerPorts (corev1Pod )
869+ }
870+ noUpdate := npmPod .noUpdate (corev1Pod )
871+ require .Equal (t , tt .expectedNoUpdate , noUpdate )
872+ })
873+ }
874+ }
0 commit comments