k8s.io/kubernetes@v1.29.3/pkg/scheduler/metrics/resources/resources_test.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // Package resources provides a metrics collector that reports the 18 // resource consumption (requests and limits) of the pods in the cluster 19 // as the scheduler and kubelet would interpret it. 20 package resources 21 22 import ( 23 "net/http" 24 "net/http/httptest" 25 "strings" 26 "testing" 27 28 v1 "k8s.io/api/core/v1" 29 "k8s.io/apimachinery/pkg/api/resource" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "k8s.io/apimachinery/pkg/labels" 32 corelisters "k8s.io/client-go/listers/core/v1" 33 "k8s.io/component-base/metrics" 34 "k8s.io/component-base/metrics/testutil" 35 "k8s.io/utils/ptr" 36 ) 37 38 type fakePodLister struct { 39 pods []*v1.Pod 40 } 41 42 func (l *fakePodLister) List(selector labels.Selector) (ret []*v1.Pod, err error) { 43 return l.pods, nil 44 } 45 46 func (l *fakePodLister) Pods(namespace string) corelisters.PodNamespaceLister { 47 panic("not implemented") 48 } 49 50 func Test_podResourceCollector_Handler(t *testing.T) { 51 h := Handler(&fakePodLister{pods: []*v1.Pod{ 52 { 53 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 54 Spec: v1.PodSpec{ 55 NodeName: "node-one", 56 InitContainers: []v1.Container{ 57 {Resources: v1.ResourceRequirements{ 58 Requests: v1.ResourceList{ 59 "cpu": resource.MustParse("2"), 60 "custom": resource.MustParse("3"), 61 }, 62 Limits: v1.ResourceList{ 63 "memory": resource.MustParse("1G"), 64 "custom": resource.MustParse("5"), 65 }, 66 }}, 67 }, 68 Containers: []v1.Container{ 69 {Resources: v1.ResourceRequirements{ 70 Requests: v1.ResourceList{ 71 "cpu": resource.MustParse("1"), 72 "custom": resource.MustParse("0"), 73 }, 74 Limits: v1.ResourceList{ 75 "memory": resource.MustParse("2.5Gi"), 76 "custom": resource.MustParse("6"), 77 }, 78 }}, 79 }, 80 }, 81 Status: v1.PodStatus{ 82 Conditions: []v1.PodCondition{ 83 {Type: v1.PodInitialized, Status: v1.ConditionTrue}, 84 }, 85 }, 86 }, 87 }}) 88 89 r := httptest.NewRecorder() 90 req, err := http.NewRequest("GET", "/metrics/resources", nil) 91 if err != nil { 92 t.Fatal(err) 93 } 94 h.ServeHTTP(r, req) 95 96 expected := `# HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 97 # TYPE kube_pod_resource_limit gauge 98 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 6 99 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 2.68435456e+09 100 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 101 # TYPE kube_pod_resource_request gauge 102 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 2 103 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 3 104 ` 105 out := r.Body.String() 106 if expected != out { 107 t.Fatal(out) 108 } 109 } 110 111 func Test_podResourceCollector_CollectWithStability(t *testing.T) { 112 tests := []struct { 113 name string 114 115 pods []*v1.Pod 116 expected string 117 }{ 118 {}, 119 { 120 name: "no containers", 121 pods: []*v1.Pod{ 122 { 123 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 124 }, 125 }, 126 }, 127 { 128 name: "no resources", 129 pods: []*v1.Pod{ 130 { 131 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 132 Spec: v1.PodSpec{ 133 InitContainers: []v1.Container{}, 134 Containers: []v1.Container{}, 135 }, 136 }, 137 }, 138 }, 139 { 140 name: "request only", 141 pods: []*v1.Pod{ 142 { 143 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 144 Spec: v1.PodSpec{ 145 Containers: []v1.Container{ 146 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 147 }, 148 }, 149 }, 150 }, 151 expected: ` 152 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 153 # TYPE kube_pod_resource_request gauge 154 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 1 155 `, 156 }, 157 { 158 name: "limits only", 159 pods: []*v1.Pod{ 160 { 161 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 162 Spec: v1.PodSpec{ 163 Containers: []v1.Container{ 164 {Resources: v1.ResourceRequirements{Limits: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 165 }, 166 }, 167 }, 168 }, 169 expected: ` 170 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 171 # TYPE kube_pod_resource_limit gauge 172 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 1 173 `, 174 }, 175 { 176 name: "terminal pods are excluded", 177 pods: []*v1.Pod{ 178 { 179 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo-unscheduled-succeeded"}, 180 Spec: v1.PodSpec{ 181 Containers: []v1.Container{ 182 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 183 }, 184 }, 185 // until node name is set, phase is ignored 186 Status: v1.PodStatus{Phase: v1.PodSucceeded}, 187 }, 188 { 189 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo-succeeded"}, 190 Spec: v1.PodSpec{ 191 NodeName: "node-one", 192 Containers: []v1.Container{ 193 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 194 }, 195 }, 196 Status: v1.PodStatus{Phase: v1.PodSucceeded}, 197 }, 198 { 199 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo-failed"}, 200 Spec: v1.PodSpec{ 201 NodeName: "node-one", 202 Containers: []v1.Container{ 203 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 204 }, 205 }, 206 Status: v1.PodStatus{Phase: v1.PodFailed}, 207 }, 208 { 209 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo-unknown"}, 210 Spec: v1.PodSpec{ 211 NodeName: "node-one", 212 Containers: []v1.Container{ 213 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 214 }, 215 }, 216 Status: v1.PodStatus{Phase: v1.PodUnknown}, 217 }, 218 { 219 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo-pending"}, 220 Spec: v1.PodSpec{ 221 NodeName: "node-one", 222 InitContainers: []v1.Container{ 223 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 224 }, 225 Containers: []v1.Container{ 226 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 227 }, 228 }, 229 Status: v1.PodStatus{ 230 Phase: v1.PodPending, 231 Conditions: []v1.PodCondition{ 232 {Type: "ArbitraryCondition", Status: v1.ConditionTrue}, 233 }, 234 }, 235 }, 236 }, 237 expected: ` 238 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 239 # TYPE kube_pod_resource_request gauge 240 kube_pod_resource_request{namespace="test",node="",pod="foo-unscheduled-succeeded",priority="",resource="cpu",scheduler="",unit="cores"} 1 241 kube_pod_resource_request{namespace="test",node="node-one",pod="foo-pending",priority="",resource="cpu",scheduler="",unit="cores"} 1 242 kube_pod_resource_request{namespace="test",node="node-one",pod="foo-unknown",priority="",resource="cpu",scheduler="",unit="cores"} 1 243 `, 244 }, 245 { 246 name: "zero resource should be excluded", 247 pods: []*v1.Pod{ 248 { 249 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 250 Spec: v1.PodSpec{ 251 InitContainers: []v1.Container{ 252 {Resources: v1.ResourceRequirements{ 253 Requests: v1.ResourceList{ 254 "cpu": resource.MustParse("0"), 255 "custom": resource.MustParse("0"), 256 "test.com/custom-metric": resource.MustParse("0"), 257 }, 258 Limits: v1.ResourceList{ 259 "cpu": resource.MustParse("0"), 260 "custom": resource.MustParse("0"), 261 "test.com/custom-metric": resource.MustParse("0"), 262 }, 263 }}, 264 }, 265 Containers: []v1.Container{ 266 {Resources: v1.ResourceRequirements{ 267 Requests: v1.ResourceList{ 268 "cpu": resource.MustParse("0"), 269 "custom": resource.MustParse("0"), 270 "test.com/custom-metric": resource.MustParse("0"), 271 }, 272 Limits: v1.ResourceList{ 273 "cpu": resource.MustParse("0"), 274 "custom": resource.MustParse("0"), 275 "test.com/custom-metric": resource.MustParse("0"), 276 }, 277 }}, 278 }, 279 }, 280 }, 281 }, 282 expected: ``, 283 }, 284 { 285 name: "optional field labels", 286 pods: []*v1.Pod{ 287 { 288 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 289 Spec: v1.PodSpec{ 290 SchedulerName: "default-scheduler", 291 Priority: ptr.To[int32](0), 292 NodeName: "node-one", 293 Containers: []v1.Container{ 294 {Resources: v1.ResourceRequirements{Requests: v1.ResourceList{"cpu": resource.MustParse("1")}}}, 295 }, 296 }, 297 }, 298 }, 299 expected: ` 300 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 301 # TYPE kube_pod_resource_request gauge 302 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="0",resource="cpu",scheduler="default-scheduler",unit="cores"} 1 303 `, 304 }, 305 { 306 name: "init containers and regular containers when initialized", 307 pods: []*v1.Pod{ 308 { 309 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 310 Spec: v1.PodSpec{ 311 NodeName: "node-one", 312 InitContainers: []v1.Container{ 313 {Resources: v1.ResourceRequirements{ 314 Requests: v1.ResourceList{ 315 "cpu": resource.MustParse("2"), 316 "custom": resource.MustParse("3"), 317 }, 318 Limits: v1.ResourceList{ 319 "memory": resource.MustParse("1G"), 320 "custom": resource.MustParse("5"), 321 }, 322 }}, 323 }, 324 Containers: []v1.Container{ 325 {Resources: v1.ResourceRequirements{ 326 Requests: v1.ResourceList{ 327 "cpu": resource.MustParse("1"), 328 "custom": resource.MustParse("0"), 329 }, 330 Limits: v1.ResourceList{ 331 "memory": resource.MustParse("2G"), 332 "custom": resource.MustParse("6"), 333 }, 334 }}, 335 }, 336 }, 337 Status: v1.PodStatus{ 338 Conditions: []v1.PodCondition{ 339 {Type: v1.PodInitialized, Status: v1.ConditionTrue}, 340 }, 341 }, 342 }, 343 }, 344 expected: ` 345 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 346 # TYPE kube_pod_resource_limit gauge 347 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 6 348 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 2e+09 349 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 350 # TYPE kube_pod_resource_request gauge 351 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 2 352 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 3 353 `, 354 }, 355 { 356 name: "init containers and regular containers when initializing", 357 pods: []*v1.Pod{ 358 { 359 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 360 Spec: v1.PodSpec{ 361 NodeName: "node-one", 362 InitContainers: []v1.Container{ 363 {Resources: v1.ResourceRequirements{ 364 Requests: v1.ResourceList{ 365 "cpu": resource.MustParse("2"), 366 "custom": resource.MustParse("3"), 367 }, 368 Limits: v1.ResourceList{ 369 "memory": resource.MustParse("1G"), 370 "custom": resource.MustParse("5"), 371 }, 372 }}, 373 }, 374 Containers: []v1.Container{ 375 {Resources: v1.ResourceRequirements{ 376 Requests: v1.ResourceList{ 377 "cpu": resource.MustParse("1"), 378 "custom": resource.MustParse("0"), 379 }, 380 Limits: v1.ResourceList{ 381 "memory": resource.MustParse("2G"), 382 "custom": resource.MustParse("6"), 383 }, 384 }}, 385 }, 386 }, 387 Status: v1.PodStatus{ 388 Conditions: []v1.PodCondition{ 389 {Type: "AnotherCondition", Status: v1.ConditionUnknown}, 390 {Type: v1.PodInitialized, Status: v1.ConditionFalse}, 391 }, 392 }, 393 }, 394 }, 395 expected: ` 396 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 397 # TYPE kube_pod_resource_limit gauge 398 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 6 399 kube_pod_resource_limit{namespace="test",node="node-one",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 2e+09 400 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 401 # TYPE kube_pod_resource_request gauge 402 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 2 403 kube_pod_resource_request{namespace="test",node="node-one",pod="foo",priority="",resource="custom",scheduler="",unit=""} 3 404 `, 405 }, 406 { 407 name: "aggregate container requests and limits", 408 pods: []*v1.Pod{ 409 { 410 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 411 Spec: v1.PodSpec{ 412 Containers: []v1.Container{ 413 {Resources: v1.ResourceRequirements{ 414 Requests: v1.ResourceList{"cpu": resource.MustParse("1")}, 415 Limits: v1.ResourceList{"cpu": resource.MustParse("2")}, 416 }}, 417 {Resources: v1.ResourceRequirements{ 418 Requests: v1.ResourceList{"memory": resource.MustParse("1G")}, 419 Limits: v1.ResourceList{"memory": resource.MustParse("2G")}, 420 }}, 421 {Resources: v1.ResourceRequirements{ 422 Requests: v1.ResourceList{"cpu": resource.MustParse("0.5")}, 423 Limits: v1.ResourceList{"cpu": resource.MustParse("1.25")}, 424 }}, 425 {Resources: v1.ResourceRequirements{ 426 Limits: v1.ResourceList{"memory": resource.MustParse("2G")}, 427 }}, 428 }, 429 }, 430 }, 431 }, 432 expected: ` 433 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 434 # TYPE kube_pod_resource_limit gauge 435 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 3.25 436 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 4e+09 437 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 438 # TYPE kube_pod_resource_request gauge 439 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 1.5 440 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 1e+09 441 `, 442 }, 443 { 444 name: "overhead added to requests and limits", 445 pods: []*v1.Pod{ 446 { 447 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 448 Spec: v1.PodSpec{ 449 Overhead: v1.ResourceList{ 450 "cpu": resource.MustParse("0.25"), 451 "memory": resource.MustParse("0.75G"), 452 "custom": resource.MustParse("0.5"), 453 }, 454 InitContainers: []v1.Container{ 455 {Resources: v1.ResourceRequirements{ 456 Requests: v1.ResourceList{ 457 "cpu": resource.MustParse("2"), 458 "custom": resource.MustParse("3"), 459 }, 460 Limits: v1.ResourceList{ 461 "memory": resource.MustParse("1G"), 462 "custom": resource.MustParse("5"), 463 }, 464 }}, 465 }, 466 Containers: []v1.Container{ 467 {Resources: v1.ResourceRequirements{ 468 Requests: v1.ResourceList{ 469 "cpu": resource.MustParse("1"), 470 "custom": resource.MustParse("0"), 471 }, 472 Limits: v1.ResourceList{ 473 "memory": resource.MustParse("2G"), 474 "custom": resource.MustParse("6"), 475 }, 476 }}, 477 }, 478 }, 479 }, 480 }, 481 expected: ` 482 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 483 # TYPE kube_pod_resource_limit gauge 484 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="custom",scheduler="",unit=""} 6.5 485 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 2.75e+09 486 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 487 # TYPE kube_pod_resource_request gauge 488 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="cpu",scheduler="",unit="cores"} 2.25 489 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="custom",scheduler="",unit=""} 3.5 490 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="memory",scheduler="",unit="bytes"} 7.5e+08 491 `, 492 }, 493 { 494 name: "units for standard resources", 495 pods: []*v1.Pod{ 496 { 497 ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo"}, 498 Spec: v1.PodSpec{ 499 Containers: []v1.Container{ 500 {Resources: v1.ResourceRequirements{ 501 Requests: v1.ResourceList{ 502 "storage": resource.MustParse("5"), 503 "ephemeral-storage": resource.MustParse("6"), 504 }, 505 Limits: v1.ResourceList{ 506 "hugepages-x": resource.MustParse("1"), 507 "hugepages-": resource.MustParse("2"), 508 "attachable-volumes-aws": resource.MustParse("3"), 509 "attachable-volumes-": resource.MustParse("4"), 510 }, 511 }}, 512 }, 513 }, 514 }, 515 }, 516 expected: ` 517 # HELP kube_pod_resource_limit [STABLE] Resources limit for workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 518 # TYPE kube_pod_resource_limit gauge 519 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="attachable-volumes-",scheduler="",unit="integer"} 4 520 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="attachable-volumes-aws",scheduler="",unit="integer"} 3 521 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="hugepages-",scheduler="",unit="bytes"} 2 522 kube_pod_resource_limit{namespace="test",node="",pod="foo",priority="",resource="hugepages-x",scheduler="",unit="bytes"} 1 523 # HELP kube_pod_resource_request [STABLE] Resources requested by workloads on the cluster, broken down by pod. This shows the resource usage the scheduler and kubelet expect per pod for resources along with the unit for the resource if any. 524 # TYPE kube_pod_resource_request gauge 525 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="ephemeral-storage",scheduler="",unit="bytes"} 6 526 kube_pod_resource_request{namespace="test",node="",pod="foo",priority="",resource="storage",scheduler="",unit="bytes"} 5 527 `, 528 }, 529 } 530 for _, tt := range tests { 531 t.Run(tt.name, func(t *testing.T) { 532 c := NewPodResourcesMetricsCollector(&fakePodLister{pods: tt.pods}) 533 registry := metrics.NewKubeRegistry() 534 registry.CustomMustRegister(c) 535 err := testutil.GatherAndCompare(registry, strings.NewReader(tt.expected)) 536 if err != nil { 537 t.Fatal(err) 538 } 539 }) 540 } 541 }