github.com/galamsiva2020/kubernetes-heapster-monitoring@v0.0.0-20210823134957-3c1baa7c1e70/metrics/sinks/stackdriver/stackdriver_test.go (about)

     1  // Copyright 2015 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  
    15  package stackdriver
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
    23  	"k8s.io/heapster/metrics/core"
    24  )
    25  
    26  var (
    27  	testProjectId = "test-project-id"
    28  	zone          = "europe-west1-c"
    29  
    30  	sink = &StackdriverSink{
    31  		project:           testProjectId,
    32  		heapsterZone:      zone,
    33  		stackdriverClient: nil,
    34  	}
    35  
    36  	commonLabels     = map[string]string{}
    37  	containerLabels  = map[string]string{"type": "pod_container"}
    38  	podLabels        = map[string]string{"type": "pod"}
    39  	nodeLabels       = map[string]string{"type": "node"}
    40  	nodeDaemonLabels = map[string]string{"type": "sys_container", "container_name": "kubelet"}
    41  )
    42  
    43  func generateIntMetric(value int64) core.MetricValue {
    44  	return core.MetricValue{
    45  		ValueType: core.ValueInt64,
    46  		IntValue:  value,
    47  	}
    48  }
    49  
    50  func generateLabeledIntMetric(value int64, labels map[string]string, name string) core.LabeledMetric {
    51  	return core.LabeledMetric{
    52  		Name:        name,
    53  		Labels:      labels,
    54  		MetricValue: generateIntMetric(value),
    55  	}
    56  }
    57  
    58  func generateFloatMetric(value float64) core.MetricValue {
    59  	return core.MetricValue{
    60  		ValueType:  core.ValueFloat,
    61  		FloatValue: value,
    62  	}
    63  }
    64  
    65  func deepCopy(source map[string]string) map[string]string {
    66  	result := map[string]string{}
    67  	for k, v := range source {
    68  		result[k] = v
    69  	}
    70  	return result
    71  }
    72  
    73  // Test TranslateMetric
    74  
    75  func testLegacyTranslateMetric(as *assert.Assertions, value int64, name string, labels map[string]string, expectedName string) *monitoringpb.TypedValue {
    76  	metricValue := generateIntMetric(value)
    77  	timestamp := time.Now()
    78  	collectionStartTime := timestamp.Add(-time.Second)
    79  
    80  	ts := sink.LegacyTranslateMetric(timestamp, labels, name, metricValue, collectionStartTime)
    81  
    82  	as.NotNil(ts)
    83  	as.Equal(ts.Metric.Type, expectedName)
    84  	as.Equal(len(ts.Points), 1)
    85  	return ts.Points[0].Value
    86  }
    87  
    88  func testTranslateMetric(as *assert.Assertions, value core.MetricValue, labels map[string]string, name string, expectedName string) *monitoringpb.TypedValue {
    89  	timestamp := time.Now()
    90  	collectionStartTime := timestamp.Add(-time.Second)
    91  	entityCreateTime := timestamp.Add(-time.Second)
    92  
    93  	ts := sink.TranslateMetric(timestamp, labels, name, value, collectionStartTime, entityCreateTime)
    94  
    95  	as.NotNil(ts)
    96  	as.Equal(ts.Metric.Type, expectedName)
    97  	as.Equal(len(ts.Points), 1)
    98  	return ts.Points[0].Value
    99  }
   100  
   101  func testTranslateLabeledMetric(as *assert.Assertions, labels map[string]string, metric core.LabeledMetric, expectedName string) *monitoringpb.TypedValue {
   102  	timestamp := time.Now()
   103  	collectionStartTime := timestamp.Add(-time.Second)
   104  
   105  	ts := sink.TranslateLabeledMetric(timestamp, labels, metric, collectionStartTime)
   106  
   107  	as.NotNil(ts)
   108  	as.Equal(ts.Metric.Type, expectedName)
   109  	as.Equal(len(ts.Points), 1)
   110  	return ts.Points[0].Value
   111  }
   112  
   113  func TestTranslateUptime(t *testing.T) {
   114  	as := assert.New(t)
   115  	value := testLegacyTranslateMetric(as, 30000, "uptime", commonLabels,
   116  		"container.googleapis.com/container/uptime")
   117  
   118  	as.Equal(30.0, value.GetDoubleValue())
   119  }
   120  
   121  func TestTranslateCpuUsage(t *testing.T) {
   122  	as := assert.New(t)
   123  	value := testLegacyTranslateMetric(as, 3600000000000, "cpu/usage", commonLabels,
   124  		"container.googleapis.com/container/cpu/usage_time")
   125  
   126  	as.Equal(3600.0, value.GetDoubleValue())
   127  }
   128  
   129  func TestTranslateCpuLimit(t *testing.T) {
   130  	as := assert.New(t)
   131  	value := testLegacyTranslateMetric(as, 2000, "cpu/limit", commonLabels,
   132  		"container.googleapis.com/container/cpu/reserved_cores")
   133  
   134  	as.Equal(2.0, value.GetDoubleValue())
   135  }
   136  
   137  func TestTranslateMemoryLimitNode(t *testing.T) {
   138  	metricValue := generateIntMetric(2048)
   139  	name := "memory/limit"
   140  	timestamp := time.Now()
   141  
   142  	labels := deepCopy(commonLabels)
   143  	labels["type"] = core.MetricSetTypeNode
   144  
   145  	ts := sink.LegacyTranslateMetric(timestamp, labels, name, metricValue, timestamp)
   146  	var expected *monitoringpb.TimeSeries = nil
   147  
   148  	as := assert.New(t)
   149  	as.Equal(ts, expected)
   150  }
   151  
   152  func TestTranslateMemoryLimitPod(t *testing.T) {
   153  	as := assert.New(t)
   154  	labels := deepCopy(commonLabels)
   155  	labels["type"] = core.MetricSetTypePod
   156  	value := testLegacyTranslateMetric(as, 2048, "memory/limit", labels,
   157  		"container.googleapis.com/container/memory/bytes_total")
   158  
   159  	as.Equal(int64(2048), value.GetInt64Value())
   160  }
   161  
   162  func TestTranslateMemoryNodeAllocatable(t *testing.T) {
   163  	as := assert.New(t)
   164  	value := testLegacyTranslateMetric(as, 2048, "memory/node_allocatable", commonLabels,
   165  		"container.googleapis.com/container/memory/bytes_total")
   166  
   167  	as.Equal(int64(2048), value.GetInt64Value())
   168  }
   169  
   170  func TestTranslateMemoryUsedEvictable(t *testing.T) {
   171  	metricValue := generateIntMetric(100)
   172  	name := "memory/bytes_used"
   173  	timestamp := time.Now()
   174  	collectionStartTime := timestamp.Add(-time.Second)
   175  
   176  	ts := sink.LegacyTranslateMetric(timestamp, commonLabels, name, metricValue, collectionStartTime)
   177  
   178  	as := assert.New(t)
   179  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/memory/bytes_used")
   180  	as.Equal(len(ts.Points), 1)
   181  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(100))
   182  	as.Equal(ts.Metric.Labels["memory_type"], "evictable")
   183  }
   184  
   185  func TestTranslateMemoryUsedNonEvictable(t *testing.T) {
   186  	metricValue := generateIntMetric(200)
   187  	name := core.MetricMemoryWorkingSet.MetricDescriptor.Name
   188  	timestamp := time.Now()
   189  	collectionStartTime := timestamp.Add(-time.Second)
   190  
   191  	ts := sink.LegacyTranslateMetric(timestamp, commonLabels, name, metricValue, collectionStartTime)
   192  
   193  	as := assert.New(t)
   194  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/memory/bytes_used")
   195  	as.Equal(len(ts.Points), 1)
   196  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(200))
   197  	as.Equal(ts.Metric.Labels["memory_type"], "non-evictable")
   198  }
   199  
   200  func TestTranslateMemoryMajorPageFaults(t *testing.T) {
   201  	metricValue := generateIntMetric(20)
   202  	name := "memory/major_page_faults"
   203  	timestamp := time.Now()
   204  	collectionStartTime := timestamp.Add(-time.Second)
   205  
   206  	ts := sink.LegacyTranslateMetric(timestamp, commonLabels, name, metricValue, collectionStartTime)
   207  
   208  	as := assert.New(t)
   209  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/memory/page_fault_count")
   210  	as.Equal(len(ts.Points), 1)
   211  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(20))
   212  	as.Equal(ts.Metric.Labels["fault_type"], "major")
   213  }
   214  
   215  func TestTranslateMemoryMinorPageFaults(t *testing.T) {
   216  	metricValue := generateIntMetric(42)
   217  	name := "memory/minor_page_faults"
   218  	timestamp := time.Now()
   219  	collectionStartTime := timestamp.Add(-time.Second)
   220  
   221  	ts := sink.LegacyTranslateMetric(timestamp, commonLabels, name, metricValue, collectionStartTime)
   222  
   223  	as := assert.New(t)
   224  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/memory/page_fault_count")
   225  	as.Equal(len(ts.Points), 1)
   226  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(42))
   227  	as.Equal(ts.Metric.Labels["fault_type"], "minor")
   228  }
   229  
   230  // Test LegacyTranslateLabeledMetric
   231  
   232  func TestTranslateFilesystemUsage(t *testing.T) {
   233  	metric := core.LabeledMetric{
   234  		MetricValue: generateIntMetric(10000),
   235  		Labels: map[string]string{
   236  			core.LabelResourceID.Key: "resource id",
   237  		},
   238  		Name: "filesystem/usage",
   239  	}
   240  	timestamp := time.Now()
   241  	collectionStartTime := timestamp.Add(-time.Second)
   242  
   243  	ts := sink.LegacyTranslateLabeledMetric(timestamp, commonLabels, metric, collectionStartTime)
   244  
   245  	as := assert.New(t)
   246  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/disk/bytes_used")
   247  	as.Equal(len(ts.Points), 1)
   248  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(10000))
   249  }
   250  
   251  func TestTranslateFilesystemLimit(t *testing.T) {
   252  	metric := core.LabeledMetric{
   253  		MetricValue: generateIntMetric(30000),
   254  		Labels: map[string]string{
   255  			core.LabelResourceID.Key: "resource id",
   256  		},
   257  		Name: "filesystem/limit",
   258  	}
   259  	timestamp := time.Now()
   260  	collectionStartTime := timestamp.Add(-time.Second)
   261  
   262  	ts := sink.LegacyTranslateLabeledMetric(timestamp, commonLabels, metric, collectionStartTime)
   263  
   264  	as := assert.New(t)
   265  	as.Equal(ts.Metric.Type, "container.googleapis.com/container/disk/bytes_total")
   266  	as.Equal(len(ts.Points), 1)
   267  	as.Equal(ts.Points[0].Value.GetInt64Value(), int64(30000))
   268  }
   269  
   270  func testTranslateAcceleratorMetric(t *testing.T, sourceName string, stackdriverName string) {
   271  	value := int64(12345678)
   272  	make := "nvidia"
   273  	model := "Tesla P100"
   274  	acceleratorID := "GPU-deadbeef-1234-5678-90ab-feedfacecafe"
   275  
   276  	metric := generateLabeledIntMetric(
   277  		value,
   278  		map[string]string{
   279  			core.LabelAcceleratorMake.Key:  make,
   280  			core.LabelAcceleratorModel.Key: model,
   281  			core.LabelAcceleratorID.Key:    acceleratorID,
   282  		},
   283  		sourceName)
   284  
   285  	timestamp := time.Now()
   286  	createTime := timestamp.Add(-time.Second)
   287  
   288  	ts := sink.LegacyTranslateLabeledMetric(timestamp, commonLabels, metric, createTime)
   289  
   290  	as := assert.New(t)
   291  	as.Equal(stackdriverName, ts.Metric.Type)
   292  	as.Equal(1, len(ts.Points))
   293  	as.Equal(value, ts.Points[0].Value.GetInt64Value())
   294  	as.Equal(make, ts.Metric.Labels["make"])
   295  	as.Equal(model, ts.Metric.Labels["model"])
   296  	as.Equal(acceleratorID, ts.Metric.Labels["accelerator_id"])
   297  }
   298  
   299  func TestTranslateAcceleratorMetrics(t *testing.T) {
   300  	testTranslateAcceleratorMetric(t, "accelerator/memory_total", "container.googleapis.com/container/accelerator/memory_total")
   301  	testTranslateAcceleratorMetric(t, "accelerator/memory_used", "container.googleapis.com/container/accelerator/memory_used")
   302  	testTranslateAcceleratorMetric(t, "accelerator/duty_cycle", "container.googleapis.com/container/accelerator/duty_cycle")
   303  }
   304  
   305  // Test PreprocessMemoryMetrics
   306  
   307  func TestComputeDerivedMetrics(t *testing.T) {
   308  	as := assert.New(t)
   309  
   310  	metricSet := &core.MetricSet{
   311  		MetricValues: map[string]core.MetricValue{
   312  			core.MetricMemoryUsage.MetricDescriptor.Name:           generateIntMetric(128),
   313  			core.MetricMemoryWorkingSet.MetricDescriptor.Name:      generateIntMetric(32),
   314  			core.MetricMemoryPageFaults.MetricDescriptor.Name:      generateIntMetric(42),
   315  			core.MetricMemoryMajorPageFaults.MetricDescriptor.Name: generateIntMetric(29),
   316  		},
   317  	}
   318  
   319  	computedMetrics := sink.computeDerivedMetrics(metricSet)
   320  
   321  	as.Equal(int64(96), computedMetrics.MetricValues["memory/bytes_used"].IntValue)
   322  	as.Equal(int64(13), computedMetrics.MetricValues["memory/minor_page_faults"].IntValue)
   323  }
   324  
   325  func TestTranslateMetricSet(t *testing.T) {
   326  	as := assert.New(t)
   327  
   328  	containerUptime := testTranslateMetric(as, generateIntMetric(1000), containerLabels, "uptime", "kubernetes.io/container/uptime")
   329  	containerCpuUsage := testTranslateMetric(as, generateIntMetric(2000000000), containerLabels, "cpu/usage", "kubernetes.io/container/cpu/core_usage_time")
   330  	containerCpuRequest := testTranslateMetric(as, generateIntMetric(3000), containerLabels, "cpu/request", "kubernetes.io/container/cpu/request_cores")
   331  	containerCpuLimit := testTranslateMetric(as, generateIntMetric(4000), containerLabels, "cpu/limit", "kubernetes.io/container/cpu/limit_cores")
   332  	containerMemoryUsage := testTranslateMetric(as, generateIntMetric(5), containerLabels, "memory/bytes_used", "kubernetes.io/container/memory/used_bytes")
   333  	containerMemoryRequest := testTranslateMetric(as, generateIntMetric(6), containerLabels, "memory/request", "kubernetes.io/container/memory/request_bytes")
   334  	containerMemoryLimit := testTranslateMetric(as, generateIntMetric(7), containerLabels, "memory/limit", "kubernetes.io/container/memory/limit_bytes")
   335  	containerEphemeralStorageUsage := testTranslateMetric(as, generateIntMetric(5), containerLabels, "ephemeral_storage/usage", "kubernetes.io/container/ephemeral_storage/used_bytes")
   336  	containerEphemeralStorageRequest := testTranslateMetric(as, generateIntMetric(6), containerLabels, "ephemeral_storage/request", "kubernetes.io/container/ephemeral_storage/request_bytes")
   337  	containerEphemeralStorageLimit := testTranslateMetric(as, generateIntMetric(7), containerLabels, "ephemeral_storage/limit", "kubernetes.io/container/ephemeral_storage/limit_bytes")
   338  	containerRestartCount := testTranslateMetric(as, generateIntMetric(8), containerLabels, "restart_count", "kubernetes.io/container/restart_count")
   339  	podNetworkBytesRx := testTranslateMetric(as, generateIntMetric(9), podLabels, "network/rx", "kubernetes.io/pod/network/received_bytes_count")
   340  	podNetworkBytesTx := testTranslateMetric(as, generateIntMetric(10), podLabels, "network/tx", "kubernetes.io/pod/network/sent_bytes_count")
   341  	podVolumeTotal := testTranslateLabeledMetric(as, podLabels, generateLabeledIntMetric(11, map[string]string{}, "filesystem/limit"), "kubernetes.io/pod/volume/total_bytes")
   342  	podVolumeUsed := testTranslateLabeledMetric(as, podLabels, generateLabeledIntMetric(12, map[string]string{}, "filesystem/usage"), "kubernetes.io/pod/volume/used_bytes")
   343  	nodeCpuUsage := testTranslateMetric(as, generateIntMetric(13000000000), nodeLabels, "cpu/usage", "kubernetes.io/node/cpu/core_usage_time")
   344  	nodeCpuTotal := testTranslateMetric(as, generateFloatMetric(14000), nodeLabels, "cpu/node_capacity", "kubernetes.io/node/cpu/total_cores")
   345  	nodeCpuAllocatable := testTranslateMetric(as, generateFloatMetric(15000), nodeLabels, "cpu/node_allocatable", "kubernetes.io/node/cpu/allocatable_cores")
   346  	nodeMemoryUsage := testTranslateMetric(as, generateIntMetric(16), nodeLabels, "memory/bytes_used", "kubernetes.io/node/memory/used_bytes")
   347  	nodeMemoryTotal := testTranslateMetric(as, generateFloatMetric(17), nodeLabels, "memory/node_capacity", "kubernetes.io/node/memory/total_bytes")
   348  	nodeMemoryAllocatable := testTranslateMetric(as, generateFloatMetric(18), nodeLabels, "memory/node_allocatable", "kubernetes.io/node/memory/allocatable_bytes")
   349  	nodeNetworkBytesRx := testTranslateMetric(as, generateIntMetric(19), nodeLabels, "network/rx", "kubernetes.io/node/network/received_bytes_count")
   350  	nodeNetworkBytesTx := testTranslateMetric(as, generateIntMetric(20), nodeLabels, "network/tx", "kubernetes.io/node/network/sent_bytes_count")
   351  	nodeDaemonCpuUsage := testTranslateMetric(as, generateIntMetric(21000000000), nodeDaemonLabels, "cpu/usage", "kubernetes.io/node_daemon/cpu/core_usage_time")
   352  	nodeDaemonMemoryUsage := testTranslateMetric(as, generateIntMetric(22), nodeDaemonLabels, "memory/bytes_used", "kubernetes.io/node_daemon/memory/used_bytes")
   353  
   354  	as.Equal(float64(1), containerUptime.GetDoubleValue())
   355  	as.Equal(float64(2), containerCpuUsage.GetDoubleValue())
   356  	as.Equal(float64(3), containerCpuRequest.GetDoubleValue())
   357  	as.Equal(float64(4), containerCpuLimit.GetDoubleValue())
   358  	as.Equal(int64(5), containerMemoryUsage.GetInt64Value())
   359  	as.Equal(int64(6), containerMemoryRequest.GetInt64Value())
   360  	as.Equal(int64(7), containerMemoryLimit.GetInt64Value())
   361  	as.Equal(int64(8), containerRestartCount.GetInt64Value())
   362  	as.Equal(int64(9), podNetworkBytesRx.GetInt64Value())
   363  	as.Equal(int64(10), podNetworkBytesTx.GetInt64Value())
   364  	as.Equal(int64(11), podVolumeTotal.GetInt64Value())
   365  	as.Equal(int64(12), podVolumeUsed.GetInt64Value())
   366  	as.Equal(float64(13), nodeCpuUsage.GetDoubleValue())
   367  	as.Equal(float64(14), nodeCpuTotal.GetDoubleValue())
   368  	as.Equal(float64(15), nodeCpuAllocatable.GetDoubleValue())
   369  	as.Equal(int64(16), nodeMemoryUsage.GetInt64Value())
   370  	as.Equal(int64(17), nodeMemoryTotal.GetInt64Value())
   371  	as.Equal(int64(18), nodeMemoryAllocatable.GetInt64Value())
   372  	as.Equal(int64(19), nodeNetworkBytesRx.GetInt64Value())
   373  	as.Equal(int64(20), nodeNetworkBytesTx.GetInt64Value())
   374  	as.Equal(float64(21), nodeDaemonCpuUsage.GetDoubleValue())
   375  	as.Equal(int64(22), nodeDaemonMemoryUsage.GetInt64Value())
   376  	as.Equal(int64(5), containerEphemeralStorageUsage.GetInt64Value())
   377  	as.Equal(int64(6), containerEphemeralStorageRequest.GetInt64Value())
   378  	as.Equal(int64(7), containerEphemeralStorageLimit.GetInt64Value())
   379  }