github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/metrics/sources/kubelet/kubelet_test.go (about) 1 // Copyright 2014 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package kubelet 15 16 import ( 17 "net" 18 "net/http/httptest" 19 "strconv" 20 "strings" 21 "testing" 22 "time" 23 24 cadvisor_api "github.com/google/cadvisor/info/v1" 25 jsoniter "github.com/json-iterator/go" 26 "github.com/stretchr/testify/assert" 27 "github.com/stretchr/testify/require" 28 kube_api "k8s.io/api/core/v1" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 util "k8s.io/client-go/util/testing" 31 "k8s.io/heapster/metrics/core" 32 ) 33 34 func TestDecodeMetrics1(t *testing.T) { 35 kMS := kubeletMetricsSource{ 36 nodename: "test", 37 hostname: "test-hostname", 38 } 39 c1 := cadvisor_api.ContainerInfo{ 40 ContainerReference: cadvisor_api.ContainerReference{ 41 Name: "/", 42 }, 43 Spec: cadvisor_api.ContainerSpec{ 44 CreationTime: time.Now(), 45 HasCpu: true, 46 }, 47 Stats: []*cadvisor_api.ContainerStats{ 48 { 49 Timestamp: time.Now(), 50 Cpu: cadvisor_api.CpuStats{ 51 Usage: cadvisor_api.CpuUsage{ 52 Total: 100, 53 PerCpu: []uint64{5, 10}, 54 User: 1, 55 System: 1, 56 }, 57 LoadAverage: 20, 58 }, 59 }, 60 }, 61 } 62 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 63 assert.Equal(t, metricSetKey, "node:test") 64 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 65 } 66 67 func TestDecodeMetrics2(t *testing.T) { 68 kMS := kubeletMetricsSource{ 69 nodename: "test", 70 hostname: "test-hostname", 71 } 72 c1 := cadvisor_api.ContainerInfo{ 73 ContainerReference: cadvisor_api.ContainerReference{ 74 Name: "/", 75 }, 76 Spec: cadvisor_api.ContainerSpec{ 77 CreationTime: time.Now(), 78 HasCpu: true, 79 }, 80 Stats: []*cadvisor_api.ContainerStats{ 81 { 82 Timestamp: time.Now(), 83 Cpu: cadvisor_api.CpuStats{ 84 Usage: cadvisor_api.CpuUsage{ 85 Total: 100, 86 PerCpu: []uint64{5, 10}, 87 User: 1, 88 System: 1, 89 }, 90 LoadAverage: 20, 91 }, 92 }, 93 }, 94 } 95 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 96 assert.Equal(t, metricSetKey, "node:test") 97 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 98 } 99 100 func TestDecodeMetrics3(t *testing.T) { 101 kMS := kubeletMetricsSource{ 102 nodename: "test", 103 hostname: "test-hostname", 104 } 105 c1 := cadvisor_api.ContainerInfo{ 106 ContainerReference: cadvisor_api.ContainerReference{ 107 Name: "/docker-daemon", 108 }, 109 Spec: cadvisor_api.ContainerSpec{ 110 CreationTime: time.Now(), 111 HasCpu: true, 112 }, 113 Stats: []*cadvisor_api.ContainerStats{ 114 { 115 Timestamp: time.Now(), 116 Cpu: cadvisor_api.CpuStats{ 117 Usage: cadvisor_api.CpuUsage{ 118 Total: 100, 119 PerCpu: []uint64{5, 10}, 120 User: 1, 121 System: 1, 122 }, 123 LoadAverage: 20, 124 }, 125 }, 126 }, 127 } 128 metricSetKey, _ := kMS.decodeMetrics(&c1) 129 assert.Equal(t, metricSetKey, "node:test/container:docker-daemon") 130 } 131 132 func TestDecodeMetrics4(t *testing.T) { 133 kMS := kubeletMetricsSource{ 134 nodename: "test", 135 hostname: "test-hostname", 136 } 137 c1 := cadvisor_api.ContainerInfo{ 138 ContainerReference: cadvisor_api.ContainerReference{ 139 Name: "testKubelet", 140 }, 141 Spec: cadvisor_api.ContainerSpec{ 142 CreationTime: time.Now(), 143 HasCpu: true, 144 Labels: make(map[string]string), 145 }, 146 Stats: []*cadvisor_api.ContainerStats{ 147 { 148 Timestamp: time.Now(), 149 Cpu: cadvisor_api.CpuStats{ 150 Usage: cadvisor_api.CpuUsage{ 151 Total: 100, 152 PerCpu: []uint64{5, 10}, 153 User: 1, 154 System: 1, 155 }, 156 LoadAverage: 20, 157 }, 158 }, 159 }, 160 } 161 162 c1.Spec.Labels[kubernetesContainerLabel] = "testContainer" 163 c1.Spec.Labels[kubernetesPodNamespaceLabel] = "testPodNS" 164 c1.Spec.Labels[kubernetesPodNameLabel] = "testPodName" 165 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 166 assert.Equal(t, metricSetKey, "namespace:testPodNS/pod:testPodName/container:testContainer") 167 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePodContainer) 168 } 169 170 func TestDecodeMetrics5(t *testing.T) { 171 kMS := kubeletMetricsSource{ 172 nodename: "test", 173 hostname: "test-hostname", 174 } 175 c1 := cadvisor_api.ContainerInfo{ 176 ContainerReference: cadvisor_api.ContainerReference{ 177 Name: "k8s_test.testkubelet", 178 }, 179 Spec: cadvisor_api.ContainerSpec{ 180 CreationTime: time.Now(), 181 HasCpu: true, 182 Labels: make(map[string]string), 183 }, 184 Stats: []*cadvisor_api.ContainerStats{ 185 { 186 Timestamp: time.Now(), 187 Cpu: cadvisor_api.CpuStats{ 188 Usage: cadvisor_api.CpuUsage{ 189 Total: 100, 190 PerCpu: []uint64{5, 10}, 191 User: 1, 192 System: 1, 193 }, 194 LoadAverage: 20, 195 }, 196 }, 197 }, 198 } 199 c1.Spec.Labels[kubernetesContainerLabel] = "POD" 200 c1.Spec.Labels[kubernetesPodNameLabel] = "testnamespace/testPodName" 201 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 202 assert.Equal(t, metricSetKey, "namespace:testnamespace/pod:testPodName") 203 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePod) 204 205 c1.Spec.Labels[kubernetesContainerLabel] = "" 206 c1.Spec.Labels[kubernetesPodNameLabel] = "testnamespace/testPodName" 207 metricSetKey, metricSet = kMS.decodeMetrics(&c1) 208 assert.Equal(t, metricSetKey, "namespace:testnamespace/pod:testPodName/container:test") 209 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePodContainer) 210 } 211 212 func TestDecodeMetrics6(t *testing.T) { 213 kMS := kubeletMetricsSource{ 214 nodename: "test", 215 hostname: "test-hostname", 216 } 217 c1 := cadvisor_api.ContainerInfo{ 218 ContainerReference: cadvisor_api.ContainerReference{ 219 Name: "/", 220 }, 221 Spec: cadvisor_api.ContainerSpec{ 222 CreationTime: time.Now(), 223 HasCustomMetrics: true, 224 CustomMetrics: []cadvisor_api.MetricSpec{ 225 { 226 Name: "test1", 227 Type: cadvisor_api.MetricGauge, 228 Format: cadvisor_api.IntType, 229 }, 230 { 231 Name: "test2", 232 Type: cadvisor_api.MetricCumulative, 233 Format: cadvisor_api.IntType, 234 }, 235 { 236 Name: "test3", 237 Type: cadvisor_api.MetricGauge, 238 Format: cadvisor_api.FloatType, 239 }, 240 { 241 Name: "test4", 242 Type: cadvisor_api.MetricCumulative, 243 Format: cadvisor_api.FloatType, 244 }, 245 }, 246 }, 247 Stats: []*cadvisor_api.ContainerStats{ 248 { 249 Timestamp: time.Now(), 250 Cpu: cadvisor_api.CpuStats{ 251 Usage: cadvisor_api.CpuUsage{ 252 Total: 100, 253 PerCpu: []uint64{5, 10}, 254 User: 1, 255 System: 1, 256 }, 257 LoadAverage: 20, 258 }, 259 CustomMetrics: map[string][]cadvisor_api.MetricVal{ 260 "test1": { 261 { 262 Label: "test1", 263 Timestamp: time.Now(), 264 IntValue: 1, 265 FloatValue: 1.0, 266 }, 267 }, 268 "test2": { 269 { 270 Label: "test2", 271 Timestamp: time.Now(), 272 IntValue: 1, 273 FloatValue: 1.0, 274 }, 275 }, 276 "test3": { 277 { 278 Label: "test3", 279 Timestamp: time.Now(), 280 IntValue: 1, 281 FloatValue: 1.0, 282 }, 283 }, 284 "test4": { 285 { 286 Label: "test4", 287 Timestamp: time.Now(), 288 IntValue: 1, 289 FloatValue: 1.0, 290 }, 291 }, 292 }, 293 }, 294 }, 295 } 296 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 297 assert.Equal(t, metricSetKey, "node:test") 298 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 299 } 300 301 var nodes = []kube_api.Node{ 302 { 303 ObjectMeta: metav1.ObjectMeta{ 304 Name: "testNode", 305 }, 306 Status: kube_api.NodeStatus{ 307 Conditions: []kube_api.NodeCondition{ 308 { 309 Type: "NotReady", 310 Status: kube_api.ConditionTrue, 311 }, 312 }, 313 Addresses: []kube_api.NodeAddress{ 314 { 315 Type: kube_api.NodeHostName, 316 Address: "testNode", 317 }, 318 { 319 Type: kube_api.NodeInternalIP, 320 Address: "127.0.0.1", 321 }, 322 }, 323 }, 324 }, 325 { 326 ObjectMeta: metav1.ObjectMeta{ 327 Name: "testNode", 328 }, 329 Status: kube_api.NodeStatus{ 330 Conditions: []kube_api.NodeCondition{ 331 { 332 Type: "NotReady", 333 Status: kube_api.ConditionTrue, 334 }, 335 }, 336 Addresses: []kube_api.NodeAddress{ 337 { 338 Type: kube_api.NodeHostName, 339 Address: "testNode", 340 }, 341 { 342 Type: kube_api.NodeInternalIP, 343 Address: "127.0.0.1", 344 }, 345 }, 346 }, 347 }, 348 { 349 ObjectMeta: metav1.ObjectMeta{ 350 Name: "testNode", 351 }, 352 Status: kube_api.NodeStatus{ 353 Conditions: []kube_api.NodeCondition{ 354 { 355 Type: "NotReady", 356 Status: kube_api.ConditionTrue, 357 }, 358 }, 359 Addresses: []kube_api.NodeAddress{ 360 { 361 Type: kube_api.NodeHostName, 362 Address: "testNode", 363 }, 364 { 365 Type: kube_api.NodeInternalIP, 366 Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", 367 }, 368 { 369 Type: kube_api.NodeInternalIP, 370 Address: "127.0.0.1", 371 }, 372 }, 373 }, 374 }, 375 { 376 ObjectMeta: metav1.ObjectMeta{ 377 Name: "testNode", 378 }, 379 Status: kube_api.NodeStatus{ 380 Conditions: []kube_api.NodeCondition{ 381 { 382 Type: "NotReady", 383 Status: kube_api.ConditionTrue, 384 }, 385 }, 386 Addresses: []kube_api.NodeAddress{ 387 { 388 Type: kube_api.NodeHostName, 389 Address: "testNode", 390 }, 391 { 392 Type: kube_api.NodeExternalIP, 393 Address: "127.0.0.1", 394 }, 395 }, 396 }, 397 }, 398 } 399 400 func TestGetNodeHostnameAndIP(t *testing.T) { 401 for _, node := range nodes { 402 hostname, ip, err := GetNodeHostnameAndIP(&node) 403 assert.NoError(t, err) 404 assert.Equal(t, hostname, "testNode") 405 assert.True(t, ip.Equal(net.ParseIP("127.0.0.1"))) 406 } 407 } 408 409 func TestScrapeMetrics(t *testing.T) { 410 rootContainer := cadvisor_api.ContainerInfo{ 411 ContainerReference: cadvisor_api.ContainerReference{ 412 Name: "/", 413 }, 414 Spec: cadvisor_api.ContainerSpec{ 415 CreationTime: time.Now(), 416 HasCpu: true, 417 HasMemory: true, 418 }, 419 Stats: []*cadvisor_api.ContainerStats{ 420 { 421 Timestamp: time.Now(), 422 }, 423 }, 424 } 425 426 subcontainer := cadvisor_api.ContainerInfo{ 427 ContainerReference: cadvisor_api.ContainerReference{ 428 Name: "/docker-daemon", 429 }, 430 Spec: cadvisor_api.ContainerSpec{ 431 CreationTime: time.Now(), 432 HasCpu: true, 433 HasMemory: true, 434 }, 435 Stats: []*cadvisor_api.ContainerStats{ 436 { 437 Timestamp: time.Now(), 438 }, 439 }, 440 } 441 response := map[string]cadvisor_api.ContainerInfo{ 442 rootContainer.Name: { 443 ContainerReference: cadvisor_api.ContainerReference{ 444 Name: rootContainer.Name, 445 }, 446 Spec: rootContainer.Spec, 447 Stats: []*cadvisor_api.ContainerStats{ 448 rootContainer.Stats[0], 449 }, 450 }, 451 subcontainer.Name: { 452 ContainerReference: cadvisor_api.ContainerReference{ 453 Name: subcontainer.Name, 454 }, 455 Spec: subcontainer.Spec, 456 Stats: []*cadvisor_api.ContainerStats{ 457 subcontainer.Stats[0], 458 }, 459 }, 460 } 461 data, err := jsoniter.ConfigFastest.Marshal(&response) 462 require.NoError(t, err) 463 handler := util.FakeHandler{ 464 StatusCode: 200, 465 RequestBody: "", 466 ResponseBody: string(data), 467 T: t, 468 } 469 server := httptest.NewServer(&handler) 470 defer server.Close() 471 472 var client KubeletClient 473 474 mtrcSrc := kubeletMetricsSource{ 475 kubeletClient: &client, 476 } 477 478 split := strings.SplitN(strings.Replace(server.URL, "http://", "", 1), ":", 2) 479 mtrcSrc.host.IP = net.ParseIP(split[0]) 480 mtrcSrc.host.Port, err = strconv.Atoi(split[1]) 481 482 start := time.Now() 483 end := start.Add(5 * time.Second) 484 res, err := mtrcSrc.ScrapeMetrics(start, end) 485 assert.Nil(t, err, "scrape error") 486 assert.Equal(t, res.MetricSets["node:/container:docker-daemon"].Labels["type"], "sys_container") 487 assert.Equal(t, res.MetricSets["node:/container:docker-daemon"].Labels["container_name"], "docker-daemon") 488 489 } 490 491 func TestGetNodeSchedulableStatus(t *testing.T) { 492 metas := []struct { 493 Node *kube_api.Node 494 Wanted string 495 }{ 496 { 497 Node: &kube_api.Node{ 498 Spec: kube_api.NodeSpec{ 499 Unschedulable: false, 500 }, 501 }, 502 Wanted: "true", 503 }, 504 { 505 Node: &kube_api.Node{ 506 Spec: kube_api.NodeSpec{ 507 Unschedulable: true, 508 }, 509 }, 510 Wanted: "false", 511 }, 512 } 513 514 for _, meta := range metas { 515 got := getNodeSchedulableStatus(meta.Node) 516 if got != meta.Wanted { 517 t.Errorf("get node schedulable status error. wanted: %s, got: %s", meta.Wanted, got) 518 } 519 } 520 }