@@ -26,6 +26,9 @@ import (
26
26
27
27
v1 "k8s.io/api/core/v1"
28
28
"k8s.io/apimachinery/pkg/api/resource"
29
+ utilfeature "k8s.io/apiserver/pkg/util/feature"
30
+ featuregatetesting "k8s.io/component-base/featuregate/testing"
31
+ "k8s.io/kubernetes/pkg/features"
29
32
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
30
33
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
31
34
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
@@ -42,6 +45,17 @@ const (
42
45
var (
43
46
containerRestartPolicyAlways = v1 .ContainerRestartPolicyAlways
44
47
48
+ podLevelRequirementsGuaranteed = & v1.ResourceRequirements {
49
+ Limits : v1.ResourceList {
50
+ v1 .ResourceCPU : resource .MustParse ("1000Mi" ),
51
+ v1 .ResourceMemory : resource .MustParse ("1Gi" ),
52
+ },
53
+ Requests : v1.ResourceList {
54
+ v1 .ResourceCPU : resource .MustParse ("1000Mi" ),
55
+ v1 .ResourceMemory : resource .MustParse ("1Gi" ),
56
+ },
57
+ }
58
+
45
59
requirementsGuaranteed = & v1.ResourceRequirements {
46
60
Limits : v1.ResourceList {
47
61
v1 .ResourceCPU : resource .MustParse ("1000Mi" ),
@@ -131,6 +145,7 @@ type testStaticPolicy struct {
131
145
topologyHint * topologymanager.TopologyHint
132
146
expectedTopologyHints map [string ][]topologymanager.TopologyHint
133
147
initContainersReusableMemory reusableMemory
148
+ podLevelResourcesEnabled bool
134
149
}
135
150
136
151
func initTests (t * testing.T , testCase * testStaticPolicy , hint * topologymanager.TopologyHint , initContainersReusableMemory reusableMemory ) (Policy , state.State , error ) {
@@ -2006,18 +2021,76 @@ func TestStaticPolicyAllocate(t *testing.T) {
2006
2021
topologyHint : & topologymanager.TopologyHint {NUMANodeAffinity : newNUMAAffinity (0 , 1 ), Preferred : true },
2007
2022
expectedError : fmt .Errorf ("[memorymanager] preferred hint violates NUMA node allocation" ),
2008
2023
},
2024
+ {
2025
+ description : "should do nothing for guaranteed pod with pod level resources" ,
2026
+ expectedAssignments : state.ContainerMemoryAssignments {},
2027
+ machineState : state.NUMANodeMap {
2028
+ 0 : & state.NUMANodeState {
2029
+ MemoryMap : map [v1.ResourceName ]* state.MemoryTable {
2030
+ v1 .ResourceMemory : {
2031
+ Allocatable : 1536 * mb ,
2032
+ Free : 1536 * mb ,
2033
+ Reserved : 0 ,
2034
+ SystemReserved : 512 * mb ,
2035
+ TotalMemSize : 2 * gb ,
2036
+ },
2037
+ hugepages1Gi : {
2038
+ Allocatable : gb ,
2039
+ Free : gb ,
2040
+ Reserved : 0 ,
2041
+ SystemReserved : 0 ,
2042
+ TotalMemSize : gb ,
2043
+ },
2044
+ },
2045
+ Cells : []int {},
2046
+ },
2047
+ },
2048
+ expectedMachineState : state.NUMANodeMap {
2049
+ 0 : & state.NUMANodeState {
2050
+ MemoryMap : map [v1.ResourceName ]* state.MemoryTable {
2051
+ v1 .ResourceMemory : {
2052
+ Allocatable : 1536 * mb ,
2053
+ Free : 1536 * mb ,
2054
+ Reserved : 0 ,
2055
+ SystemReserved : 512 * mb ,
2056
+ TotalMemSize : 2 * gb ,
2057
+ },
2058
+ hugepages1Gi : {
2059
+ Allocatable : gb ,
2060
+ Free : gb ,
2061
+ Reserved : 0 ,
2062
+ SystemReserved : 0 ,
2063
+ TotalMemSize : gb ,
2064
+ },
2065
+ },
2066
+ Cells : []int {},
2067
+ },
2068
+ },
2069
+ systemReserved : systemReservedMemory {
2070
+ 0 : map [v1.ResourceName ]uint64 {
2071
+ v1 .ResourceMemory : 512 * mb ,
2072
+ },
2073
+ },
2074
+ pod : getPodWithPodLevelResources ("pod1" , podLevelRequirementsGuaranteed , "container1" , requirementsGuaranteed ),
2075
+ expectedTopologyHints : nil ,
2076
+ topologyHint : & topologymanager.TopologyHint {},
2077
+ expectedError : nil ,
2078
+ podLevelResourcesEnabled : true ,
2079
+ },
2009
2080
}
2010
2081
2011
2082
for _ , testCase := range testCases {
2012
2083
t .Run (testCase .description , func (t * testing.T ) {
2084
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , testCase .podLevelResourcesEnabled )
2085
+
2013
2086
t .Logf ("TestStaticPolicyAllocate %s" , testCase .description )
2014
2087
p , s , err := initTests (t , & testCase , testCase .topologyHint , nil )
2015
2088
if err != nil {
2016
2089
t .Fatalf ("Unexpected error: %v" , err )
2017
2090
}
2018
2091
2019
2092
err = p .Allocate (tCtx , s , testCase .pod , & testCase .pod .Spec .Containers [0 ])
2020
- if ! reflect . DeepEqual (err , testCase .expectedError ) {
2093
+ if ( err == nil ) != ( testCase . expectedError == nil ) || (err != nil && testCase .expectedError != nil && err . Error () != testCase . expectedError . Error () ) {
2021
2094
t .Fatalf ("The actual error %v is different from the expected one %v" , err , testCase .expectedError )
2022
2095
}
2023
2096
@@ -3732,10 +3805,23 @@ func TestStaticPolicyGetTopologyHints(t *testing.T) {
3732
3805
},
3733
3806
},
3734
3807
},
3808
+ {
3809
+ description : "should not provide topology hints for guaranteed pod with pod level resources" ,
3810
+ pod : getPodWithPodLevelResources ("pod1" , podLevelRequirementsGuaranteed , "container1" , requirementsGuaranteed ),
3811
+ systemReserved : systemReservedMemory {
3812
+ 0 : map [v1.ResourceName ]uint64 {
3813
+ v1 .ResourceMemory : 1024 * mb ,
3814
+ },
3815
+ },
3816
+ expectedTopologyHints : nil ,
3817
+ podLevelResourcesEnabled : true ,
3818
+ },
3735
3819
}
3736
3820
3737
3821
for _ , testCase := range testCases {
3738
3822
t .Run (testCase .description , func (t * testing.T ) {
3823
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , testCase .podLevelResourcesEnabled )
3824
+
3739
3825
p , s , err := initTests (t , & testCase , nil , nil )
3740
3826
if err != nil {
3741
3827
t .Fatalf ("Unexpected error: %v" , err )
@@ -3749,6 +3835,39 @@ func TestStaticPolicyGetTopologyHints(t *testing.T) {
3749
3835
}
3750
3836
}
3751
3837
3838
+ func TestStaticPolicyGetPodTopologyHints (t * testing.T ) {
3839
+ _ , tCtx := ktesting .NewTestContext (t )
3840
+ testCases := []testStaticPolicy {
3841
+ {
3842
+ description : "should not provide pod topology hints for guaranteed pod with pod level resources" ,
3843
+ pod : getPodWithPodLevelResources ("pod1" , podLevelRequirementsGuaranteed , "container1" , requirementsGuaranteed ),
3844
+ systemReserved : systemReservedMemory {
3845
+ 0 : map [v1.ResourceName ]uint64 {
3846
+ v1 .ResourceMemory : 1024 * mb ,
3847
+ },
3848
+ },
3849
+ expectedTopologyHints : nil ,
3850
+ podLevelResourcesEnabled : true ,
3851
+ },
3852
+ }
3853
+
3854
+ for _ , testCase := range testCases {
3855
+ t .Run (testCase .description , func (t * testing.T ) {
3856
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , testCase .podLevelResourcesEnabled )
3857
+
3858
+ p , s , err := initTests (t , & testCase , nil , nil )
3859
+ if err != nil {
3860
+ t .Fatalf ("Unexpected error: %v" , err )
3861
+ }
3862
+
3863
+ topologyHints := p .GetPodTopologyHints (tCtx , s , testCase .pod )
3864
+ if ! reflect .DeepEqual (topologyHints , testCase .expectedTopologyHints ) {
3865
+ t .Fatalf ("The actual topology hints: '%+v' are different from the expected one: '%+v'" , topologyHints , testCase .expectedTopologyHints )
3866
+ }
3867
+ })
3868
+ }
3869
+ }
3870
+
3752
3871
func Test_getPodRequestedResources (t * testing.T ) {
3753
3872
testCases := []struct {
3754
3873
description string
0 commit comments