k8s.io/kubernetes@v1.29.3/pkg/kubelet/cm/pod_container_manager_linux_test.go (about) 1 //go:build linux 2 // +build linux 3 4 /* 5 Copyright 2016 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package cm 21 22 import ( 23 "strings" 24 "testing" 25 26 "github.com/stretchr/testify/require" 27 "k8s.io/apimachinery/pkg/api/resource" 28 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 30 v1 "k8s.io/api/core/v1" 31 "k8s.io/apimachinery/pkg/types" 32 ) 33 34 func TestIsCgroupPod(t *testing.T) { 35 qosContainersInfo := QOSContainersInfo{ 36 Guaranteed: RootCgroupName, 37 Burstable: NewCgroupName(RootCgroupName, strings.ToLower(string(v1.PodQOSBurstable))), 38 BestEffort: NewCgroupName(RootCgroupName, strings.ToLower(string(v1.PodQOSBestEffort))), 39 } 40 podUID := types.UID("123") 41 testCases := []struct { 42 input CgroupName 43 expectedResult bool 44 expectedUID types.UID 45 }{ 46 { 47 input: RootCgroupName, 48 expectedResult: false, 49 expectedUID: types.UID(""), 50 }, 51 { 52 input: NewCgroupName(qosContainersInfo.Guaranteed), 53 expectedResult: false, 54 expectedUID: types.UID(""), 55 }, 56 { 57 input: NewCgroupName(qosContainersInfo.Guaranteed, GetPodCgroupNameSuffix(podUID)), 58 expectedResult: true, 59 expectedUID: podUID, 60 }, 61 { 62 input: NewCgroupName(qosContainersInfo.Guaranteed, GetPodCgroupNameSuffix(podUID), "container.scope"), 63 expectedResult: false, 64 expectedUID: types.UID(""), 65 }, 66 { 67 input: NewCgroupName(qosContainersInfo.Burstable), 68 expectedResult: false, 69 expectedUID: types.UID(""), 70 }, 71 { 72 input: NewCgroupName(qosContainersInfo.Burstable, GetPodCgroupNameSuffix(podUID)), 73 expectedResult: true, 74 expectedUID: podUID, 75 }, 76 { 77 input: NewCgroupName(qosContainersInfo.Burstable, GetPodCgroupNameSuffix(podUID), "container.scope"), 78 expectedResult: false, 79 expectedUID: types.UID(""), 80 }, 81 { 82 input: NewCgroupName(qosContainersInfo.BestEffort), 83 expectedResult: false, 84 expectedUID: types.UID(""), 85 }, 86 { 87 input: NewCgroupName(qosContainersInfo.BestEffort, GetPodCgroupNameSuffix(podUID)), 88 expectedResult: true, 89 expectedUID: podUID, 90 }, 91 { 92 input: NewCgroupName(qosContainersInfo.BestEffort, GetPodCgroupNameSuffix(podUID), "container.scope"), 93 expectedResult: false, 94 expectedUID: types.UID(""), 95 }, 96 { 97 input: NewCgroupName(RootCgroupName, "system"), 98 expectedResult: false, 99 expectedUID: types.UID(""), 100 }, 101 { 102 input: NewCgroupName(RootCgroupName, "system", "kubelet"), 103 expectedResult: false, 104 expectedUID: types.UID(""), 105 }, 106 { 107 // contains reserved word "pod" in cgroup name 108 input: NewCgroupName(RootCgroupName, GetPodCgroupNameSuffix("this-uid-contains-reserved-word-pod")), 109 expectedResult: false, 110 expectedUID: types.UID(""), 111 }, 112 } 113 for _, cgroupDriver := range []string{"cgroupfs", "systemd"} { 114 pcm := &podContainerManagerImpl{ 115 cgroupManager: NewCgroupManager(nil, cgroupDriver), 116 enforceCPULimits: true, 117 qosContainersInfo: qosContainersInfo, 118 } 119 for _, testCase := range testCases { 120 // Give the right cgroup structure based on whether systemd is enabled. 121 var name string 122 if cgroupDriver == "systemd" { 123 name = testCase.input.ToSystemd() 124 } else { 125 name = testCase.input.ToCgroupfs() 126 } 127 // check if this is a pod or not with the literal cgroupfs input 128 result, resultUID := pcm.IsPodCgroup(name) 129 if result != testCase.expectedResult { 130 t.Errorf("Unexpected result for driver: %v, input: %v, expected: %v, actual: %v", cgroupDriver, testCase.input, testCase.expectedResult, result) 131 } 132 if resultUID != testCase.expectedUID { 133 t.Errorf("Unexpected result for driver: %v, input: %v, expected: %v, actual: %v", cgroupDriver, testCase.input, testCase.expectedUID, resultUID) 134 } 135 136 } 137 } 138 } 139 140 func TestGetPodContainerName(t *testing.T) { 141 newGuaranteedPodWithUID := func(uid types.UID) *v1.Pod { 142 return &v1.Pod{ 143 ObjectMeta: metav1.ObjectMeta{ 144 UID: uid, 145 }, 146 Spec: v1.PodSpec{ 147 Containers: []v1.Container{ 148 { 149 Name: "container", 150 Resources: v1.ResourceRequirements{ 151 Requests: v1.ResourceList{ 152 v1.ResourceCPU: resource.MustParse("1000m"), 153 v1.ResourceMemory: resource.MustParse("1G"), 154 }, 155 Limits: v1.ResourceList{ 156 v1.ResourceCPU: resource.MustParse("1000m"), 157 v1.ResourceMemory: resource.MustParse("1G"), 158 }, 159 }, 160 }, 161 }, 162 }, 163 } 164 } 165 newBurstablePodWithUID := func(uid types.UID) *v1.Pod { 166 return &v1.Pod{ 167 ObjectMeta: metav1.ObjectMeta{ 168 UID: uid, 169 }, 170 Spec: v1.PodSpec{ 171 Containers: []v1.Container{ 172 { 173 Name: "container", 174 Resources: v1.ResourceRequirements{ 175 Requests: v1.ResourceList{ 176 v1.ResourceCPU: resource.MustParse("1000m"), 177 v1.ResourceMemory: resource.MustParse("1G"), 178 }, 179 }, 180 }, 181 }, 182 }, 183 } 184 } 185 newBestEffortPodWithUID := func(uid types.UID) *v1.Pod { 186 return &v1.Pod{ 187 ObjectMeta: metav1.ObjectMeta{ 188 UID: uid, 189 }, 190 Spec: v1.PodSpec{ 191 Containers: []v1.Container{ 192 { 193 Name: "container", 194 }, 195 }, 196 }, 197 } 198 } 199 200 qosContainersInfo := QOSContainersInfo{ 201 Guaranteed: RootCgroupName, 202 Burstable: NewCgroupName(RootCgroupName, strings.ToLower(string(v1.PodQOSBurstable))), 203 BestEffort: NewCgroupName(RootCgroupName, strings.ToLower(string(v1.PodQOSBestEffort))), 204 } 205 206 type fields struct { 207 cgroupManager CgroupManager 208 } 209 type args struct { 210 pod *v1.Pod 211 } 212 213 tests := []struct { 214 name string 215 fields fields 216 args args 217 wantCgroupName CgroupName 218 wantLiteralCgroupfs string 219 }{ 220 { 221 name: "pod with qos guaranteed and cgroupfs", 222 fields: fields{ 223 cgroupManager: NewCgroupManager(nil, "cgroupfs"), 224 }, 225 args: args{ 226 pod: newGuaranteedPodWithUID("fake-uid-1"), 227 }, 228 wantCgroupName: NewCgroupName(qosContainersInfo.Guaranteed, "podfake-uid-1"), 229 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.Guaranteed, "podfake-uid-1").ToCgroupfs(), 230 }, { 231 name: "pod with qos guaranteed and systemd", 232 fields: fields{ 233 cgroupManager: NewCgroupManager(nil, "systemd"), 234 }, 235 args: args{ 236 pod: newGuaranteedPodWithUID("fake-uid-2"), 237 }, 238 wantCgroupName: NewCgroupName(qosContainersInfo.Guaranteed, "podfake-uid-2"), 239 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.Guaranteed, "podfake-uid-2").ToSystemd(), 240 }, { 241 name: "pod with qos burstable and cgroupfs", 242 fields: fields{ 243 cgroupManager: NewCgroupManager(nil, "cgroupfs"), 244 }, 245 args: args{ 246 pod: newBurstablePodWithUID("fake-uid-3"), 247 }, 248 wantCgroupName: NewCgroupName(qosContainersInfo.Burstable, "podfake-uid-3"), 249 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.Burstable, "podfake-uid-3").ToCgroupfs(), 250 }, { 251 name: "pod with qos burstable and systemd", 252 fields: fields{ 253 cgroupManager: NewCgroupManager(nil, "systemd"), 254 }, 255 args: args{ 256 pod: newBurstablePodWithUID("fake-uid-4"), 257 }, 258 wantCgroupName: NewCgroupName(qosContainersInfo.Burstable, "podfake-uid-4"), 259 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.Burstable, "podfake-uid-4").ToSystemd(), 260 }, { 261 name: "pod with qos best-effort and cgroupfs", 262 fields: fields{ 263 cgroupManager: NewCgroupManager(nil, "cgroupfs"), 264 }, 265 args: args{ 266 pod: newBestEffortPodWithUID("fake-uid-5"), 267 }, 268 wantCgroupName: NewCgroupName(qosContainersInfo.BestEffort, "podfake-uid-5"), 269 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.BestEffort, "podfake-uid-5").ToCgroupfs(), 270 }, { 271 name: "pod with qos best-effort and systemd", 272 fields: fields{ 273 cgroupManager: NewCgroupManager(nil, "systemd"), 274 }, 275 args: args{ 276 pod: newBestEffortPodWithUID("fake-uid-6"), 277 }, 278 wantCgroupName: NewCgroupName(qosContainersInfo.BestEffort, "podfake-uid-6"), 279 wantLiteralCgroupfs: NewCgroupName(qosContainersInfo.BestEffort, "podfake-uid-6").ToSystemd(), 280 }, 281 } 282 283 for _, tt := range tests { 284 pcm := &podContainerManagerImpl{ 285 cgroupManager: tt.fields.cgroupManager, 286 qosContainersInfo: qosContainersInfo, 287 } 288 289 t.Run(tt.name, func(t *testing.T) { 290 actualCgroupName, actualLiteralCgroupfs := pcm.GetPodContainerName(tt.args.pod) 291 require.Equalf(t, tt.wantCgroupName, actualCgroupName, "Unexpected cgroup name for pod with UID %s, container resources: %v", tt.args.pod.UID, tt.args.pod.Spec.Containers[0].Resources) 292 require.Equalf(t, tt.wantLiteralCgroupfs, actualLiteralCgroupfs, "Unexpected literal cgroupfs for pod with UID %s, container resources: %v", tt.args.pod.UID, tt.args.pod.Spec.Containers[0].Resources) 293 }) 294 } 295 }