3
0
mirror of https://github.com/grafana/grafana.git synced 2025-02-25 18:55:37 -06:00

fix(alerting): extend instant vector check for non-nullable types ()

This commit is contained in:
Jean-Philippe Quéméner 2024-09-17 13:20:40 +02:00 committed by GitHub
parent 41cd0f5180
commit 10314585ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 6 deletions
pkg/services/ngalert/eval

View File

@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
var logger = log.New("ngalert.eval")
@ -789,17 +790,20 @@ func buildResult(f *data.Frame, val *float64, ts time.Time) Result {
}
func scalarInstantVector(f *data.Frame) (*float64, bool) {
defaultReturnValue := 0.0
if len(f.Fields) != 2 {
return &defaultReturnValue, false
return nil, false
}
if f.Fields[0].Len() > 1 || (f.Fields[0].Type() != data.FieldTypeNullableTime && f.Fields[0].Type() != data.FieldTypeTime) {
return &defaultReturnValue, false
return nil, false
}
if f.Fields[1].Len() > 1 || f.Fields[1].Type() != data.FieldTypeNullableFloat64 {
return &defaultReturnValue, false
switch f.Fields[1].Type() {
case data.FieldTypeFloat64:
return util.Pointer(f.Fields[1].At(0).(float64)), true
case data.FieldTypeNullableFloat64:
return f.Fields[1].At(0).(*float64), true
default:
return nil, true
}
return f.Fields[1].At(0).(*float64), true
}
// AsDataFrame forms the EvalResults in Frame suitable for displaying in the table panel of the front end.

View File

@ -2,6 +2,7 @@ package eval
import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
@ -1342,6 +1343,76 @@ func TestCreate(t *testing.T) {
})
}
func TestQueryServiceResponse(t *testing.T) {
data := `
{
"results": {
"A": {
"status": 200,
"frames": [
{
"schema": {
"refId": "A",
"meta": {
"type": "numeric-multi",
"typeVersion": [
0,
1
],
"custom": {
"resultType": "scalar"
},
"executedQueryString": "Expr: 1\nStep: 15s"
},
"fields": [
{
"name": "Time",
"type": "time",
"typeInfo": {
"frame": "time.Time"
},
"config": {
"interval": 15000
}
},
{
"name": "Value",
"type": "number",
"typeInfo": {
"frame": "float64"
},
"labels": {},
"config": {
"displayNameFromDS": "1"
}
}
]
},
"data": {
"values": [
[
1719855251019
],
[
1
]
]
}
}
]
}
}
}
`
var s backend.QueryDataResponse
err := json.Unmarshal([]byte(data), &s)
require.NoError(t, err)
res := EvaluateAlert(&s, models.Condition{Condition: "A"}, time.Time{})
require.Equal(t, 1, len(res))
require.Equal(t, Alerting, res[0].State)
}
type fakeExpressionService struct {
hook func(ctx context.Context, now time.Time, pipeline expr.DataPipeline) (*backend.QueryDataResponse, error)
buildHook func(req *expr.Request) (expr.DataPipeline, error)