github.com/timstclair/heapster@v0.20.0-alpha1/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 "encoding/json" 18 "net/http/httptest" 19 "strconv" 20 "strings" 21 "testing" 22 "time" 23 24 cadvisor_api "github.com/google/cadvisor/info/v1" 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 "k8s.io/heapster/metrics/core" 28 kube_api "k8s.io/kubernetes/pkg/api" 29 "k8s.io/kubernetes/pkg/util" 30 ) 31 32 func TestDecodeMetrics1(t *testing.T) { 33 kMS := kubeletMetricsSource{ 34 nodename: "test", 35 hostname: "test-hostname", 36 cpuLastVal: make(map[string]cpuVal), 37 } 38 c1 := cadvisor_api.ContainerInfo{ 39 ContainerReference: cadvisor_api.ContainerReference{ 40 Name: "/", 41 }, 42 Spec: cadvisor_api.ContainerSpec{ 43 CreationTime: time.Now(), 44 HasCpu: true, 45 }, 46 Stats: []*cadvisor_api.ContainerStats{ 47 { 48 Timestamp: time.Now(), 49 Cpu: cadvisor_api.CpuStats{ 50 Usage: cadvisor_api.CpuUsage{ 51 Total: 100, 52 PerCpu: []uint64{5, 10}, 53 User: 1, 54 System: 1, 55 }, 56 LoadAverage: 20, 57 }, 58 }, 59 }, 60 } 61 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 62 assert.Equal(t, metricSetKey, "node:test") 63 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 64 } 65 66 func TestDecodeMetrics2(t *testing.T) { 67 kMS := kubeletMetricsSource{ 68 nodename: "test", 69 hostname: "test-hostname", 70 cpuLastVal: make(map[string]cpuVal), 71 } 72 kMS.cpuLastVal["node:test"] = cpuVal{ 73 Val: 100, 74 Timestamp: time.Now(), 75 } 76 c1 := cadvisor_api.ContainerInfo{ 77 ContainerReference: cadvisor_api.ContainerReference{ 78 Name: "/", 79 }, 80 Spec: cadvisor_api.ContainerSpec{ 81 CreationTime: time.Now(), 82 HasCpu: true, 83 }, 84 Stats: []*cadvisor_api.ContainerStats{ 85 { 86 Timestamp: time.Now(), 87 Cpu: cadvisor_api.CpuStats{ 88 Usage: cadvisor_api.CpuUsage{ 89 Total: 100, 90 PerCpu: []uint64{5, 10}, 91 User: 1, 92 System: 1, 93 }, 94 LoadAverage: 20, 95 }, 96 }, 97 }, 98 } 99 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 100 assert.Equal(t, metricSetKey, "node:test") 101 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 102 } 103 104 func TestDecodeMetrics3(t *testing.T) { 105 kMS := kubeletMetricsSource{ 106 nodename: "test", 107 hostname: "test-hostname", 108 cpuLastVal: make(map[string]cpuVal), 109 } 110 c1 := cadvisor_api.ContainerInfo{ 111 ContainerReference: cadvisor_api.ContainerReference{ 112 Name: "/docker-daemon", 113 }, 114 Spec: cadvisor_api.ContainerSpec{ 115 CreationTime: time.Now(), 116 HasCpu: true, 117 }, 118 Stats: []*cadvisor_api.ContainerStats{ 119 { 120 Timestamp: time.Now(), 121 Cpu: cadvisor_api.CpuStats{ 122 Usage: cadvisor_api.CpuUsage{ 123 Total: 100, 124 PerCpu: []uint64{5, 10}, 125 User: 1, 126 System: 1, 127 }, 128 LoadAverage: 20, 129 }, 130 }, 131 }, 132 } 133 metricSetKey, _ := kMS.decodeMetrics(&c1) 134 assert.Equal(t, metricSetKey, "node:test/container:docker-daemon") 135 } 136 137 func TestDecodeMetrics4(t *testing.T) { 138 kMS := kubeletMetricsSource{ 139 nodename: "test", 140 hostname: "test-hostname", 141 cpuLastVal: make(map[string]cpuVal), 142 } 143 c1 := cadvisor_api.ContainerInfo{ 144 ContainerReference: cadvisor_api.ContainerReference{ 145 Name: "testKubelet", 146 }, 147 Spec: cadvisor_api.ContainerSpec{ 148 CreationTime: time.Now(), 149 HasCpu: true, 150 Labels: make(map[string]string), 151 }, 152 Stats: []*cadvisor_api.ContainerStats{ 153 { 154 Timestamp: time.Now(), 155 Cpu: cadvisor_api.CpuStats{ 156 Usage: cadvisor_api.CpuUsage{ 157 Total: 100, 158 PerCpu: []uint64{5, 10}, 159 User: 1, 160 System: 1, 161 }, 162 LoadAverage: 20, 163 }, 164 }, 165 }, 166 } 167 168 c1.Spec.Labels[kubernetesContainerLabel] = "testContainer" 169 c1.Spec.Labels[kubernetesPodNamespaceLabel] = "testPodNS" 170 c1.Spec.Labels[kubernetesPodNameLabel] = "testPodName" 171 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 172 assert.Equal(t, metricSetKey, "namespace:testPodNS/pod:testPodName/container:testContainer") 173 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePodContainer) 174 } 175 176 func TestDecodeMetrics5(t *testing.T) { 177 kMS := kubeletMetricsSource{ 178 nodename: "test", 179 hostname: "test-hostname", 180 cpuLastVal: make(map[string]cpuVal), 181 } 182 c1 := cadvisor_api.ContainerInfo{ 183 ContainerReference: cadvisor_api.ContainerReference{ 184 Name: "k8s_test.testkubelet", 185 }, 186 Spec: cadvisor_api.ContainerSpec{ 187 CreationTime: time.Now(), 188 HasCpu: true, 189 Labels: make(map[string]string), 190 }, 191 Stats: []*cadvisor_api.ContainerStats{ 192 { 193 Timestamp: time.Now(), 194 Cpu: cadvisor_api.CpuStats{ 195 Usage: cadvisor_api.CpuUsage{ 196 Total: 100, 197 PerCpu: []uint64{5, 10}, 198 User: 1, 199 System: 1, 200 }, 201 LoadAverage: 20, 202 }, 203 }, 204 }, 205 } 206 c1.Spec.Labels[kubernetesContainerLabel] = "POD" 207 c1.Spec.Labels[kubernetesPodNameLabel] = "testnamespace/testPodName" 208 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 209 assert.Equal(t, metricSetKey, "namespace:testnamespace/pod:testPodName") 210 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePod) 211 212 c1.Spec.Labels[kubernetesContainerLabel] = "" 213 c1.Spec.Labels[kubernetesPodNameLabel] = "testnamespace/testPodName" 214 metricSetKey, metricSet = kMS.decodeMetrics(&c1) 215 assert.Equal(t, metricSetKey, "namespace:testnamespace/pod:testPodName/container:test") 216 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypePodContainer) 217 } 218 219 func TestDecodeMetrics6(t *testing.T) { 220 kMS := kubeletMetricsSource{ 221 nodename: "test", 222 hostname: "test-hostname", 223 cpuLastVal: make(map[string]cpuVal), 224 } 225 c1 := cadvisor_api.ContainerInfo{ 226 ContainerReference: cadvisor_api.ContainerReference{ 227 Name: "/", 228 }, 229 Spec: cadvisor_api.ContainerSpec{ 230 CreationTime: time.Now(), 231 HasCustomMetrics: true, 232 CustomMetrics: []cadvisor_api.MetricSpec{ 233 { 234 Name: "test1", 235 Type: cadvisor_api.MetricGauge, 236 Format: cadvisor_api.IntType, 237 }, 238 { 239 Name: "test2", 240 Type: cadvisor_api.MetricCumulative, 241 Format: cadvisor_api.IntType, 242 }, 243 { 244 Name: "test3", 245 Type: cadvisor_api.MetricGauge, 246 Format: cadvisor_api.FloatType, 247 }, 248 { 249 Name: "test4", 250 Type: cadvisor_api.MetricCumulative, 251 Format: cadvisor_api.FloatType, 252 }, 253 }, 254 }, 255 Stats: []*cadvisor_api.ContainerStats{ 256 { 257 Timestamp: time.Now(), 258 Cpu: cadvisor_api.CpuStats{ 259 Usage: cadvisor_api.CpuUsage{ 260 Total: 100, 261 PerCpu: []uint64{5, 10}, 262 User: 1, 263 System: 1, 264 }, 265 LoadAverage: 20, 266 }, 267 CustomMetrics: map[string][]cadvisor_api.MetricVal{ 268 "test1": []cadvisor_api.MetricVal{ 269 { 270 Label: "test1", 271 Timestamp: time.Now(), 272 IntValue: 1, 273 FloatValue: 1.0, 274 }, 275 }, 276 "test2": []cadvisor_api.MetricVal{ 277 { 278 Label: "test2", 279 Timestamp: time.Now(), 280 IntValue: 1, 281 FloatValue: 1.0, 282 }, 283 }, 284 "test3": []cadvisor_api.MetricVal{ 285 { 286 Label: "test3", 287 Timestamp: time.Now(), 288 IntValue: 1, 289 FloatValue: 1.0, 290 }, 291 }, 292 "test4": []cadvisor_api.MetricVal{ 293 { 294 Label: "test4", 295 Timestamp: time.Now(), 296 IntValue: 1, 297 FloatValue: 1.0, 298 }, 299 }, 300 }, 301 }, 302 }, 303 } 304 metricSetKey, metricSet := kMS.decodeMetrics(&c1) 305 assert.Equal(t, metricSetKey, "node:test") 306 assert.Equal(t, metricSet.Labels[core.LabelMetricSetType.Key], core.MetricSetTypeNode) 307 } 308 309 func TestGetNodeHostnameAndIP(t *testing.T) { 310 var node = kube_api.Node{ 311 Status: kube_api.NodeStatus{ 312 Conditions: []kube_api.NodeCondition{ 313 { 314 Type: kube_api.NodeReady, 315 Status: kube_api.ConditionFalse, 316 }, 317 }, 318 }, 319 } 320 _, _, err := getNodeHostnameAndIP(&node) 321 322 node = kube_api.Node{ 323 Status: kube_api.NodeStatus{ 324 Conditions: []kube_api.NodeCondition{ 325 { 326 Type: "NotReady", 327 Status: kube_api.ConditionTrue, 328 }, 329 }, 330 Addresses: []kube_api.NodeAddress{ 331 { 332 Type: kube_api.NodeHostName, 333 Address: "testNode", 334 }, 335 { 336 Type: kube_api.NodeInternalIP, 337 Address: "127.0.0.1", 338 }, 339 }, 340 }, 341 } 342 node.Name = "testNode" 343 hostname, ip, err := getNodeHostnameAndIP(&node) 344 assert.NoError(t, err) 345 assert.Equal(t, hostname, "testNode") 346 assert.Equal(t, ip, "127.0.0.1") 347 348 } 349 350 func TestScrapeMetrics(t *testing.T) { 351 rootContainer := cadvisor_api.ContainerInfo{ 352 ContainerReference: cadvisor_api.ContainerReference{ 353 Name: "/", 354 }, 355 Spec: cadvisor_api.ContainerSpec{ 356 CreationTime: time.Now(), 357 HasCpu: true, 358 HasMemory: true, 359 }, 360 Stats: []*cadvisor_api.ContainerStats{ 361 { 362 Timestamp: time.Now(), 363 }, 364 }, 365 } 366 367 subcontainer := cadvisor_api.ContainerInfo{ 368 ContainerReference: cadvisor_api.ContainerReference{ 369 Name: "/docker-daemon", 370 }, 371 Spec: cadvisor_api.ContainerSpec{ 372 CreationTime: time.Now(), 373 HasCpu: true, 374 HasMemory: true, 375 }, 376 Stats: []*cadvisor_api.ContainerStats{ 377 { 378 Timestamp: time.Now(), 379 }, 380 }, 381 } 382 response := map[string]cadvisor_api.ContainerInfo{ 383 rootContainer.Name: { 384 ContainerReference: cadvisor_api.ContainerReference{ 385 Name: rootContainer.Name, 386 }, 387 Spec: rootContainer.Spec, 388 Stats: []*cadvisor_api.ContainerStats{ 389 rootContainer.Stats[0], 390 }, 391 }, 392 subcontainer.Name: { 393 ContainerReference: cadvisor_api.ContainerReference{ 394 Name: subcontainer.Name, 395 }, 396 Spec: subcontainer.Spec, 397 Stats: []*cadvisor_api.ContainerStats{ 398 subcontainer.Stats[0], 399 }, 400 }, 401 } 402 data, err := json.Marshal(&response) 403 require.NoError(t, err) 404 handler := util.FakeHandler{ 405 StatusCode: 200, 406 RequestBody: "", 407 ResponseBody: string(data), 408 T: t, 409 } 410 server := httptest.NewServer(&handler) 411 defer server.Close() 412 413 var client KubeletClient 414 415 mtrcSrc := kubeletMetricsSource{ 416 kubeletClient: &client, 417 cpuLastVal: make(map[string]cpuVal), 418 } 419 420 split := strings.SplitN(strings.Replace(server.URL, "http://", "", 1), ":", 2) 421 mtrcSrc.host.IP = split[0] 422 mtrcSrc.host.Port, err = strconv.Atoi(split[1]) 423 424 start := time.Now() 425 end := start.Add(5 * time.Second) 426 res := mtrcSrc.ScrapeMetrics(start, end) 427 assert.Equal(t, res.MetricSets["node:/container:docker-daemon"].Labels["type"], "sys_container") 428 assert.Equal(t, res.MetricSets["node:/container:docker-daemon"].Labels["container_name"], "docker-daemon") 429 430 }