mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 18:28:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			864 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			864 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2015 The Kubernetes Authors.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package qos
 | |
| 
 | |
| import (
 | |
| 	"strconv"
 | |
| 	"testing"
 | |
| 
 | |
| 	v1 "k8s.io/api/core/v1"
 | |
| 	"k8s.io/apimachinery/pkg/api/resource"
 | |
| 	"k8s.io/kubernetes/pkg/apis/scheduling"
 | |
| 
 | |
| 	utilfeature "k8s.io/apiserver/pkg/util/feature"
 | |
| 	featuregatetesting "k8s.io/component-base/featuregate/testing"
 | |
| 	"k8s.io/kubernetes/pkg/features"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	standardMemoryAmount = 8000000000
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	cpuLimit = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "cpu-limit",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	memoryLimitCPURequest = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "memory-limit-cpu-request",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceCPU): resource.MustParse("0"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	zeroMemoryLimit = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "zero-memory-limit",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse("0"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	noRequestLimit = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "no-request-limit",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	equalRequestLimitCPUMemory = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "equal-request-limit-cpu-memory",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
 | |
| 							v1.ResourceName(v1.ResourceCPU):    resource.MustParse("5m"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceCPU):    resource.MustParse("5m"),
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	cpuUnlimitedMemoryLimitedWithRequests = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "cpu-unlimited-memory-limited-with-requests",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse(strconv.FormatInt(standardMemoryAmount/2, 10)),
 | |
| 							v1.ResourceName(v1.ResourceCPU):    resource.MustParse("5m"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse("10G"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	requestNoLimit = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "request-no-limit",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): resource.MustParse(strconv.FormatInt(standardMemoryAmount-1, 10)),
 | |
| 							v1.ResourceName(v1.ResourceCPU):    resource.MustParse("5m"),
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	systemCritical = scheduling.SystemCriticalPriority
 | |
| 
 | |
| 	clusterCritical = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			PriorityClassName: scheduling.SystemClusterCritical,
 | |
| 			Priority:          &systemCritical,
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "cluster-critical",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	systemNodeCritical = scheduling.SystemCriticalPriority + 1000
 | |
| 
 | |
| 	nodeCritical = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			PriorityClassName: scheduling.SystemNodeCritical,
 | |
| 			Priority:          &systemNodeCritical,
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "node-critical",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 	sampleDefaultMemRequest    = resource.MustParse(strconv.FormatInt(standardMemoryAmount/8, 10))
 | |
| 	sampleDefaultMemLimit      = resource.MustParse(strconv.FormatInt(1000+(standardMemoryAmount/8), 10))
 | |
| 	sampleDefaultPodMemRequest = resource.MustParse(strconv.FormatInt(standardMemoryAmount/4, 10))
 | |
| 	sampleDefaultPodMemLimit   = resource.MustParse(strconv.FormatInt(1000+(standardMemoryAmount/4), 10))
 | |
| 
 | |
| 	sampleContainer = v1.Container{
 | |
| 		Name: "main-1",
 | |
| 		Resources: v1.ResourceRequirements{
 | |
| 			Requests: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemRequest,
 | |
| 			},
 | |
| 			Limits: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstableUniqueContainerPod = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-unique-container",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	sampleInitContainer = v1.Container{
 | |
| 		Name: "init-container",
 | |
| 		Resources: v1.ResourceRequirements{
 | |
| 			Requests: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemRequest,
 | |
| 			},
 | |
| 			Limits: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 	restartPolicyAlways    = v1.ContainerRestartPolicyAlways
 | |
| 	sampleSidecarContainer = v1.Container{
 | |
| 		Name:          "sidecar-container",
 | |
| 		RestartPolicy: &restartPolicyAlways,
 | |
| 		Resources: v1.ResourceRequirements{
 | |
| 			Requests: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemRequest,
 | |
| 			},
 | |
| 			Limits: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	sampleSmallSidecarContainer = v1.Container{
 | |
| 		Name:          "sidecar-small-container",
 | |
| 		RestartPolicy: &restartPolicyAlways,
 | |
| 		Resources: v1.ResourceRequirements{
 | |
| 			Requests: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): resource.MustParse(strconv.FormatInt(standardMemoryAmount/20, 10)),
 | |
| 			},
 | |
| 			Limits: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	sampleBigSidecarContainer = v1.Container{
 | |
| 		Name:          "sidecar-big-container",
 | |
| 		RestartPolicy: &restartPolicyAlways,
 | |
| 		Resources: v1.ResourceRequirements{
 | |
| 			Requests: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): resource.MustParse(strconv.FormatInt(standardMemoryAmount/2, 10)),
 | |
| 			},
 | |
| 			Limits: v1.ResourceList{
 | |
| 				v1.ResourceName(v1.ResourceMemory): sampleDefaultMemLimit,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstableMixedUniqueMainContainerPod = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			InitContainers: []v1.Container{
 | |
| 				sampleInitContainer,
 | |
| 			}, Containers: []v1.Container{
 | |
| 				sampleContainer,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstableMixedMultiContainerSameRequestPod = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			InitContainers: []v1.Container{
 | |
| 				sampleInitContainer, sampleSidecarContainer,
 | |
| 			}, Containers: []v1.Container{
 | |
| 				sampleContainer,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstableMixedMultiContainerSmallSidecarPod = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			InitContainers: []v1.Container{
 | |
| 				sampleInitContainer, sampleSmallSidecarContainer,
 | |
| 			}, Containers: []v1.Container{
 | |
| 				sampleContainer,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstableMixedMultiContainerBigSidecarContainerPod = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			InitContainers: []v1.Container{
 | |
| 				sampleInitContainer, sampleBigSidecarContainer,
 | |
| 			}, Containers: []v1.Container{
 | |
| 				sampleContainer,
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	// Pod definitions with their resource specifications are defined in this section.
 | |
| 	// TODO(ndixita): cleanup the tests to create a method that generates pod
 | |
| 	// definitions based on input resource parameters, replacing the current
 | |
| 	// approach of individual pod variables.
 | |
| 	guaranteedPodResourcesNoContainerResources = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "no-request-limit-1",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 				{
 | |
| 					Name:      "no-request-limit-2",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	guaranteedPodResourcesEqualContainerRequests = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "guaranteed-container-1",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 				{
 | |
| 					Name: "guaranteed-container-2",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	guaranteedPodResourcesUnequalContainerRequests = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-container",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("3m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 				{
 | |
| 					Name:      "best-effort-container",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesNoContainerResources = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "no-request-limit-1",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 				{
 | |
| 					Name:      "no-request-limit-2",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesEqualContainerRequests = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "guaranteed-container-1",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 				{
 | |
| 					Name: "guaranteed-container-2",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesUnequalContainerRequests = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-container",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("3m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 				{
 | |
| 					Name:      "best-effort-container",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesNoContainerResourcesWithSidecar = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name:      "no-request-limit",
 | |
| 					Resources: v1.ResourceRequirements{},
 | |
| 				},
 | |
| 			},
 | |
| 			InitContainers: []v1.Container{
 | |
| 				{
 | |
| 					Name:          "no-request-limit-sidecar",
 | |
| 					Resources:     v1.ResourceRequirements{},
 | |
| 					RestartPolicy: &restartPolicyAlways,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesEqualContainerRequestsWithSidecar = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemRequest,
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-container",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			InitContainers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-sidecar",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemRequest,
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 					RestartPolicy: &restartPolicyAlways,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	burstablePodResourcesUnequalContainerRequestsWithSidecar = v1.Pod{
 | |
| 		Spec: v1.PodSpec{
 | |
| 			Resources: &v1.ResourceRequirements{
 | |
| 				Requests: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: resource.MustParse("2000000000"),
 | |
| 				},
 | |
| 				Limits: v1.ResourceList{
 | |
| 					v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 					v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 				},
 | |
| 			},
 | |
| 			Containers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-container-1",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: resource.MustParse("1000000000"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 				{
 | |
| 					Name: "burstable-container-2",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: resource.MustParse("500000000"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 				},
 | |
| 			},
 | |
| 			InitContainers: []v1.Container{
 | |
| 				{
 | |
| 					Name: "burstable-sidecar",
 | |
| 					Resources: v1.ResourceRequirements{
 | |
| 						Requests: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: resource.MustParse("200000000"),
 | |
| 						},
 | |
| 						Limits: v1.ResourceList{
 | |
| 							v1.ResourceCPU:    resource.MustParse("5m"),
 | |
| 							v1.ResourceMemory: sampleDefaultPodMemLimit,
 | |
| 						},
 | |
| 					},
 | |
| 					RestartPolicy: &restartPolicyAlways,
 | |
| 				},
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| )
 | |
| 
 | |
| type lowHighOOMScoreAdjTest struct {
 | |
| 	lowOOMScoreAdj  int
 | |
| 	highOOMScoreAdj int
 | |
| }
 | |
| type oomTest struct {
 | |
| 	pod                             *v1.Pod
 | |
| 	memoryCapacity                  int64
 | |
| 	lowHighOOMScoreAdj              map[string]lowHighOOMScoreAdjTest // [container-name] : min and max oom_score_adj score the container should be assigned.
 | |
| 	podLevelResourcesFeatureEnabled bool
 | |
| }
 | |
| 
 | |
| func TestGetContainerOOMScoreAdjust(t *testing.T) {
 | |
| 	oomTests := map[string]oomTest{
 | |
| 		"cpu-limit": {
 | |
| 			pod:            &cpuLimit,
 | |
| 			memoryCapacity: 4000000000,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"cpu-limit": {lowOOMScoreAdj: 999, highOOMScoreAdj: 999},
 | |
| 			},
 | |
| 		},
 | |
| 		"memory-limit-cpu-request": {
 | |
| 			pod:            &memoryLimitCPURequest,
 | |
| 			memoryCapacity: 8000000000,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"memory-limit-cpu-request": {lowOOMScoreAdj: 999, highOOMScoreAdj: 999},
 | |
| 			},
 | |
| 		},
 | |
| 		"zero-memory-limit": {
 | |
| 			pod:            &zeroMemoryLimit,
 | |
| 			memoryCapacity: 7230457451,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"zero-memory-limit": {lowOOMScoreAdj: 1000, highOOMScoreAdj: 1000},
 | |
| 			},
 | |
| 		},
 | |
| 		"no-request-limit": {
 | |
| 			pod:            &noRequestLimit,
 | |
| 			memoryCapacity: 4000000000,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"no-request-limit": {lowOOMScoreAdj: 1000, highOOMScoreAdj: 1000},
 | |
| 			},
 | |
| 		},
 | |
| 		"equal-request-limit-cpu-memory": {
 | |
| 			pod:            &equalRequestLimitCPUMemory,
 | |
| 			memoryCapacity: 123456789,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"equal-request-limit-cpu-memory": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 			},
 | |
| 		},
 | |
| 		"cpu-unlimited-memory-limited-with-requests": {
 | |
| 			pod:            &cpuUnlimitedMemoryLimitedWithRequests,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"cpu-unlimited-memory-limited-with-requests": {lowOOMScoreAdj: 495, highOOMScoreAdj: 505},
 | |
| 			},
 | |
| 		},
 | |
| 		"request-no-limit": {
 | |
| 			pod:            &requestNoLimit,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"request-no-limit": {lowOOMScoreAdj: 3, highOOMScoreAdj: 3},
 | |
| 			},
 | |
| 		},
 | |
| 		"cluster-critical": {
 | |
| 			pod:            &clusterCritical,
 | |
| 			memoryCapacity: 4000000000,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"cluster-critical": {lowOOMScoreAdj: 1000, highOOMScoreAdj: 1000},
 | |
| 			},
 | |
| 		},
 | |
| 		"node-critical": {
 | |
| 			pod:            &nodeCritical,
 | |
| 			memoryCapacity: 4000000000,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"node-critical": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 			},
 | |
| 		},
 | |
| 		"burstable-unique-container-pod": {
 | |
| 			pod:            &burstableUniqueContainerPod,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"burstable-unique-container": {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 			},
 | |
| 		},
 | |
| 		"burstable-mixed-unique-main-container-pod": {
 | |
| 			pod:            &burstableMixedUniqueMainContainerPod,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"init-container": {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 				"main-1":         {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 			},
 | |
| 		},
 | |
| 		"burstable-mixed-multi-container-small-sidecar-pod": {
 | |
| 			pod:            &burstableMixedMultiContainerSmallSidecarPod,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"init-container":          {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 				"sidecar-small-container": {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 				"main-1":                  {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 			},
 | |
| 		},
 | |
| 		"burstable-mixed-multi-container-sample-request-pod": {
 | |
| 			pod:            &burstableMixedMultiContainerSameRequestPod,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"init-container":    {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 				"sidecar-container": {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 				"main-1":            {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 			},
 | |
| 		},
 | |
| 		"burstable-mixed-multi-container-big-sidecar-container-pod": {
 | |
| 			pod:            &burstableMixedMultiContainerBigSidecarContainerPod,
 | |
| 			memoryCapacity: standardMemoryAmount,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"init-container":        {lowOOMScoreAdj: 875, highOOMScoreAdj: 880},
 | |
| 				"sidecar-big-container": {lowOOMScoreAdj: 500, highOOMScoreAdj: 500},
 | |
| 				"main-1":                {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 			},
 | |
| 		},
 | |
| 		"guaranteed-pod-resources-no-container-resources": {
 | |
| 			pod: &guaranteedPodResourcesNoContainerResources,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"no-request-limit-1": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 				"no-request-limit-2": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"guaranteed-pod-resources-equal-container-resources": {
 | |
| 			pod: &guaranteedPodResourcesEqualContainerRequests,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"guaranteed-container-1": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 				"guaranteed-container-2": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"guaranteed-pod-resources-unequal-container-requests": {
 | |
| 			pod: &guaranteedPodResourcesUnequalContainerRequests,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"burstable-container":   {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 				"best-effort-container": {lowOOMScoreAdj: -997, highOOMScoreAdj: -997},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-no-container-resources": {
 | |
| 			pod: &burstablePodResourcesNoContainerResources,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"no-request-limit-1": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 				"no-request-limit-2": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-equal-container-requests": {
 | |
| 			pod: &burstablePodResourcesEqualContainerRequests,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"guaranteed-container-1": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 				"guaranteed-container-2": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-unequal-container-requests": {
 | |
| 			pod: &burstablePodResourcesUnequalContainerRequests,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"burstable-container":   {lowOOMScoreAdj: 625, highOOMScoreAdj: 625},
 | |
| 				"best-effort-container": {lowOOMScoreAdj: 875, highOOMScoreAdj: 875},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-no-container-resources-with-sidecar": {
 | |
| 			pod: &burstablePodResourcesNoContainerResourcesWithSidecar,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"no-request-limit":         {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 				"no-request-limit-sidecar": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-equal-container-requests-with-sidecar": {
 | |
| 			pod: &burstablePodResourcesEqualContainerRequestsWithSidecar,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"burstable-container": {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 				"burstable-sidecar":   {lowOOMScoreAdj: 750, highOOMScoreAdj: 750},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 		"burstable-pod-resources-unequal-container-requests-with-sidecar": {
 | |
| 			pod: &burstablePodResourcesUnequalContainerRequestsWithSidecar,
 | |
| 			lowHighOOMScoreAdj: map[string]lowHighOOMScoreAdjTest{
 | |
| 				"burstable-container-1": {lowOOMScoreAdj: 725, highOOMScoreAdj: 725},
 | |
| 				"burstable-container-2": {lowOOMScoreAdj: 850, highOOMScoreAdj: 850},
 | |
| 				"burstable-sidecar":     {lowOOMScoreAdj: 850, highOOMScoreAdj: 850},
 | |
| 			},
 | |
| 			memoryCapacity:                  4000000000,
 | |
| 			podLevelResourcesFeatureEnabled: true,
 | |
| 		},
 | |
| 	}
 | |
| 	for name, test := range oomTests {
 | |
| 		t.Run(name, func(t *testing.T) {
 | |
| 			featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodLevelResources, test.podLevelResourcesFeatureEnabled)
 | |
| 			listContainers := test.pod.Spec.InitContainers
 | |
| 			listContainers = append(listContainers, test.pod.Spec.Containers...)
 | |
| 			for _, container := range listContainers {
 | |
| 				oomScoreAdj := GetContainerOOMScoreAdjust(test.pod, &container, test.memoryCapacity)
 | |
| 				if oomScoreAdj < test.lowHighOOMScoreAdj[container.Name].lowOOMScoreAdj || oomScoreAdj > test.lowHighOOMScoreAdj[container.Name].highOOMScoreAdj {
 | |
| 					t.Errorf("oom_score_adj %s should be between %d and %d, but was %d", container.Name, test.lowHighOOMScoreAdj[container.Name].lowOOMScoreAdj, test.lowHighOOMScoreAdj[container.Name].highOOMScoreAdj, oomScoreAdj)
 | |
| 				}
 | |
| 			}
 | |
| 		})
 | |
| 
 | |
| 	}
 | |
| }
 | 
