github.com/google/cloudprober@v0.11.3/surfacers/cloudwatch/cloudwatch_test.go (about)

     1  // Copyright 2021 The Cloudprober Authors.
     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 cloudwatch
    16  
    17  import (
    18  	"context"
    19  	"reflect"
    20  	"strings"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/aws/aws-sdk-go/aws"
    25  	"github.com/aws/aws-sdk-go/service/cloudwatch"
    26  	"github.com/google/cloudprober/logger"
    27  	"github.com/google/cloudprober/metrics"
    28  	configpb "github.com/google/cloudprober/surfacers/cloudwatch/proto"
    29  )
    30  
    31  func newTestCWSurfacer() CWSurfacer {
    32  	l, _ := logger.New(context.TODO(), "test-logger")
    33  	namespace := "sre/test/cloudprober"
    34  	resolution := int64(60)
    35  
    36  	return CWSurfacer{
    37  		l: l,
    38  		c: &configpb.SurfacerConf{
    39  			Namespace:  &namespace,
    40  			Resolution: &resolution,
    41  		},
    42  	}
    43  }
    44  
    45  func TestEmLabelsToDimensions(t *testing.T) {
    46  	timestamp := time.Now()
    47  
    48  	tests := map[string]struct {
    49  		em   *metrics.EventMetrics
    50  		want []*cloudwatch.Dimension
    51  	}{
    52  		"no label": {
    53  			em:   metrics.NewEventMetrics(timestamp),
    54  			want: []*cloudwatch.Dimension{},
    55  		},
    56  		"one label": {
    57  			em: metrics.NewEventMetrics(timestamp).
    58  				AddLabel("ptype", "sysvars"),
    59  			want: []*cloudwatch.Dimension{
    60  				{
    61  					Name:  aws.String("ptype"),
    62  					Value: aws.String("sysvars"),
    63  				},
    64  			},
    65  		},
    66  		"three labels": {
    67  			em: metrics.NewEventMetrics(timestamp).
    68  				AddLabel("ptype", "sysvars").
    69  				AddLabel("probe", "sysvars").
    70  				AddLabel("test", "testing123"),
    71  			want: []*cloudwatch.Dimension{
    72  				{
    73  					Name:  aws.String("ptype"),
    74  					Value: aws.String("sysvars"),
    75  				},
    76  				{
    77  					Name:  aws.String("probe"),
    78  					Value: aws.String("sysvars"),
    79  				},
    80  				{
    81  					Name:  aws.String("test"),
    82  					Value: aws.String("testing123"),
    83  				},
    84  			},
    85  		},
    86  	}
    87  
    88  	for name, tc := range tests {
    89  		t.Run(name, func(t *testing.T) {
    90  			got := emLabelsToDimensions(tc.em)
    91  			if !reflect.DeepEqual(got, tc.want) {
    92  				t.Errorf("got: %v, want: %v", got, tc.want)
    93  			}
    94  		})
    95  	}
    96  }
    97  
    98  func TestNewCWMetricDatum(t *testing.T) {
    99  	timestamp := time.Now()
   100  
   101  	tests := map[string]struct {
   102  		surfacer   CWSurfacer
   103  		metricname string
   104  		value      float64
   105  		dimensions []*cloudwatch.Dimension
   106  		timestamp  time.Time
   107  		duration   time.Duration
   108  		want       *cloudwatch.MetricDatum
   109  	}{
   110  		"simple": {
   111  			surfacer:   newTestCWSurfacer(),
   112  			metricname: "testingmetric",
   113  			value:      float64(20),
   114  			dimensions: []*cloudwatch.Dimension{
   115  				{
   116  					Name: aws.String("test"), Value: aws.String("value"),
   117  				},
   118  			},
   119  			timestamp: timestamp,
   120  			want: &cloudwatch.MetricDatum{
   121  				Dimensions: []*cloudwatch.Dimension{
   122  					{
   123  						Name: aws.String("test"), Value: aws.String("value"),
   124  					},
   125  				},
   126  				MetricName:        aws.String("testingmetric"),
   127  				Value:             aws.Float64(float64(20)),
   128  				StorageResolution: aws.Int64(60),
   129  				Timestamp:         aws.Time(timestamp),
   130  				Unit:              aws.String(cloudwatch.StandardUnitCount),
   131  			},
   132  		},
   133  		"le_dimension_count_unit": {
   134  			surfacer:   newTestCWSurfacer(),
   135  			metricname: "testingmetric",
   136  			value:      float64(20),
   137  			dimensions: []*cloudwatch.Dimension{
   138  				{
   139  					Name: aws.String("test"), Value: aws.String("value"),
   140  				},
   141  			},
   142  			timestamp: timestamp,
   143  			want: &cloudwatch.MetricDatum{
   144  				Dimensions: []*cloudwatch.Dimension{
   145  					{
   146  						Name: aws.String("test"), Value: aws.String("value"),
   147  					},
   148  				},
   149  				MetricName:        aws.String("testingmetric"),
   150  				Value:             aws.Float64(float64(20)),
   151  				StorageResolution: aws.Int64(60),
   152  				Timestamp:         aws.Time(timestamp),
   153  				Unit:              aws.String("Count"),
   154  			},
   155  		},
   156  		"latency_name_nanosecond_unit": {
   157  			surfacer:   newTestCWSurfacer(),
   158  			metricname: "latency",
   159  			value:      float64(20),
   160  			dimensions: []*cloudwatch.Dimension{
   161  				{
   162  					Name: aws.String("name"), Value: aws.String("value"),
   163  				},
   164  			},
   165  			timestamp: timestamp,
   166  			duration:  time.Nanosecond,
   167  			want: &cloudwatch.MetricDatum{
   168  				Dimensions: []*cloudwatch.Dimension{
   169  					{
   170  						Name: aws.String("name"), Value: aws.String("value"),
   171  					},
   172  				},
   173  				MetricName:        aws.String("latency"),
   174  				Value:             aws.Float64(0.00002),
   175  				StorageResolution: aws.Int64(60),
   176  				Timestamp:         aws.Time(timestamp),
   177  				Unit:              aws.String("Milliseconds"),
   178  			},
   179  		},
   180  		"latency_name_microseconds_unit": {
   181  			surfacer:   newTestCWSurfacer(),
   182  			metricname: "latency",
   183  			value:      float64(20),
   184  			dimensions: []*cloudwatch.Dimension{
   185  				{
   186  					Name: aws.String("name"), Value: aws.String("value"),
   187  				},
   188  			},
   189  			timestamp: timestamp,
   190  			duration:  time.Microsecond,
   191  			want: &cloudwatch.MetricDatum{
   192  				Dimensions: []*cloudwatch.Dimension{
   193  					{
   194  						Name: aws.String("name"), Value: aws.String("value"),
   195  					},
   196  				},
   197  				MetricName:        aws.String("latency"),
   198  				Value:             aws.Float64(0.02),
   199  				StorageResolution: aws.Int64(60),
   200  				Timestamp:         aws.Time(timestamp),
   201  				Unit:              aws.String("Milliseconds"),
   202  			},
   203  		},
   204  		"latency_name_milliseconds_unit": {
   205  			surfacer:   newTestCWSurfacer(),
   206  			metricname: "latency",
   207  			value:      float64(20),
   208  			dimensions: []*cloudwatch.Dimension{
   209  				{
   210  					Name: aws.String("name"), Value: aws.String("value"),
   211  				},
   212  			},
   213  			timestamp: timestamp,
   214  			duration:  time.Millisecond,
   215  			want: &cloudwatch.MetricDatum{
   216  				Dimensions: []*cloudwatch.Dimension{
   217  					{
   218  						Name: aws.String("name"), Value: aws.String("value"),
   219  					},
   220  				},
   221  				MetricName:        aws.String("latency"),
   222  				Value:             aws.Float64(20),
   223  				StorageResolution: aws.Int64(60),
   224  				Timestamp:         aws.Time(timestamp),
   225  				Unit:              aws.String("Milliseconds"),
   226  			},
   227  		},
   228  		"latency_name_seconds_unit": {
   229  			surfacer:   newTestCWSurfacer(),
   230  			metricname: "latency",
   231  			value:      float64(20),
   232  			dimensions: []*cloudwatch.Dimension{
   233  				{
   234  					Name: aws.String("name"), Value: aws.String("value"),
   235  				},
   236  			},
   237  			timestamp: timestamp,
   238  			duration:  time.Second,
   239  			want: &cloudwatch.MetricDatum{
   240  				Dimensions: []*cloudwatch.Dimension{
   241  					{
   242  						Name: aws.String("name"), Value: aws.String("value"),
   243  					},
   244  				},
   245  				MetricName:        aws.String("latency"),
   246  				Value:             aws.Float64(20000),
   247  				StorageResolution: aws.Int64(60),
   248  				Timestamp:         aws.Time(timestamp),
   249  				Unit:              aws.String("Milliseconds"),
   250  			},
   251  		},
   252  	}
   253  
   254  	for name, tc := range tests {
   255  		t.Run(name, func(t *testing.T) {
   256  			got := tc.surfacer.newCWMetricDatum(
   257  				tc.metricname,
   258  				tc.value,
   259  				tc.dimensions,
   260  				tc.timestamp,
   261  				tc.duration,
   262  			)
   263  
   264  			if !reflect.DeepEqual(got, tc.want) {
   265  				t.Errorf("got: %v, want: %v", got, tc.want)
   266  			}
   267  		})
   268  	}
   269  }
   270  
   271  func ErrorContains(out error, want string) bool {
   272  	if out == nil {
   273  		return want == ""
   274  	}
   275  	if want == "" {
   276  		return false
   277  	}
   278  	return strings.Contains(out.Error(), want)
   279  }