362 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			362 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Go
		
	
	
	
| package azure_monitor
 | |
| 
 | |
| import (
 | |
| 	"bufio"
 | |
| 	"compress/gzip"
 | |
| 	"encoding/json"
 | |
| 	"net/http"
 | |
| 	"net/http/httptest"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/Azure/go-autorest/autorest"
 | |
| 	"github.com/influxdata/telegraf"
 | |
| 	"github.com/influxdata/telegraf/testutil"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func TestAggregate(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name     string
 | |
| 		plugin   *AzureMonitor
 | |
| 		metrics  []telegraf.Metric
 | |
| 		addTime  time.Time
 | |
| 		pushTime time.Time
 | |
| 		check    func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric)
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "add metric outside window is dropped",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 42,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			addTime:  time.Unix(3600, 0),
 | |
| 			pushTime: time.Unix(3600, 0),
 | |
| 			check: func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric) {
 | |
| 				require.Equal(t, int64(1), plugin.MetricOutsideWindow.Get())
 | |
| 				require.Len(t, metrics, 0)
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "metric not sent until period expires",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 42,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			addTime:  time.Unix(0, 0),
 | |
| 			pushTime: time.Unix(0, 0),
 | |
| 			check: func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric) {
 | |
| 				require.Len(t, metrics, 0)
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "add strings as dimensions",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:              "test",
 | |
| 				ResourceID:          "/test",
 | |
| 				StringsAsDimensions: true,
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{
 | |
| 						"host": "localhost",
 | |
| 					},
 | |
| 					map[string]interface{}{
 | |
| 						"value":   42,
 | |
| 						"message": "howdy",
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			addTime:  time.Unix(0, 0),
 | |
| 			pushTime: time.Unix(3600, 0),
 | |
| 			check: func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric) {
 | |
| 				expected := []telegraf.Metric{
 | |
| 					testutil.MustMetric(
 | |
| 						"cpu-value",
 | |
| 						map[string]string{
 | |
| 							"host":    "localhost",
 | |
| 							"message": "howdy",
 | |
| 						},
 | |
| 						map[string]interface{}{
 | |
| 							"min":   42.0,
 | |
| 							"max":   42.0,
 | |
| 							"sum":   42.0,
 | |
| 							"count": 1,
 | |
| 						},
 | |
| 						time.Unix(0, 0),
 | |
| 					),
 | |
| 				}
 | |
| 				testutil.RequireMetricsEqual(t, expected, metrics)
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "add metric to cache and push",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 				cache:      make(map[time.Time]map[uint64]*aggregate, 36),
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 42,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			addTime:  time.Unix(0, 0),
 | |
| 			pushTime: time.Unix(3600, 0),
 | |
| 			check: func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric) {
 | |
| 				expected := []telegraf.Metric{
 | |
| 					testutil.MustMetric(
 | |
| 						"cpu-value",
 | |
| 						map[string]string{},
 | |
| 						map[string]interface{}{
 | |
| 							"min":   42.0,
 | |
| 							"max":   42.0,
 | |
| 							"sum":   42.0,
 | |
| 							"count": 1,
 | |
| 						},
 | |
| 						time.Unix(0, 0),
 | |
| 					),
 | |
| 				}
 | |
| 
 | |
| 				testutil.RequireMetricsEqual(t, expected, metrics)
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "added metric are aggregated",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 				cache:      make(map[time.Time]map[uint64]*aggregate, 36),
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 42,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 84,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 2,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			addTime:  time.Unix(0, 0),
 | |
| 			pushTime: time.Unix(3600, 0),
 | |
| 			check: func(t *testing.T, plugin *AzureMonitor, metrics []telegraf.Metric) {
 | |
| 				expected := []telegraf.Metric{
 | |
| 					testutil.MustMetric(
 | |
| 						"cpu-value",
 | |
| 						map[string]string{},
 | |
| 						map[string]interface{}{
 | |
| 							"min":   2.0,
 | |
| 							"max":   84.0,
 | |
| 							"sum":   128.0,
 | |
| 							"count": 3,
 | |
| 						},
 | |
| 						time.Unix(0, 0),
 | |
| 					),
 | |
| 				}
 | |
| 
 | |
| 				testutil.RequireMetricsEqual(t, expected, metrics)
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 	for _, tt := range tests {
 | |
| 		t.Run(tt.name, func(t *testing.T) {
 | |
| 			err := tt.plugin.Connect()
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			// Reset globals
 | |
| 			tt.plugin.MetricOutsideWindow.Set(0)
 | |
| 
 | |
| 			tt.plugin.timeFunc = func() time.Time { return tt.addTime }
 | |
| 			for _, m := range tt.metrics {
 | |
| 				tt.plugin.Add(m)
 | |
| 			}
 | |
| 
 | |
| 			tt.plugin.timeFunc = func() time.Time { return tt.pushTime }
 | |
| 			metrics := tt.plugin.Push()
 | |
| 			tt.plugin.Reset()
 | |
| 
 | |
| 			tt.check(t, tt.plugin, metrics)
 | |
| 		})
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestWrite(t *testing.T) {
 | |
| 	readBody := func(r *http.Request) ([]*azureMonitorMetric, error) {
 | |
| 		gz, err := gzip.NewReader(r.Body)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		scanner := bufio.NewScanner(gz)
 | |
| 
 | |
| 		azmetrics := make([]*azureMonitorMetric, 0)
 | |
| 		for scanner.Scan() {
 | |
| 			line := scanner.Text()
 | |
| 			var amm azureMonitorMetric
 | |
| 			err = json.Unmarshal([]byte(line), &amm)
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 			azmetrics = append(azmetrics, &amm)
 | |
| 		}
 | |
| 
 | |
| 		return azmetrics, nil
 | |
| 	}
 | |
| 
 | |
| 	ts := httptest.NewServer(http.NotFoundHandler())
 | |
| 	defer ts.Close()
 | |
| 
 | |
| 	url := "http://" + ts.Listener.Addr().String() + "/metrics"
 | |
| 
 | |
| 	tests := []struct {
 | |
| 		name    string
 | |
| 		plugin  *AzureMonitor
 | |
| 		metrics []telegraf.Metric
 | |
| 		handler func(t *testing.T, w http.ResponseWriter, r *http.Request)
 | |
| 	}{
 | |
| 		{
 | |
| 			name: "if not an azure metric nothing is sent",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"value": 42,
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			handler: func(t *testing.T, w http.ResponseWriter, r *http.Request) {
 | |
| 				t.Fatal("should not call")
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "single azure metric",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu-value",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"min":   float64(42),
 | |
| 						"max":   float64(42),
 | |
| 						"sum":   float64(42),
 | |
| 						"count": int64(1),
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			handler: func(t *testing.T, w http.ResponseWriter, r *http.Request) {
 | |
| 				azmetrics, err := readBody(r)
 | |
| 				require.NoError(t, err)
 | |
| 				require.Len(t, azmetrics, 1)
 | |
| 				w.WriteHeader(http.StatusOK)
 | |
| 			},
 | |
| 		},
 | |
| 		{
 | |
| 			name: "multiple azure metric",
 | |
| 			plugin: &AzureMonitor{
 | |
| 				Region:     "test",
 | |
| 				ResourceID: "/test",
 | |
| 			},
 | |
| 			metrics: []telegraf.Metric{
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu-value",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"min":   float64(42),
 | |
| 						"max":   float64(42),
 | |
| 						"sum":   float64(42),
 | |
| 						"count": int64(1),
 | |
| 					},
 | |
| 					time.Unix(0, 0),
 | |
| 				),
 | |
| 				testutil.MustMetric(
 | |
| 					"cpu-value",
 | |
| 					map[string]string{},
 | |
| 					map[string]interface{}{
 | |
| 						"min":   float64(42),
 | |
| 						"max":   float64(42),
 | |
| 						"sum":   float64(42),
 | |
| 						"count": int64(1),
 | |
| 					},
 | |
| 					time.Unix(60, 0),
 | |
| 				),
 | |
| 			},
 | |
| 			handler: func(t *testing.T, w http.ResponseWriter, r *http.Request) {
 | |
| 				azmetrics, err := readBody(r)
 | |
| 				require.NoError(t, err)
 | |
| 				require.Len(t, azmetrics, 2)
 | |
| 				w.WriteHeader(http.StatusOK)
 | |
| 			},
 | |
| 		},
 | |
| 	}
 | |
| 	for _, tt := range tests {
 | |
| 		t.Run(tt.name, func(t *testing.T) {
 | |
| 			ts.Config.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 				tt.handler(t, w, r)
 | |
| 			})
 | |
| 
 | |
| 			err := tt.plugin.Connect()
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			// override real authorizer and write url
 | |
| 			tt.plugin.auth = autorest.NullAuthorizer{}
 | |
| 			tt.plugin.url = url
 | |
| 
 | |
| 			err = tt.plugin.Write(tt.metrics)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 	}
 | |
| }
 |