mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Testdata: support null values in manual entry and return all data (#32276)
This commit is contained in:
parent
dea7c70fac
commit
7f1b9eafda
@ -285,42 +285,40 @@ func (p *testDataPlugin) handleManualEntryScenario(ctx context.Context, req *bac
|
||||
for _, q := range req.Queries {
|
||||
model, err := simplejson.NewJson(q.JSON)
|
||||
if err != nil {
|
||||
continue
|
||||
return nil, fmt.Errorf("error reading query")
|
||||
}
|
||||
points := model.Get("points").MustArray()
|
||||
|
||||
frame := newSeriesForQuery(q, model, 0)
|
||||
startTime := q.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
||||
endTime := q.TimeRange.To.UnixNano() / int64(time.Millisecond)
|
||||
|
||||
timeVec := make([]*time.Time, 0)
|
||||
floatVec := make([]*float64, 0)
|
||||
timeField := data.NewFieldFromFieldType(data.FieldTypeTime, 0)
|
||||
valueField := data.NewFieldFromFieldType(data.FieldTypeNullableFloat64, 0)
|
||||
timeField.Name = "time"
|
||||
valueField.Name = "value"
|
||||
|
||||
for _, val := range points {
|
||||
pointValues := val.([]interface{})
|
||||
|
||||
var value float64
|
||||
var value *float64
|
||||
|
||||
if valueFloat, err := strconv.ParseFloat(string(pointValues[0].(json.Number)), 64); err == nil {
|
||||
value = valueFloat
|
||||
if pointValues[0] != nil {
|
||||
if valueFloat, err := strconv.ParseFloat(string(pointValues[0].(json.Number)), 64); err == nil {
|
||||
value = &valueFloat
|
||||
}
|
||||
}
|
||||
|
||||
timeInt, err := strconv.ParseInt(string(pointValues[1].(json.Number)), 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
t := time.Unix(timeInt/int64(1e+3), (timeInt%int64(1e+3))*int64(1e+6))
|
||||
|
||||
if timeInt >= startTime && timeInt <= endTime {
|
||||
timeVec = append(timeVec, &t)
|
||||
floatVec = append(floatVec, &value)
|
||||
}
|
||||
timeField.Append(t)
|
||||
valueField.Append(value)
|
||||
}
|
||||
|
||||
frame.Fields = data.Fields{
|
||||
data.NewField("time", nil, timeVec),
|
||||
data.NewField("value", nil, floatVec),
|
||||
}
|
||||
frame.Fields = data.Fields{timeField, valueField}
|
||||
|
||||
respD := resp.Responses[q.RefID]
|
||||
respD.Frames = append(respD.Frames, frame)
|
||||
|
@ -185,6 +185,57 @@ func TestTestdataScenarios(t *testing.T) {
|
||||
require.True(t, maxNil)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("manual entry ", func(t *testing.T) {
|
||||
t.Run("should support nulls and return all data", func(t *testing.T) {
|
||||
timeRange := plugins.DataTimeRange{From: "5m", To: "now", Now: time.Now()}
|
||||
|
||||
query := backend.DataQuery{
|
||||
RefID: "A",
|
||||
TimeRange: backend.TimeRange{
|
||||
From: timeRange.MustGetFrom(),
|
||||
To: timeRange.MustGetTo(),
|
||||
},
|
||||
JSON: []byte(`{ "points": [
|
||||
[
|
||||
4, 1616557148000
|
||||
],
|
||||
[
|
||||
null, 1616558756000
|
||||
],
|
||||
[
|
||||
4, 1616561658000
|
||||
]] }`),
|
||||
}
|
||||
|
||||
req := &backend.QueryDataRequest{
|
||||
PluginContext: backend.PluginContext{},
|
||||
Queries: []backend.DataQuery{query},
|
||||
}
|
||||
|
||||
resp, err := p.handleManualEntryScenario(context.Background(), req)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
dResp, exists := resp.Responses[query.RefID]
|
||||
require.True(t, exists)
|
||||
require.NoError(t, dResp.Error)
|
||||
|
||||
require.Len(t, dResp.Frames, 1)
|
||||
frame := dResp.Frames[0]
|
||||
require.Len(t, frame.Fields, 2)
|
||||
require.Equal(t, "time", frame.Fields[0].Name)
|
||||
require.Equal(t, "value", frame.Fields[1].Name)
|
||||
require.Equal(t, 3, frame.Rows())
|
||||
|
||||
vals := frame.Fields[1]
|
||||
v, _ := vals.ConcreteAt(0)
|
||||
require.Equal(t, float64(4), v)
|
||||
require.Nil(t, vals.At(1))
|
||||
v, _ = vals.ConcreteAt(2)
|
||||
require.Equal(t, float64(4), v)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestParseLabels(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user