package cloudwatch import ( "context" "encoding/json" "testing" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend/datasource" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestTimeSeriesQuery(t *testing.T) { executor := newExecutor(nil, newTestConfig(), fakeSessionCache{}) now := time.Now() origNewCWClient := NewCWClient t.Cleanup(func() { NewCWClient = origNewCWClient }) var cwClient FakeCWClient NewCWClient = func(sess *session.Session) cloudwatchiface.CloudWatchAPI { return cwClient } t.Run("Custom metrics", func(t *testing.T) { cwClient = FakeCWClient{ CloudWatchAPI: nil, GetMetricDataOutput: cloudwatch.GetMetricDataOutput{ NextToken: nil, Messages: []*cloudwatch.MessageData{}, MetricDataResults: []*cloudwatch.MetricDataResult{ { StatusCode: aws.String("Complete"), Id: aws.String("a"), Label: aws.String("NetworkOut"), Values: []*float64{aws.Float64(1.0)}, Timestamps: []*time.Time{&now}, }, { StatusCode: aws.String("Complete"), Id: aws.String("b"), Label: aws.String("NetworkIn"), Values: []*float64{aws.Float64(1.0)}, Timestamps: []*time.Time{&now}, }, }, }, } im := datasource.NewInstanceManager(func(s backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { return datasourceInfo{}, nil }) executor := newExecutor(im, newTestConfig(), fakeSessionCache{}) resp, err := executor.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{ DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{}, }, Queries: []backend.DataQuery{ { RefID: "A", TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -2), To: now.Add(time.Hour * -1), }, JSON: json.RawMessage(`{ "type": "timeSeriesQuery", "subtype": "metrics", "namespace": "AWS/EC2", "metricName": "NetworkOut", "expression": "", "dimensions": { "InstanceId": "i-00645d91ed77d87ac" }, "region": "us-east-2", "id": "a", "alias": "NetworkOut", "statistics": [ "Maximum" ], "period": "300", "hide": false, "matchExact": true, "refId": "A" }`), }, { RefID: "B", TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -2), To: now.Add(time.Hour * -1), }, JSON: json.RawMessage(`{ "type": "timeSeriesQuery", "subtype": "metrics", "namespace": "AWS/EC2", "metricName": "NetworkIn", "expression": "", "dimensions": { "InstanceId": "i-00645d91ed77d87ac" }, "region": "us-east-2", "id": "b", "alias": "NetworkIn", "statistics": [ "Maximum" ], "period": "300", "matchExact": true, "refId": "B" }`), }, }, }) require.NoError(t, err) assert.Equal(t, "NetworkOut", resp.Responses["A"].Frames[0].Name) assert.Equal(t, "NetworkIn", resp.Responses["B"].Frames[0].Name) }) t.Run("End time before start time should result in error", func(t *testing.T) { _, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -1), To: now.Add(time.Hour * -2), }}}}) assert.EqualError(t, err, "invalid time range: start time must be before end time") }) t.Run("End time equals start time should result in error", func(t *testing.T) { _, err := executor.executeTimeSeriesQuery(context.Background(), &backend.QueryDataRequest{Queries: []backend.DataQuery{{TimeRange: backend.TimeRange{ From: now.Add(time.Hour * -1), To: now.Add(time.Hour * -1), }}}}) assert.EqualError(t, err, "invalid time range: start time must be before end time") }) }