@@ -31,13 +31,16 @@ import (
3131 "k8s.io/apimachinery/pkg/runtime"
3232 "k8s.io/apimachinery/pkg/runtime/schema"
3333 "k8s.io/apimachinery/pkg/util/sets"
34+ utilfeature "k8s.io/apiserver/pkg/util/feature"
3435 "k8s.io/client-go/informers"
3536 "k8s.io/client-go/kubernetes/fake"
3637 core "k8s.io/client-go/testing"
3738 "k8s.io/client-go/tools/cache"
39+ featuregatetesting "k8s.io/component-base/featuregate/testing"
3840 "k8s.io/kubernetes/pkg/api/legacyscheme"
3941 "k8s.io/kubernetes/pkg/controller"
4042 metricsclient "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
43+ "k8s.io/kubernetes/pkg/features"
4144 cmapi "k8s.io/metrics/pkg/apis/custom_metrics/v1beta2"
4245 emapi "k8s.io/metrics/pkg/apis/external_metrics/v1beta1"
4346 metricsapi "k8s.io/metrics/pkg/apis/metrics/v1beta1"
@@ -2225,17 +2228,18 @@ func TestGroupPods(t *testing.T) {
22252228 }
22262229}
22272230
2228- func TestCalculatePodRequests (t * testing.T ) {
2231+ func TestCalculateRequests (t * testing.T ) {
22292232 containerRestartPolicyAlways := v1 .ContainerRestartPolicyAlways
22302233 testPod := "test-pod"
22312234
22322235 tests := []struct {
2233- name string
2234- pods []* v1.Pod
2235- container string
2236- resource v1.ResourceName
2237- expectedRequests map [string ]int64
2238- expectedError error
2236+ name string
2237+ pods []* v1.Pod
2238+ container string
2239+ resource v1.ResourceName
2240+ enablePodLevelResources bool
2241+ expectedRequests map [string ]int64
2242+ expectedError error
22392243 }{
22402244 {
22412245 name : "void" ,
@@ -2246,7 +2250,7 @@ func TestCalculatePodRequests(t *testing.T) {
22462250 expectedError : nil ,
22472251 },
22482252 {
2249- name : "pod with regular containers " ,
2253+ name : "Sum container requests if pod-level feature is disabled " ,
22502254 pods : []* v1.Pod {{
22512255 ObjectMeta : metav1.ObjectMeta {
22522256 Name : testPod ,
@@ -2265,7 +2269,8 @@ func TestCalculatePodRequests(t *testing.T) {
22652269 expectedError : nil ,
22662270 },
22672271 {
2268- name : "calculate requests with special container" ,
2272+ name : "Pod-level resources are enabled, but not set: fallback to sum container requests" ,
2273+ enablePodLevelResources : true ,
22692274 pods : []* v1.Pod {{
22702275 ObjectMeta : metav1.ObjectMeta {
22712276 Name : testPod ,
@@ -2278,13 +2283,37 @@ func TestCalculatePodRequests(t *testing.T) {
22782283 },
22792284 },
22802285 }},
2281- container : "container1 " ,
2286+ container : "" ,
22822287 resource : v1 .ResourceCPU ,
2283- expectedRequests : map [string ]int64 {testPod : 100 },
2288+ expectedRequests : map [string ]int64 {testPod : 150 },
2289+ expectedError : nil ,
2290+ },
2291+ {
2292+ name : "Pod-level resources override container requests when feature enabled and pod resources specified" ,
2293+ enablePodLevelResources : true ,
2294+ pods : []* v1.Pod {{
2295+
2296+ ObjectMeta : metav1.ObjectMeta {
2297+ Name : testPod ,
2298+ Namespace : testNamespace ,
2299+ },
2300+ Spec : v1.PodSpec {
2301+ Resources : & v1.ResourceRequirements {
2302+ Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (800 , resource .DecimalSI )},
2303+ },
2304+ Containers : []v1.Container {
2305+ {Name : "container1" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (100 , resource .DecimalSI )}}},
2306+ {Name : "container2" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (50 , resource .DecimalSI )}}},
2307+ },
2308+ },
2309+ }},
2310+ container : "" ,
2311+ resource : v1 .ResourceCPU ,
2312+ expectedRequests : map [string ]int64 {testPod : 800 },
22842313 expectedError : nil ,
22852314 },
22862315 {
2287- name : "container missing requests" ,
2316+ name : "Fail if at least one of the containers is missing requests and pod-level feature/requests are not set " ,
22882317 pods : []* v1.Pod {{
22892318 ObjectMeta : metav1.ObjectMeta {
22902319 Name : testPod ,
@@ -2293,6 +2322,7 @@ func TestCalculatePodRequests(t *testing.T) {
22932322 Spec : v1.PodSpec {
22942323 Containers : []v1.Container {
22952324 {Name : "container1" },
2325+ {Name : "container2" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (50 , resource .DecimalSI )}}},
22962326 },
22972327 },
22982328 }},
@@ -2301,6 +2331,71 @@ func TestCalculatePodRequests(t *testing.T) {
23012331 expectedRequests : nil ,
23022332 expectedError : fmt .Errorf ("missing request for %s in container %s of Pod %s" , v1 .ResourceCPU , "container1" , testPod ),
23032333 },
2334+ {
2335+ name : "Pod-level resources override missing container requests when feature enabled and pod resources specified" ,
2336+ enablePodLevelResources : true ,
2337+ pods : []* v1.Pod {{
2338+ ObjectMeta : metav1.ObjectMeta {
2339+ Name : testPod ,
2340+ Namespace : testNamespace ,
2341+ },
2342+ Spec : v1.PodSpec {
2343+ Resources : & v1.ResourceRequirements {
2344+ Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (800 , resource .DecimalSI )},
2345+ },
2346+ Containers : []v1.Container {
2347+ {Name : "container1" },
2348+ {Name : "container2" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (50 , resource .DecimalSI )}}},
2349+ },
2350+ },
2351+ }},
2352+ container : "" ,
2353+ resource : v1 .ResourceCPU ,
2354+ expectedRequests : map [string ]int64 {testPod : 800 },
2355+ expectedError : nil ,
2356+ },
2357+ {
2358+ name : "Container: if a container name is specified, calculate requests only for that container" ,
2359+ pods : []* v1.Pod {{
2360+ ObjectMeta : metav1.ObjectMeta {
2361+ Name : testPod ,
2362+ Namespace : testNamespace ,
2363+ },
2364+ Spec : v1.PodSpec {
2365+ Containers : []v1.Container {
2366+ {Name : "container1" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (100 , resource .DecimalSI )}}},
2367+ {Name : "container2" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (50 , resource .DecimalSI )}}},
2368+ },
2369+ },
2370+ }},
2371+ container : "container1" ,
2372+ resource : v1 .ResourceCPU ,
2373+ expectedRequests : map [string ]int64 {testPod : 100 },
2374+ expectedError : nil ,
2375+ },
2376+ {
2377+ name : "Container: if a container name is specified, calculate requests only for that container and ignore pod-level requests" ,
2378+ enablePodLevelResources : true ,
2379+ pods : []* v1.Pod {{
2380+ ObjectMeta : metav1.ObjectMeta {
2381+ Name : testPod ,
2382+ Namespace : testNamespace ,
2383+ },
2384+ Spec : v1.PodSpec {
2385+ Resources : & v1.ResourceRequirements {
2386+ Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (800 , resource .DecimalSI )},
2387+ },
2388+ Containers : []v1.Container {
2389+ {Name : "container1" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (100 , resource .DecimalSI )}}},
2390+ {Name : "container2" , Resources : v1.ResourceRequirements {Requests : v1.ResourceList {v1 .ResourceCPU : * resource .NewMilliQuantity (50 , resource .DecimalSI )}}},
2391+ },
2392+ },
2393+ }},
2394+ container : "container1" ,
2395+ resource : v1 .ResourceCPU ,
2396+ expectedRequests : map [string ]int64 {testPod : 100 },
2397+ expectedError : nil ,
2398+ },
23042399 {
23052400 name : "pod with restartable init containers" ,
23062401 pods : []* v1.Pod {{
@@ -2327,7 +2422,9 @@ func TestCalculatePodRequests(t *testing.T) {
23272422
23282423 for _ , tc := range tests {
23292424 t .Run (tc .name , func (t * testing.T ) {
2330- requests , err := calculatePodRequests (tc .pods , tc .container , tc .resource )
2425+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .PodLevelResources , tc .enablePodLevelResources )
2426+
2427+ requests , err := calculateRequests (tc .pods , tc .container , tc .resource )
23312428 assert .Equal (t , tc .expectedRequests , requests , "requests should be as expected" )
23322429 assert .Equal (t , tc .expectedError , err , "error should be as expected" )
23332430 })
0 commit comments