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