@@ -577,13 +577,13 @@ func TestApplyPodLimitRange(t *testing.T) {
577
577
{
578
578
ContainerName : "container1" ,
579
579
Target : apiv1.ResourceList {
580
- apiv1 .ResourceMemory : resource .MustParse ("2000000000000m " ),
580
+ apiv1 .ResourceMemory : resource .MustParse ("2000000000 " ),
581
581
},
582
582
},
583
583
{
584
584
ContainerName : "container2" ,
585
585
Target : apiv1.ResourceList {
586
- apiv1 .ResourceMemory : resource .MustParse ("2000000000000m " ),
586
+ apiv1 .ResourceMemory : resource .MustParse ("2000000000 " ),
587
587
},
588
588
},
589
589
},
@@ -644,13 +644,13 @@ func TestApplyPodLimitRange(t *testing.T) {
644
644
{
645
645
ContainerName : "container1" ,
646
646
Target : apiv1.ResourceList {
647
- apiv1 .ResourceMemory : resource .MustParse ("2000000000000m " ),
647
+ apiv1 .ResourceMemory : resource .MustParse ("2000000000 " ),
648
648
},
649
649
},
650
650
{
651
651
ContainerName : "container2" ,
652
652
Target : apiv1.ResourceList {
653
- apiv1 .ResourceMemory : resource .MustParse ("2000000000000m " ),
653
+ apiv1 .ResourceMemory : resource .MustParse ("2000000000 " ),
654
654
},
655
655
},
656
656
},
@@ -801,3 +801,121 @@ func TestApplyLimitRangeMinToRequest(t *testing.T) {
801
801
})
802
802
}
803
803
}
804
+
805
+ func TestCapPodMemoryWithUnderByteSplit (t * testing.T ) {
806
+ // It's important that recommendations are different so straightforwardly
807
+ // splitting Max between containers results in fractional bytes going to them.
808
+ // We want to ensure we'll round millibytes the right way (rounding down when
809
+ // caping to max, to stay below max, rounding up when caping to min).
810
+ recommendation := vpa_types.RecommendedPodResources {
811
+ ContainerRecommendations : []vpa_types.RecommendedContainerResources {
812
+ {
813
+ ContainerName : "container-1" ,
814
+ Target : apiv1.ResourceList {
815
+ apiv1 .ResourceMemory : resource .MustParse ("1Gi" ),
816
+ },
817
+ },
818
+ {
819
+ ContainerName : "container-2" ,
820
+ Target : apiv1.ResourceList {
821
+ apiv1 .ResourceMemory : resource .MustParse ("2Gi" ),
822
+ },
823
+ },
824
+ },
825
+ }
826
+ pod := apiv1.Pod {
827
+ Spec : apiv1.PodSpec {
828
+ Containers : []apiv1.Container {
829
+ {
830
+ Name : "container-1" ,
831
+ Resources : apiv1.ResourceRequirements {
832
+ Requests : apiv1.ResourceList {
833
+ apiv1 .ResourceMemory : resource .MustParse ("50M" ),
834
+ },
835
+ Limits : apiv1.ResourceList {
836
+ apiv1 .ResourceMemory : resource .MustParse ("50M" ),
837
+ },
838
+ },
839
+ },
840
+ {
841
+ Name : "container-2" ,
842
+ Resources : apiv1.ResourceRequirements {
843
+ Requests : apiv1.ResourceList {
844
+ apiv1 .ResourceMemory : resource .MustParse ("50M" ),
845
+ },
846
+ Limits : apiv1.ResourceList {
847
+ apiv1 .ResourceMemory : resource .MustParse ("50M" ),
848
+ },
849
+ },
850
+ },
851
+ },
852
+ },
853
+ }
854
+
855
+ tests := []struct {
856
+ name string
857
+ limitRange apiv1.LimitRangeItem
858
+ expectedRecommendation vpa_types.RecommendedPodResources
859
+ }{
860
+ {
861
+ name : "cap to max" ,
862
+ limitRange : apiv1.LimitRangeItem {
863
+ Type : apiv1 .LimitTypePod ,
864
+ Max : apiv1.ResourceList {
865
+ apiv1 .ResourceMemory : resource .MustParse ("1Gi" ),
866
+ },
867
+ },
868
+ expectedRecommendation : vpa_types.RecommendedPodResources {
869
+ ContainerRecommendations : []vpa_types.RecommendedContainerResources {
870
+ {
871
+ ContainerName : "container-1" ,
872
+ Target : apiv1.ResourceList {
873
+ apiv1 .ResourceMemory : * resource .NewQuantity (357913941 , resource .BinarySI ),
874
+ },
875
+ },
876
+ {
877
+ ContainerName : "container-2" ,
878
+ Target : apiv1.ResourceList {
879
+ apiv1 .ResourceMemory : * resource .NewQuantity (715827882 , resource .BinarySI ),
880
+ },
881
+ },
882
+ },
883
+ },
884
+ },
885
+ {
886
+ name : "cap to min" ,
887
+ limitRange : apiv1.LimitRangeItem {
888
+ Type : apiv1 .LimitTypePod ,
889
+ Min : apiv1.ResourceList {
890
+ apiv1 .ResourceMemory : resource .MustParse ("4Gi" ),
891
+ },
892
+ },
893
+ expectedRecommendation : vpa_types.RecommendedPodResources {
894
+ ContainerRecommendations : []vpa_types.RecommendedContainerResources {
895
+ {
896
+ ContainerName : "container-1" ,
897
+ Target : apiv1.ResourceList {
898
+ apiv1 .ResourceMemory : * resource .NewQuantity (1431655766 , resource .BinarySI ),
899
+ },
900
+ },
901
+ {
902
+ ContainerName : "container-2" ,
903
+ Target : apiv1.ResourceList {
904
+ apiv1 .ResourceMemory : * resource .NewQuantity (2863311531 , resource .BinarySI ),
905
+ },
906
+ },
907
+ },
908
+ },
909
+ },
910
+ }
911
+
912
+ for _ , tc := range tests {
913
+ t .Run (tc .name , func (t * testing.T ) {
914
+ calculator := fakeLimitRangeCalculator {podLimitRange : tc .limitRange }
915
+ processor := NewCappingRecommendationProcessor (& calculator )
916
+ processedRecommendation , _ , err := processor .Apply (& recommendation , nil , nil , & pod )
917
+ assert .NoError (t , err )
918
+ assert .Equal (t , tc .expectedRecommendation , * processedRecommendation )
919
+ })
920
+ }
921
+ }
0 commit comments