Implement tests for multiple sizes huge pages
Co-Authored-By: Odin Ugedal <odin@ugedal.com>
This commit is contained in:
@@ -24,7 +24,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
@@ -3908,114 +3908,186 @@ func TestValidateVolumes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHugePagesIsolation(t *testing.T) {
|
||||
successCases := []core.Pod{
|
||||
{ // Basic fields.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
testCases := map[string]struct {
|
||||
pod *core.Pod
|
||||
enableHugePageStorageMediumSize bool
|
||||
expectError bool
|
||||
}{
|
||||
"Valid: request hugepages-2Mi": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "123", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
"Valid: HugePageStorageMediumSize enabled: request more than one hugepages size": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
enableHugePageStorageMediumSize: true,
|
||||
expectError: false,
|
||||
},
|
||||
"Invalid: HugePageStorageMediumSize disabled: request hugepages-1Gi, limit hugepages-2Mi and hugepages-1Gi": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-multiple", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
},
|
||||
"Invalid: not requesting cpu and memory": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-requireCpuOrMemory", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
},
|
||||
"Invalid: request 1Gi hugepages-2Mi but limit 2Gi": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
},
|
||||
"Invalid: HugePageStorageMediumSize disabled: request more than one hugepages size": {
|
||||
pod: &core.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
expectError: true,
|
||||
},
|
||||
}
|
||||
failureCases := []core.Pod{
|
||||
{ // Basic fields.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-requireCpuOrMemory", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
{ // Basic fields.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-shared", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
{ // Basic fields.
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "hugepages-multiple", Namespace: "ns"},
|
||||
Spec: core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File",
|
||||
Resources: core.ResourceRequirements{
|
||||
Requests: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
Limits: core.ResourceList{
|
||||
core.ResourceName(core.ResourceCPU): resource.MustParse("10"),
|
||||
core.ResourceName(core.ResourceMemory): resource.MustParse("10G"),
|
||||
core.ResourceName("hugepages-2Mi"): resource.MustParse("1Gi"),
|
||||
core.ResourceName("hugepages-1Gi"): resource.MustParse("2Gi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
RestartPolicy: core.RestartPolicyAlways,
|
||||
DNSPolicy: core.DNSClusterFirst,
|
||||
},
|
||||
},
|
||||
}
|
||||
for i := range successCases {
|
||||
pod := &successCases[i]
|
||||
if errs := ValidatePod(pod); len(errs) != 0 {
|
||||
t.Errorf("Unexpected error for case[%d], err: %v", i, errs)
|
||||
}
|
||||
}
|
||||
for i := range failureCases {
|
||||
pod := &failureCases[i]
|
||||
if errs := ValidatePod(pod); len(errs) == 0 {
|
||||
t.Errorf("Expected error for case[%d], pod: %v", i, pod.Name)
|
||||
}
|
||||
for tcName, tc := range testCases {
|
||||
t.Run(tcName, func(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.HugePageStorageMediumSize, tc.enableHugePageStorageMediumSize)()
|
||||
errs := ValidatePod(tc.pod, PodValidationOptions{tc.enableHugePageStorageMediumSize})
|
||||
if tc.expectError && len(errs) == 0 {
|
||||
t.Errorf("Unexpected success")
|
||||
}
|
||||
if !tc.expectError && len(errs) != 0 {
|
||||
t.Errorf("Unexpected error(s): %v", errs)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7375,7 +7447,7 @@ func TestValidatePod(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, pod := range successCases {
|
||||
if errs := ValidatePod(&pod); len(errs) != 0 {
|
||||
if errs := ValidatePod(&pod, PodValidationOptions{}); len(errs) != 0 {
|
||||
t.Errorf("expected success: %v", errs)
|
||||
}
|
||||
}
|
||||
@@ -8225,7 +8297,7 @@ func TestValidatePod(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for k, v := range errorCases {
|
||||
if errs := ValidatePod(&v.spec); len(errs) == 0 {
|
||||
if errs := ValidatePod(&v.spec, PodValidationOptions{}); len(errs) == 0 {
|
||||
t.Errorf("expected failure for %q", k)
|
||||
} else if v.expectedError == "" {
|
||||
t.Errorf("missing expectedError for %q, got %q", k, errs.ToAggregate().Error())
|
||||
@@ -8965,7 +9037,7 @@ func TestValidatePodUpdate(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
test.new.ObjectMeta.ResourceVersion = "1"
|
||||
test.old.ObjectMeta.ResourceVersion = "1"
|
||||
errs := ValidatePodUpdate(&test.new, &test.old)
|
||||
errs := ValidatePodUpdate(&test.new, &test.old, PodValidationOptions{})
|
||||
if test.err == "" {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("unexpected invalid: %s (%+v)\nA: %+v\nB: %+v", test.test, errs, test.new, test.old)
|
||||
@@ -14876,7 +14948,7 @@ func TestPodIPsValidation(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
errs := ValidatePod(&testCase.pod)
|
||||
errs := ValidatePod(&testCase.pod, PodValidationOptions{})
|
||||
if len(errs) == 0 && testCase.expectError {
|
||||
t.Errorf("expected failure for %s, but there were none", testCase.pod.Name)
|
||||
return
|
||||
|
Reference in New Issue
Block a user