mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
TestData: support boolean and strings in CSV metric response (#33099)
This commit is contained in:
parent
fa620c1c38
commit
18bbbaf53e
@ -328,6 +328,47 @@ func (p *testDataPlugin) handleManualEntryScenario(ctx context.Context, req *bac
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func csvToFieldValues(stringInput string) (*data.Field, error) {
|
||||
parts := strings.Split(strings.ReplaceAll(stringInput, " ", ""), ",")
|
||||
if len(parts) < 1 {
|
||||
return nil, fmt.Errorf("csv must have at least one value")
|
||||
}
|
||||
|
||||
first := parts[0]
|
||||
if first == "T" || first == "F" {
|
||||
field := data.NewFieldFromFieldType(data.FieldTypeNullableBool, len(parts))
|
||||
for idx, strVal := range parts {
|
||||
if strVal == "null" || strVal == "" {
|
||||
continue
|
||||
}
|
||||
field.SetConcrete(idx, strVal == "T")
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
// If we can not parse the first value as a number, assume strings
|
||||
_, err := strconv.ParseFloat(first, 64)
|
||||
if err != nil {
|
||||
field := data.NewFieldFromFieldType(data.FieldTypeNullableString, len(parts))
|
||||
for idx, strVal := range parts {
|
||||
if strVal == "null" || strVal == "" {
|
||||
continue
|
||||
}
|
||||
field.SetConcrete(idx, strVal)
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
// Set any valid numbers
|
||||
field := data.NewFieldFromFieldType(data.FieldTypeNullableFloat64, len(parts))
|
||||
for idx, strVal := range parts {
|
||||
if val, err := strconv.ParseFloat(strVal, 64); err == nil {
|
||||
field.SetConcrete(idx, val)
|
||||
}
|
||||
}
|
||||
return field, nil
|
||||
}
|
||||
|
||||
func (p *testDataPlugin) handleCSVMetricValuesScenario(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
resp := backend.NewQueryDataResponse()
|
||||
|
||||
@ -338,38 +379,32 @@ func (p *testDataPlugin) handleCSVMetricValuesScenario(ctx context.Context, req
|
||||
}
|
||||
|
||||
stringInput := model.Get("stringInput").MustString()
|
||||
stringInput = strings.ReplaceAll(stringInput, " ", "")
|
||||
|
||||
var values []*float64
|
||||
for _, strVal := range strings.Split(stringInput, ",") {
|
||||
if strVal == "null" {
|
||||
values = append(values, nil)
|
||||
}
|
||||
if val, err := strconv.ParseFloat(strVal, 64); err == nil {
|
||||
values = append(values, &val)
|
||||
}
|
||||
valueField, err := csvToFieldValues(stringInput)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valueField.Name = frameNameForQuery(q, model, 0)
|
||||
|
||||
if len(values) == 0 {
|
||||
return resp, nil
|
||||
}
|
||||
timeField := data.NewFieldFromFieldType(data.FieldTypeTime, valueField.Len())
|
||||
timeField.Name = "time"
|
||||
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("time", nil, []*time.Time{}),
|
||||
data.NewField(frameNameForQuery(q, model, 0), nil, []*float64{}))
|
||||
startTime := q.TimeRange.From.UnixNano() / int64(time.Millisecond)
|
||||
endTime := q.TimeRange.To.UnixNano() / int64(time.Millisecond)
|
||||
count := valueField.Len()
|
||||
var step int64 = 0
|
||||
if len(values) > 1 {
|
||||
step = (endTime - startTime) / int64(len(values)-1)
|
||||
if count > 1 {
|
||||
step = (endTime - startTime) / int64(count-1)
|
||||
}
|
||||
|
||||
for _, val := range values {
|
||||
for i := 0; i < count; i++ {
|
||||
t := time.Unix(startTime/int64(1e+3), (startTime%int64(1e+3))*int64(1e+6))
|
||||
frame.AppendRow(&t, val)
|
||||
timeField.Set(i, t)
|
||||
startTime += step
|
||||
}
|
||||
|
||||
frame := data.NewFrame("", timeField, valueField)
|
||||
|
||||
respD := resp.Responses[q.RefID]
|
||||
respD.Frames = append(respD.Frames, frame)
|
||||
resp.Responses[q.RefID] = respD
|
||||
|
@ -263,3 +263,32 @@ func TestParseLabels(t *testing.T) {
|
||||
assert.Equal(t, expectedTags, parseLabels(model), fmt.Sprintf("Actual tags in test case %d doesn't match expected tags", i+1))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadCSV(t *testing.T) {
|
||||
fBool, err := csvToFieldValues("T, F,F,T ,")
|
||||
require.NoError(t, err)
|
||||
|
||||
fNum, err := csvToFieldValues("1,2,,4,5")
|
||||
require.NoError(t, err)
|
||||
|
||||
fStr, err := csvToFieldValues("a,b,,,c")
|
||||
require.NoError(t, err)
|
||||
|
||||
frame := data.NewFrame("", fBool, fNum, fStr)
|
||||
out, err := data.FrameToJSON(frame, true, true)
|
||||
require.NoError(t, err)
|
||||
|
||||
// require.Equal(t, "", string(out))
|
||||
|
||||
require.JSONEq(t, `{"schema":{
|
||||
"fields":[
|
||||
{"type":"bool","typeInfo":{"frame":"bool","nullable":true}},
|
||||
{"type":"number","typeInfo":{"frame":"float64","nullable":true}},
|
||||
{"type":"string","typeInfo":{"frame":"string","nullable":true}}
|
||||
]},"data":{
|
||||
"values":[
|
||||
[true,false,false,true,null],
|
||||
[1,2,null,4,5],
|
||||
["a","b",null,null,"c"]
|
||||
]}}`, string(out))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user