Add tests for kubectl qos (#129388)

* Add tests for kubectl qos

* Update staging/src/k8s.io/kubectl/pkg/util/qos/qos_test.go

Co-authored-by: Arda Güçlü <aguclu@redhat.com>

---------

Co-authored-by: Arda Güçlü <aguclu@redhat.com>

Kubernetes-commit: 215d0b094b686ae0ad83a8f2d3078e5860a979ba
This commit is contained in:
lixiv 2024-12-30 12:46:12 +08:00 committed by Kubernetes Publisher
parent a8a00dbee1
commit be364695f5
3 changed files with 218 additions and 15 deletions

12
go.mod
View File

@ -31,12 +31,12 @@ require (
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.28.0
gopkg.in/evanphx/json-patch.v4 v4.12.0
k8s.io/api v0.0.0-20241214014715-eac45518d7fe
k8s.io/apimachinery v0.0.0-20241218005452-a1a247aa259f
k8s.io/api v0.0.0-20241220201724-9603cdf39dd3
k8s.io/apimachinery v0.0.0-20241218214440-307a3ddd3cae
k8s.io/cli-runtime v0.0.0-20241214022530-e4532273187e
k8s.io/client-go v0.0.0-20241215015103-67da6d1a4174
k8s.io/component-base v0.0.0-20241218055610-6f2a8d010d0b
k8s.io/component-helpers v0.0.0-20241214020249-81a0289f4873
k8s.io/client-go v0.0.0-20241229162156-da6e2946e51b
k8s.io/component-base v0.0.0-20241227092012-b0e32027e0d6
k8s.io/component-helpers v0.0.0-20241218220436-ea1d94c89c60
k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7
k8s.io/metrics v0.0.0-20241214022351-cd48baffab30
@ -94,3 +94,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/kustomize/api v0.18.0 // indirect
)
replace k8s.io/code-generator => k8s.io/code-generator v0.0.0-20241218220056-bd95f067c5d5

20
go.sum
View File

@ -200,18 +200,18 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.0.0-20241214014715-eac45518d7fe h1:3brWXwMKrWloyi0Qqv6SqRIGC/yS1wf5/OSxirB/ruw=
k8s.io/api v0.0.0-20241214014715-eac45518d7fe/go.mod h1:TeD+e60UFfC0xfnP9/tT92lG7sSnSs+ebTPX1oCNrDU=
k8s.io/apimachinery v0.0.0-20241218005452-a1a247aa259f h1:LrAV1siJEy6+lNiha/RymCV2riXmYUOaMSN5nQqq680=
k8s.io/apimachinery v0.0.0-20241218005452-a1a247aa259f/go.mod h1:vmecNW2HWfNZboIXS3Vg/3qp+T42YyW6jCpcdhnas9s=
k8s.io/api v0.0.0-20241220201724-9603cdf39dd3 h1:3iyOtnvuB7R9AEVZwh3FVRdSz4Q6bDIHh2H8HRs8Tzw=
k8s.io/api v0.0.0-20241220201724-9603cdf39dd3/go.mod h1:bKle1AFx44vmuGNGuRrPJ7r/4K4DXYFQTlcRWFZTodM=
k8s.io/apimachinery v0.0.0-20241218214440-307a3ddd3cae h1:f/c+v/txPi2w3c3YUM1hO6aMDx8s1HOYYNUD3ugomyg=
k8s.io/apimachinery v0.0.0-20241218214440-307a3ddd3cae/go.mod h1:vmecNW2HWfNZboIXS3Vg/3qp+T42YyW6jCpcdhnas9s=
k8s.io/cli-runtime v0.0.0-20241214022530-e4532273187e h1:Ie/aQEIDo9fPuITJKm5xetW+8JGsD8Zvj7Zm63urQWw=
k8s.io/cli-runtime v0.0.0-20241214022530-e4532273187e/go.mod h1:zBvvuqEnbfCG7dmlroXrfVhDrCGEtz7MfknRnmp8Kpg=
k8s.io/client-go v0.0.0-20241215015103-67da6d1a4174 h1:NcD7ZRs38+ChK6qTJN5ahkVq7MWuNaZZiO1AspZLwck=
k8s.io/client-go v0.0.0-20241215015103-67da6d1a4174/go.mod h1:9DOj9Eg/2wdCibOBBR8J+SamkzoU+TVr9bk5B7KAbgM=
k8s.io/component-base v0.0.0-20241218055610-6f2a8d010d0b h1:5xS2+0VdSMu+MLC9Jm87whzBFtpC7qsuxE2cZE3LiAU=
k8s.io/component-base v0.0.0-20241218055610-6f2a8d010d0b/go.mod h1:Kj/g/ohXooaZcUnb1iGPgPp+Oxo1YFgKwkpjzIG/nbc=
k8s.io/component-helpers v0.0.0-20241214020249-81a0289f4873 h1:xoV3np7eRxerPwLtt56i6mpBTXVDQa1HLMZFJINO9Cc=
k8s.io/component-helpers v0.0.0-20241214020249-81a0289f4873/go.mod h1:r8hkfAgz6EBX5lp+DOOlbuM8bmTS93KSaLJS2CBsrGM=
k8s.io/client-go v0.0.0-20241229162156-da6e2946e51b h1:gTH1Y1wyRRzMGqTjR82376gIuiz3RLUKgavZPR/GmOg=
k8s.io/client-go v0.0.0-20241229162156-da6e2946e51b/go.mod h1:87icbG03uieDcFQ5Y9uD1Kuq+L382I6gZn38z8Wwe1s=
k8s.io/component-base v0.0.0-20241227092012-b0e32027e0d6 h1:fDg6IigKI8lU+5we9oEq7iofXG3Pa0pTQCgrBAtgPrs=
k8s.io/component-base v0.0.0-20241227092012-b0e32027e0d6/go.mod h1:CBPOY8y18whIdnIRKT/mXuqDMRKARlq7lFQ3fB2T86s=
k8s.io/component-helpers v0.0.0-20241218220436-ea1d94c89c60 h1:qz61k0DW/lD8fsdCGFYCrbMV9S8m2vQfq/RCB800O4g=
k8s.io/component-helpers v0.0.0-20241218220436-ea1d94c89c60/go.mod h1:xC8r6WOACz7ljnn4nXOc9rSQN636pJXWDct9rXXEHWQ=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=

201
pkg/util/qos/qos_test.go Normal file
View File

@ -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)
}
})
}
}