CloudWatch: Remove simplejson in favor of 'encoding/json' (#51062)

This commit is contained in:
Adam Simpson
2022-07-08 19:39:53 +00:00
committed by GitHub
parent eb6d6d0d2b
commit 05cdef5004
7 changed files with 356 additions and 276 deletions
+98 -66
View File
@@ -1,12 +1,12 @@
package cloudwatch
import (
"encoding/json"
"fmt"
"testing"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -37,32 +37,33 @@ func TestRequestParser(t *testing.T) {
migratedQuery := migratedQueries[0]
assert.Equal(t, "A", migratedQuery.RefID)
model, err := simplejson.NewJson(migratedQuery.JSON)
var model QueryJson
err = json.Unmarshal(migratedQuery.JSON, &model)
require.NoError(t, err)
assert.Equal(t, "Average", model.Get("statistic").MustString())
res, err := model.Get("statistic").Array()
assert.Error(t, err)
assert.Nil(t, res)
assert.Equal(t, "Average", *model.Statistic)
})
})
t.Run("New dimensions structure", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
fixtureJSON := []byte(`{
"refId": "ref1",
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
"id": "",
"expression": "",
"dimensions": map[string]interface{}{
"InstanceId": []interface{}{"test"},
"InstanceType": []interface{}{"test2", "test3"},
"dimensions": {
"InstanceId": ["test"],
"InstanceType": ["test2", "test3"]
},
"statistic": "Average",
"period": "600",
"hide": false,
})
"hide": false
}`)
var query QueryJson
err := json.Unmarshal(fixtureJSON, &query)
require.NoError(t, err)
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, "us-east-1", res.Region)
@@ -81,21 +82,25 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Old dimensions structure (backwards compatibility)", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
fixtureJSON := []byte(`{
"refId": "ref1",
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
"id": "",
"expression": "",
"dimensions": map[string]interface{}{
"InstanceId": "test",
"InstanceType": "test2",
"dimensions": {
"InstanceId": ["test"],
"InstanceType": ["test2"]
},
"statistic": "Average",
"period": "600",
"hide": false,
})
"hide": false
}`)
var query QueryJson
err := json.Unmarshal(fixtureJSON, &query)
require.NoError(t, err)
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
@@ -115,21 +120,25 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Period defined in the editor by the user is being used when time range is short", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
fixtureJSON := []byte(`{
"refId": "ref1",
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
"id": "",
"expression": "",
"dimensions": map[string]interface{}{
"InstanceId": "test",
"InstanceType": "test2",
"dimensions": {
"InstanceId": ["test"],
"InstanceType": ["test2"]
},
"statistic": "Average",
"hide": false,
})
query.Set("period", "900")
"hide": false
}`)
var query QueryJson
err := json.Unmarshal(fixtureJSON, &query)
require.NoError(t, err)
query.Period = "900"
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
@@ -137,24 +146,28 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Period is parsed correctly if not defined by user", func(t *testing.T) {
query := simplejson.NewFromAny(map[string]interface{}{
fixtureJSON := []byte(`{
"refId": "ref1",
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
"id": "",
"expression": "",
"dimensions": map[string]interface{}{
"InstanceId": "test",
"InstanceType": "test2",
"dimensions": {
"InstanceId": ["test"],
"InstanceType": ["test2"]
},
"statistic": "Average",
"hide": false,
"period": "auto",
})
"period": "auto"
}`)
var query QueryJson
err := json.Unmarshal(fixtureJSON, &query)
require.NoError(t, err)
t.Run("Time range is 5 minutes", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.Local().Add(time.Minute * time.Duration(5))
@@ -164,7 +177,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 1 day", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(0, 0, -1)
@@ -174,7 +187,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 2 days", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(0, 0, -2)
res, err := parseRequestQuery(query, "ref1", from, to)
@@ -183,7 +196,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 7 days", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(0, 0, -7)
@@ -193,7 +206,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 30 days", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(0, 0, -30)
@@ -203,7 +216,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 90 days", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(0, 0, -90)
@@ -213,7 +226,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 1 year", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(-1, 0, 0)
@@ -223,7 +236,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 2 years", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now()
from := to.AddDate(-2, 0, 0)
@@ -233,7 +246,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 2 days, but 16 days ago", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now().AddDate(0, 0, -14)
from := to.AddDate(0, 0, -2)
res, err := parseRequestQuery(query, "ref1", from, to)
@@ -242,7 +255,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 2 days, but 90 days ago", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now().AddDate(0, 0, -88)
from := to.AddDate(0, 0, -2)
res, err := parseRequestQuery(query, "ref1", from, to)
@@ -251,7 +264,7 @@ func TestRequestParser(t *testing.T) {
})
t.Run("Time range is 2 days, but 456 days ago", func(t *testing.T) {
query.Set("period", "auto")
query.Period = "auto"
to := time.Now().AddDate(0, 0, -454)
from := to.AddDate(0, 0, -2)
res, err := parseRequestQuery(query, "ref1", from, to)
@@ -273,7 +286,7 @@ func TestRequestParser(t *testing.T) {
t.Run("and an expression is specified it should be metric search builder", func(t *testing.T) {
query := getBaseJsonQuery()
query.Set("expression", "SUM(a)")
query.Expression = "SUM(a)"
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, MetricQueryTypeSearch, res.MetricQueryType)
@@ -284,7 +297,7 @@ func TestRequestParser(t *testing.T) {
t.Run("and an expression is specified it should be metric search builder", func(t *testing.T) {
query := getBaseJsonQuery()
query.Set("expression", "SUM(a)")
query.Expression = "SUM(a)"
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, MetricQueryTypeSearch, res.MetricQueryType)
@@ -303,7 +316,7 @@ func TestRequestParser(t *testing.T) {
t.Run("Valid id is generated if ID is not provided and refId is not a valid MetricData ID", func(t *testing.T) {
query := getBaseJsonQuery()
query.Set("refId", "$$")
query.RefId = "$$"
res, err := parseRequestQuery(query, "$$", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
require.NoError(t, err)
assert.Equal(t, "$$", res.RefId)
@@ -312,8 +325,11 @@ func TestRequestParser(t *testing.T) {
t.Run("parseRequestQuery sets label when label is present in json query", func(t *testing.T) {
query := getBaseJsonQuery()
query.Set("alias", "some alias")
query.Set("label", "some label")
alias := "some alias"
query.Alias = &alias
label := "some label"
query.Label = &label
res, err := parseRequestQuery(query, "ref1", time.Now().Add(-2*time.Hour), time.Now().Add(-time.Hour))
@@ -323,15 +339,22 @@ func TestRequestParser(t *testing.T) {
})
}
func getBaseJsonQuery() *simplejson.Json {
return simplejson.NewFromAny(map[string]interface{}{
func getBaseJsonQuery() QueryJson {
fixtureJSON := []byte(`{
"refId": "ref1",
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
"statistic": "Average",
"period": "900",
})
"period": "900"
}`)
var query QueryJson
err := json.Unmarshal(fixtureJSON, &query)
if err != nil {
panic(err)
}
return query
}
func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_creates_new_label(t *testing.T) {
@@ -352,7 +375,7 @@ func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_create
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
queryJson, err := simplejson.NewJson([]byte(fmt.Sprintf(`{
queryJson := []byte(fmt.Sprintf(`{
"region": "us-east-1",
"namespace": "ec2",
"metricName": "CPUUtilization",
@@ -363,26 +386,35 @@ func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_create
"statistic": "Average",
"period": "600",
"hide": false
}`, tc.inputAlias)))
}`, tc.inputAlias))
var query QueryJson
err := json.Unmarshal(queryJson, &query)
require.NoError(t, err)
migrateAliasToDynamicLabel(queryJson)
migrateAliasToDynamicLabel(&query)
assert.Equal(t, simplejson.NewFromAny(
map[string]interface{}{
"alias": tc.inputAlias,
"dimensions": map[string]interface{}{"InstanceId": []interface{}{"test"}},
"hide": false,
"label": tc.expectedLabel,
"metricName": "CPUUtilization",
"namespace": "ec2",
"period": "600",
"region": "us-east-1",
"statistic": "Average"}), queryJson)
matchedJson := []byte(fmt.Sprintf(`{
"alias": "%s",
"dimensions": {
"InstanceId": ["test"]
},
"hide": false,
"label": "%s",
"metricName": "CPUUtilization",
"namespace": "ec2",
"period": "600",
"region": "us-east-1",
"statistic": "Average"
}`, tc.inputAlias, tc.expectedLabel))
result, err := json.Marshal(query)
require.NoError(t, err)
assert.JSONEq(t, string(matchedJson), string(result))
})
}
}
func Test_Test_migrateLegacyQuery(t *testing.T) {
t.Run("migrates alias to label when label does not already exist and feature toggle enabled", func(t *testing.T) {
migratedQueries, err := migrateLegacyQuery(