From 2d7e980da7fcd4363f32b4d7a7096c348a82c439 Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Fri, 9 Apr 2021 14:23:51 -0400 Subject: [PATCH] testData: (backend) restore null/nan in predicatable scenarios (#32855) --- pkg/tsdb/testdatasource/scenarios.go | 56 +++++++++++++++++++--------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/pkg/tsdb/testdatasource/scenarios.go b/pkg/tsdb/testdatasource/scenarios.go index d5f7a5cb61b..aabcae8dabe 100644 --- a/pkg/tsdb/testdatasource/scenarios.go +++ b/pkg/tsdb/testdatasource/scenarios.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" - "github.com/grafana/grafana/pkg/components/null" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/util/errutil" ) @@ -763,25 +762,38 @@ func predictableCSVWave(query backend.DataQuery, model *simplejson.Json) (*data. rawValues := options.Get("valuesCSV").MustString() rawValues = strings.TrimRight(strings.TrimSpace(rawValues), ",") // Strip Trailing Comma rawValesCSV := strings.Split(rawValues, ",") - values := make([]null.Float, len(rawValesCSV)) + values := make([]*float64, len(rawValesCSV)) + for i, rawValue := range rawValesCSV { - val, err := null.FloatFromString(strings.TrimSpace(rawValue), "null") - if err != nil { - return nil, errutil.Wrapf(err, "failed to parse value '%v' into nullable float", rawValue) + var val *float64 + rawValue = strings.TrimSpace(rawValue) + + switch rawValue { + case "null": + // val stays nil + case "nan": + f := math.NaN() + val = &f + default: + f, err := strconv.ParseFloat(rawValue, 64) + if err != nil { + return nil, errutil.Wrapf(err, "failed to parse value '%v' into nullable float", rawValue) + } + val = &f } values[i] = val } timeStep *= 1000 // Seconds to Milliseconds valuesLen := int64(len(values)) - getValue := func(mod int64) (null.Float, error) { + getValue := func(mod int64) (*float64, error) { var i int64 for i = 0; i < valuesLen; i++ { if mod == i*timeStep { return values[i], nil } } - return null.Float{}, fmt.Errorf("did not get value at point in waveform - should not be here") + return nil, fmt.Errorf("did not get value at point in waveform - should not be here") } fields, err := predictableSeries(query.TimeRange, timeStep, valuesLen, getValue) if err != nil { @@ -795,7 +807,7 @@ func predictableCSVWave(query backend.DataQuery, model *simplejson.Json) (*data. return frame, nil } -func predictableSeries(timeRange backend.TimeRange, timeStep, length int64, getValue func(mod int64) (null.Float, error)) (data.Fields, error) { +func predictableSeries(timeRange backend.TimeRange, timeStep, length int64, getValue func(mod int64) (*float64, error)) (data.Fields, error) { from := timeRange.From.UnixNano() / int64(time.Millisecond) to := timeRange.To.UnixNano() / int64(time.Millisecond) @@ -814,7 +826,7 @@ func predictableSeries(timeRange backend.TimeRange, timeStep, length int64, getV t := time.Unix(timeCursor/int64(1e+3), (timeCursor%int64(1e+3))*int64(1e+6)) timeVec = append(timeVec, &t) - floatVec = append(floatVec, &val.Float64) + floatVec = append(floatVec, val) timeCursor += timeStep } @@ -830,8 +842,8 @@ func predictablePulse(query backend.DataQuery, model *simplejson.Json) (*data.Fr var timeStep int64 var onCount int64 var offCount int64 - var onValue null.Float - var offValue null.Float + var onValue *float64 + var offValue *float64 options := model.Get("pulseWave") @@ -855,8 +867,8 @@ func predictablePulse(query backend.DataQuery, model *simplejson.Json) (*data.Fr return nil, fmt.Errorf("failed to parse offValue value '%v' into float: %v", options.Get("offValue"), err) } - timeStep *= 1000 // Seconds to Milliseconds - onFor := func(mod int64) (null.Float, error) { // How many items in the cycle should get the on value + timeStep *= 1000 // Seconds to Milliseconds + onFor := func(mod int64) (*float64, error) { // How many items in the cycle should get the on value var i int64 for i = 0; i < onCount; i++ { if mod == i*timeStep { @@ -989,18 +1001,26 @@ func frameNameForQuery(query backend.DataQuery, model *simplejson.Json, index in return name } -func fromStringOrNumber(val *simplejson.Json) (null.Float, error) { +func fromStringOrNumber(val *simplejson.Json) (*float64, error) { switch v := val.Interface().(type) { case json.Number: fV, err := v.Float64() if err != nil { - return null.Float{}, err + return nil, err } - return null.FloatFrom(fV), nil + return &fV, nil case string: - return null.FloatFromString(v, "null") + switch v { + case "null": + return nil, nil + case "nan": + v := math.NaN() + return &v, nil + default: + return nil, fmt.Errorf("failed to extract value from %v", v) + } default: - return null.Float{}, fmt.Errorf("failed to extract value") + return nil, fmt.Errorf("failed to extract value") } }