mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Unit tests for pod level hugepage resources
This commit is contained in:
parent
51db93c3fb
commit
b9e0d4ad66
@ -1222,6 +1222,298 @@ func TestPodResourcesDefaults(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "pod hugepages requests=unset limits=unset, container hugepages requests=unset limits=set",
|
||||
podLevelResourcesEnabled: true,
|
||||
podResources: &v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPodSpec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("3m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("6Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("6Mi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "pod hugepages requests=unset limits=set, container hugepages requests=unset limits=set",
|
||||
podLevelResourcesEnabled: true,
|
||||
podResources: &v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPodSpec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("3m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "pod hugepages requests=set limits=set, container hugepages requests=unset limits=set",
|
||||
podLevelResourcesEnabled: true,
|
||||
podResources: &v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPodSpec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("4Mi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "pod hugepages requests=set limits=set, container hugepages requests=unset limits=unset",
|
||||
podLevelResourcesEnabled: true,
|
||||
podResources: &v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{},
|
||||
},
|
||||
},
|
||||
expectedPodSpec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "pod hugepages requests=unset limits=set, container hugepages requests=unset limits=set different hugepagesizes between pod and container level",
|
||||
podLevelResourcesEnabled: true,
|
||||
podResources: &v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedPodSpec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("3m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("5m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("2m"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
}, {
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
"cpu": resource.MustParse("1m"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
for _, tc := range cases {
|
||||
|
@ -19024,7 +19024,7 @@ func TestValidatePodResourceConsistency(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "indivdual container limits greater than pod limits",
|
||||
name: "individual container limits greater than pod limits",
|
||||
podResources: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceCPU: resource.MustParse("10"),
|
||||
@ -19084,6 +19084,8 @@ func TestValidatePodResourceNames(t *testing.T) {
|
||||
{"memory", false},
|
||||
{"cpu", false},
|
||||
{"storage", true},
|
||||
{v1.ResourceHugePagesPrefix + "2Mi", false},
|
||||
{v1.ResourceHugePagesPrefix + "1Gi", false},
|
||||
{"requests.cpu", true},
|
||||
{"requests.memory", true},
|
||||
{"requests.storage", true},
|
||||
@ -19128,6 +19130,8 @@ func TestValidateResourceNames(t *testing.T) {
|
||||
{"memory", true, ""},
|
||||
{"cpu", true, ""},
|
||||
{"storage", true, ""},
|
||||
{v1.ResourceHugePagesPrefix + "2Mi", true, ""},
|
||||
{v1.ResourceHugePagesPrefix + "1Gi", true, ""},
|
||||
{"requests.cpu", true, ""},
|
||||
{"requests.memory", true, ""},
|
||||
{"requests.storage", true, ""},
|
||||
@ -23624,6 +23628,48 @@ func TestValidateResourceRequirements(t *testing.T) {
|
||||
},
|
||||
},
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "container resource hugepage with cpu or memory",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
core.ResourceCPU: resource.MustParse("10"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "container resource hugepage limit without request",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceMemory: resource.MustParse("2Mi"),
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource hugepages with cpu or memory",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceMemory: resource.MustParse("2Mi"),
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource hugepages limit without request",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceMemory: resource.MustParse("2Mi"),
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "limits and requests of memory resource are equal",
|
||||
requirements: core.ResourceRequirements{
|
||||
@ -23686,62 +23732,81 @@ func TestValidateResourceRequirements(t *testing.T) {
|
||||
validateFn func(requirements *core.ResourceRequirements,
|
||||
podClaimNames sets.Set[string], fldPath *field.Path,
|
||||
opts PodValidationOptions) field.ErrorList
|
||||
}{{
|
||||
name: "hugepage resource without cpu or memory",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
}{
|
||||
{
|
||||
name: "container resource hugepage without cpu or memory",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "container resource hugepage without limit",
|
||||
requirements: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceMemory: resource.MustParse("2Mi"),
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource hugepages without cpu or memory",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource hugepages request without limit",
|
||||
requirements: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceMemory: resource.MustParse("2Mi"),
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with ephemeral-storage",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceEphemeralStorage): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceEphemeralStorage + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with unsupported prefixed resources",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("kubernetesio/" + core.ResourceCPU): resource.MustParse("2"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("kubernetesio/" + core.ResourceMemory): resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with unsupported native resources",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("kubernetes.io/" + strings.Repeat("a", 63)): resource.MustParse("2"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("kubernetes.io/" + strings.Repeat("a", 63)): resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
},
|
||||
validateFn: ValidateContainerResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with hugepages",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceHugePagesPrefix + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with ephemeral-storage",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceEphemeralStorage): resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceEphemeralStorage + "2Mi"): resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with unsupported prefixed resources",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("kubernetesio/" + core.ResourceCPU): resource.MustParse("2"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("kubernetesio/" + core.ResourceMemory): resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
}, {
|
||||
name: "pod resource with unsupported native resources",
|
||||
requirements: core.ResourceRequirements{
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("kubernetes.io/" + strings.Repeat("a", 63)): resource.MustParse("2"),
|
||||
},
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("kubernetes.io/" + strings.Repeat("a", 63)): resource.MustParse("2"),
|
||||
},
|
||||
},
|
||||
validateFn: validatePodResourceRequirements,
|
||||
},
|
||||
{
|
||||
name: "pod resource with unsupported empty native resource name",
|
||||
requirements: core.ResourceRequirements{
|
||||
|
@ -665,7 +665,7 @@ func TestGetHugepageLimitsFromResources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
results := GetHugepageLimitsFromResources(test.resources)
|
||||
results := GetHugepageLimitsFromResources(&v1.Pod{}, test.resources)
|
||||
if !reflect.DeepEqual(expectedHugepages, results) {
|
||||
t.Errorf("%s test failed. Expected %v but got %v", test.name, expectedHugepages, results)
|
||||
}
|
||||
|
@ -543,6 +543,45 @@ func TestEnoughRequests(t *testing.T) {
|
||||
ResourceName: v1.ResourceMemory, Reason: getErrReason(v1.ResourceMemory), Requested: 2, Used: 19, Capacity: 20},
|
||||
},
|
||||
},
|
||||
{
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: newPodLevelResourcesPod(
|
||||
newResourcePod(),
|
||||
v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("3m"), v1.ResourceMemory: resource.MustParse("2"), hugePageResourceA: *resource.NewQuantity(5, resource.BinarySI)},
|
||||
},
|
||||
),
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
name: "pod-level hugepages resource fit",
|
||||
wantInsufficientResources: []InsufficientResource{},
|
||||
},
|
||||
{
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: newPodLevelResourcesPod(
|
||||
newResourcePod(framework.Resource{MilliCPU: 1, Memory: 1, ScalarResources: map[v1.ResourceName]int64{hugePageResourceA: 3}}),
|
||||
v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("3m"), v1.ResourceMemory: resource.MustParse("2"), hugePageResourceA: *resource.NewQuantity(5, resource.BinarySI)},
|
||||
},
|
||||
),
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
name: "both pod-level and container-level hugepages resource fit",
|
||||
wantInsufficientResources: []InsufficientResource{},
|
||||
},
|
||||
{
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: newPodLevelResourcesPod(
|
||||
newResourcePod(),
|
||||
v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("3m"), v1.ResourceMemory: resource.MustParse("2"), hugePageResourceA: *resource.NewQuantity(10, resource.BinarySI)},
|
||||
},
|
||||
),
|
||||
nodeInfo: framework.NewNodeInfo(),
|
||||
name: "pod-level hugepages resource not fit",
|
||||
wantStatus: framework.NewStatus(framework.Unschedulable, getErrReason(hugePageResourceA)),
|
||||
wantInsufficientResources: []InsufficientResource{
|
||||
{ResourceName: hugePageResourceA, Reason: getErrReason(hugePageResourceA), Requested: 10, Used: 0, Capacity: 5},
|
||||
},
|
||||
},
|
||||
{
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: newResourceInitPod(newPodLevelResourcesPod(
|
||||
@ -1547,8 +1586,25 @@ func TestIsFit(t *testing.T) {
|
||||
pod: st.MakePod().Resources(
|
||||
v1.ResourceRequirements{Requests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("2")}},
|
||||
).Obj(),
|
||||
node: st.MakeNode().Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj(),
|
||||
expected: true,
|
||||
node: st.MakeNode().Capacity(map[v1.ResourceName]string{v1.ResourceCPU: "2"}).Obj(),
|
||||
podLevelResourcesEnabled: true,
|
||||
expected: true,
|
||||
},
|
||||
"sufficient pod-level resource hugepages": {
|
||||
pod: st.MakePod().Resources(
|
||||
v1.ResourceRequirements{Requests: v1.ResourceList{hugePageResourceA: resource.MustParse("2Mi")}},
|
||||
).Obj(),
|
||||
node: st.MakeNode().Capacity(map[v1.ResourceName]string{hugePageResourceA: "2Mi"}).Obj(),
|
||||
podLevelResourcesEnabled: true,
|
||||
expected: true,
|
||||
},
|
||||
"insufficient pod-level resource hugepages": {
|
||||
pod: st.MakePod().Resources(
|
||||
v1.ResourceRequirements{Requests: v1.ResourceList{hugePageResourceA: resource.MustParse("4Mi")}},
|
||||
).Obj(),
|
||||
node: st.MakeNode().Capacity(map[v1.ResourceName]string{hugePageResourceA: "2Mi"}).Obj(),
|
||||
podLevelResourcesEnabled: true,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/swap"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@ -373,10 +376,11 @@ func TestMetrics(t *testing.T) {
|
||||
|
||||
func TestGetHugePagesMountOptions(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
pod *v1.Pod
|
||||
medium v1.StorageMedium
|
||||
shouldFail bool
|
||||
expectedResult string
|
||||
pod *v1.Pod
|
||||
medium v1.StorageMedium
|
||||
shouldFail bool
|
||||
expectedResult string
|
||||
podLevelResourcesEnabled bool
|
||||
}{
|
||||
"ProperValues": {
|
||||
pod: &v1.Pod{
|
||||
@ -605,10 +609,124 @@ func TestGetHugePagesMountOptions(t *testing.T) {
|
||||
shouldFail: true,
|
||||
expectedResult: "",
|
||||
},
|
||||
"PodLevelResourcesSinglePageSize": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePages,
|
||||
shouldFail: false,
|
||||
expectedResult: "pagesize=2Mi",
|
||||
},
|
||||
"PodLevelResourcesSinglePageSizeMediumPrefix": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePagesPrefix + "2Mi",
|
||||
shouldFail: false,
|
||||
expectedResult: "pagesize=2Mi",
|
||||
},
|
||||
"PodLevelResourcesMultiPageSize": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePages,
|
||||
shouldFail: true,
|
||||
expectedResult: "",
|
||||
},
|
||||
"PodLevelResourcesMultiPageSizeMediumPrefix": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePagesPrefix + "2Mi",
|
||||
shouldFail: false,
|
||||
expectedResult: "pagesize=2Mi",
|
||||
},
|
||||
"PodAndContainerLevelResourcesMultiPageSizeHugePagesMedium": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePages,
|
||||
shouldFail: true,
|
||||
expectedResult: "",
|
||||
},
|
||||
"PodAndContainerLevelResourcesMultiPageSizeHugePagesMediumPrefix": {
|
||||
podLevelResourcesEnabled: true,
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Resources: &v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName("hugepages-2Mi"): resource.MustParse("100Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
medium: v1.StorageMediumHugePagesPrefix + "2Mi",
|
||||
shouldFail: false,
|
||||
expectedResult: "pagesize=2Mi",
|
||||
},
|
||||
}
|
||||
|
||||
for testCaseName, testCase := range testCases {
|
||||
t.Run(testCaseName, func(t *testing.T) {
|
||||
if testCase.podLevelResourcesEnabled {
|
||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodLevelResources, true)
|
||||
}
|
||||
|
||||
value, err := getPageSizeMountOption(testCase.medium, testCase.pod)
|
||||
if testCase.shouldFail && err == nil {
|
||||
t.Errorf("%s: Unexpected success", testCaseName)
|
||||
|
@ -1710,6 +1710,118 @@ func TestPodLevelResourceRequests(t *testing.T) {
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceMemory: resource.MustParse("15Mi"), v1.ResourceCPU: resource.MustParse("18m")},
|
||||
},
|
||||
{
|
||||
name: "pod-level resources, hugepage request/limit single page size",
|
||||
podResources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceMemory: resource.MustParse("10Mi"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
},
|
||||
},
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceMemory: resource.MustParse("10Mi"), v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi")},
|
||||
},
|
||||
{
|
||||
name: "pod-level resources, hugepage request/limit multiple page sizes",
|
||||
podResources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("1"), v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("2Mi"), v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi")},
|
||||
},
|
||||
{
|
||||
name: "pod-level resources, container-level resources, hugepage request/limit single page size",
|
||||
podResources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("6Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("6Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("1"), v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi")},
|
||||
},
|
||||
{
|
||||
name: "pod-level resources, container-level resources, hugepage request/limit multiple page sizes",
|
||||
podResources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("2Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("2Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("1"), v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"), v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("2Gi")},
|
||||
},
|
||||
{
|
||||
name: "pod-level resources, container-level resources, hugepage request/limit multiple page sizes between pod-level and container-level",
|
||||
podResources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceCPU: resource.MustParse("1"),
|
||||
v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"),
|
||||
},
|
||||
},
|
||||
containers: []v1.Container{
|
||||
{
|
||||
Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceMemory: resource.MustParse("4Mi"),
|
||||
v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
opts: PodResourcesOptions{SkipPodLevelResources: false},
|
||||
expectedRequests: v1.ResourceList{v1.ResourceCPU: resource.MustParse("1"), v1.ResourceMemory: resource.MustParse("4Mi"), v1.ResourceHugePagesPrefix + "2Mi": resource.MustParse("10Mi"), v1.ResourceHugePagesPrefix + "1Gi": resource.MustParse("1Gi")},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@ -1721,6 +1833,47 @@ func TestPodLevelResourceRequests(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSupportedPodLevelResource(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
resource v1.ResourceName
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: v1.ResourceCPU.String(),
|
||||
resource: v1.ResourceCPU,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: v1.ResourceMemory.String(),
|
||||
resource: v1.ResourceMemory,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: v1.ResourceEphemeralStorage.String(),
|
||||
resource: v1.ResourceEphemeralStorage,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: v1.ResourceHugePagesPrefix + "2Mi",
|
||||
resource: v1.ResourceHugePagesPrefix + "2Mi",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: v1.ResourceHugePagesPrefix + "1Gi",
|
||||
resource: v1.ResourceHugePagesPrefix + "1Gi",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if got := IsSupportedPodLevelResource(tc.resource); got != tc.expected {
|
||||
t.Errorf("Supported pod level resource %s: got=%t, want=%t", tc.resource.String(), got, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAggregateContainerRequestsAndLimits(t *testing.T) {
|
||||
restartAlways := v1.ContainerRestartPolicyAlways
|
||||
cases := []struct {
|
||||
|
Loading…
Reference in New Issue
Block a user