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  }