@@ -26,6 +26,9 @@ import (
2626
2727 v1 "k8s.io/api/core/v1"
2828 "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"
2932 "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
3033 "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
3134 "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask"
@@ -42,6 +45,17 @@ const (
4245var (
4346 containerRestartPolicyAlways = v1 .ContainerRestartPolicyAlways
4447
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+
4559 requirementsGuaranteed = & v1.ResourceRequirements {
4660 Limits : v1.ResourceList {
4761 v1 .ResourceCPU : resource .MustParse ("1000Mi" ),
@@ -131,6 +145,7 @@ type testStaticPolicy struct {
131145 topologyHint * topologymanager.TopologyHint
132146 expectedTopologyHints map [string ][]topologymanager.TopologyHint
133147 initContainersReusableMemory reusableMemory
148+ podLevelResourcesEnabled bool
134149}
135150
136151func initTests (t * testing.T , testCase * testStaticPolicy , hint * topologymanager.TopologyHint , initContainersReusableMemory reusableMemory ) (Policy , state.State , error ) {
@@ -2006,18 +2021,76 @@ func TestStaticPolicyAllocate(t *testing.T) {
20062021 topologyHint : & topologymanager.TopologyHint {NUMANodeAffinity : newNUMAAffinity (0 , 1 ), Preferred : true },
20072022 expectedError : fmt .Errorf ("[memorymanager] preferred hint violates NUMA node allocation" ),
20082023 },
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+ },
20092080 }
20102081
20112082 for _ , testCase := range testCases {
20122083 t .Run (testCase .description , func (t * testing.T ) {
2084+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , testCase .podLevelResourcesEnabled )
2085+
20132086 t .Logf ("TestStaticPolicyAllocate %s" , testCase .description )
20142087 p , s , err := initTests (t , & testCase , testCase .topologyHint , nil )
20152088 if err != nil {
20162089 t .Fatalf ("Unexpected error: %v" , err )
20172090 }
20182091
20192092 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 () ) {
20212094 t .Fatalf ("The actual error %v is different from the expected one %v" , err , testCase .expectedError )
20222095 }
20232096
@@ -3732,10 +3805,23 @@ func TestStaticPolicyGetTopologyHints(t *testing.T) {
37323805 },
37333806 },
37343807 },
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+ },
37353819 }
37363820
37373821 for _ , testCase := range testCases {
37383822 t .Run (testCase .description , func (t * testing.T ) {
3823+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , testCase .podLevelResourcesEnabled )
3824+
37393825 p , s , err := initTests (t , & testCase , nil , nil )
37403826 if err != nil {
37413827 t .Fatalf ("Unexpected error: %v" , err )
@@ -3749,6 +3835,39 @@ func TestStaticPolicyGetTopologyHints(t *testing.T) {
37493835 }
37503836}
37513837
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+
37523871func Test_getPodRequestedResources (t * testing.T ) {
37533872 testCases := []struct {
37543873 description string
0 commit comments