From 215d0b094b686ae0ad83a8f2d3078e5860a979ba Mon Sep 17 00:00:00 2001 From: lixiv Date: Mon, 30 Dec 2024 12:46:12 +0800 Subject: [PATCH] Add tests for kubectl qos (#129388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add tests for kubectl qos * Update staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go Co-authored-by: Arda Güçlü --------- Co-authored-by: Arda Güçlü --- .../k8s.io/kubectl/pkg/util/qos/qos_test.go | 201 ++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go diff --git a/staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go b/staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go new file mode 100644 index 00000000000..0c0a630056c --- /dev/null +++ b/staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go @@ -0,0 +1,201 @@ +/* +Copyright 2024 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 ( + "reflect" + "testing" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" +) + +func TestGetPodQOS(t *testing.T) { + tests := []struct { + name string + pod *corev1.Pod + want corev1.PodQOSClass + }{ + { + name: "guaranteed pod with status", + pod: &corev1.Pod{ + Status: corev1.PodStatus{ + QOSClass: corev1.PodQOSGuaranteed, + }, + }, + want: corev1.PodQOSGuaranteed, + }, + { + name: "burstable pod with status", + pod: &corev1.Pod{ + Status: corev1.PodStatus{ + QOSClass: corev1.PodQOSBurstable, + }, + }, + want: corev1.PodQOSBurstable, + }, + { + name: "besteffort pod with status", + pod: &corev1.Pod{ + Status: corev1.PodStatus{ + QOSClass: corev1.PodQOSBestEffort, + }, + }, + want: corev1.PodQOSBestEffort, + }, + { + name: "guaranteed pod without status", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container1", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + }, + }, + }, + want: corev1.PodQOSGuaranteed, + }, + { + name: "guaranteed pod with two containers", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container1", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + { + Name: "container2", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + }, + }, + }, + want: corev1.PodQOSGuaranteed, + }, + { + name: "burstable pod without status", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container1", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + }, + }, + }, + want: corev1.PodQOSBurstable, + }, + { + name: "burstable pod with two containers", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container1", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + { + Name: "container2", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + Limits: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("1"), + corev1.ResourceMemory: resource.MustParse("1Gi"), + }, + }, + }, + }, + }, + }, + want: corev1.PodQOSBurstable, + }, + { + name: "besteffort pod without status", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "container1", + Resources: corev1.ResourceRequirements{}, + }, + }, + }, + }, + want: corev1.PodQOSBestEffort, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := GetPodQOS(tt.pod); !reflect.DeepEqual(got, tt.want) { + t.Errorf("unexpected PodQOSClass actual %s, expected %s", got, tt.want) + } + }) + } +}