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  }