SQL Expressions: Instrumentation fix and extra testing (#110778)

This commit is contained in:
Kyle Brandt
2025-09-15 13:00:22 -04:00
committed by GitHub
parent 3b8ea08ad7
commit 4583402ba9
3 changed files with 59 additions and 5 deletions
+37 -3
View File
@@ -10,8 +10,10 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/expr/sql"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
)
@@ -91,6 +93,9 @@ func TestSQLService(t *testing.T) {
require.Error(t, rsp.Responses["B"].Error, "should return invalid sql error")
require.ErrorContains(t, rsp.Responses["B"].Error, "not in the allowed list of")
var sqlErr *sql.ErrorWithCategory
require.ErrorAs(t, rsp.Responses["B"].Error, &sqlErr)
require.Equal(t, sql.ErrCategoryBlockedNodeOrFunc, sqlErr.Category())
})
t.Run("parse error should be returned", func(t *testing.T) {
@@ -108,6 +113,9 @@ func TestSQLService(t *testing.T) {
require.Error(t, rsp.Responses["B"].Error, "should return sql error on parsing")
require.ErrorContains(t, rsp.Responses["B"].Error, "limit expression expected to be numeric")
var sqlErr *sql.ErrorWithCategory
require.ErrorAs(t, rsp.Responses["B"].Error, &sqlErr)
require.Equal(t, sql.ErrCategoryGeneralGMSError, sqlErr.Category())
})
}
@@ -170,8 +178,11 @@ func TestSQLServiceErrors(t *testing.T) {
}
t.Run("conversion failure (and therefore dependency error)", func(t *testing.T) {
s, req := newMockQueryService(resp,
reg := prometheus.NewPedanticRegistry()
s, req := newMockQueryServiceWithMetricsRegistry(resp,
newABSQLQueries(`SELECT * FROM tsMultiNoType`),
reg,
)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagSqlExpressions)
@@ -184,20 +195,38 @@ func TestSQLServiceErrors(t *testing.T) {
require.Error(t, rsp.Responses["tsMultiNoType"].Error, "should return conversion error on DS response")
require.ErrorContains(t, rsp.Responses["tsMultiNoType"].Error, "missing the data type")
var sqlErr *sql.ErrorWithCategory
require.ErrorAs(t, rsp.Responses["tsMultiNoType"].Error, &sqlErr)
require.Equal(t, sql.ErrCategoryInputConversion, sqlErr.Category())
require.Error(t, rsp.Responses["sqlExpression"].Error, "should return dependency error")
require.ErrorContains(t, rsp.Responses["sqlExpression"].Error, "dependency")
require.ErrorAs(t, rsp.Responses["sqlExpression"].Error, &sqlErr)
require.Equal(t, sql.ErrCategoryDependency, sqlErr.Category())
require.Equal(t, 0.0, counterVal(t, s.metrics.SqlCommandCount, "ok", "none"))
require.Equal(t, 1.0, counterVal(t, s.metrics.SqlCommandCount, "error", sql.ErrCategoryInputConversion))
require.Equal(t, 1.0, counterVal(t, s.metrics.SqlCommandInputCount, "error", "false", "test", "missing"))
})
t.Run("pipeline (expressions and DS queries) will fail if the table is not found, before execution of the sql expression", func(t *testing.T) {
s, req := newMockQueryService(resp,
newABSQLQueries(`SELECT * FROM nonExisting`),
reg := prometheus.NewPedanticRegistry()
s, req := newMockQueryServiceWithMetricsRegistry(resp,
newABSQLQueries(`SELECT * FROM nonExisting`), reg,
)
s.features = featuremgmt.WithFeatures(featuremgmt.FlagSqlExpressions)
_, err := s.BuildPipeline(t.Context(), req)
var sqlErr *sql.ErrorWithCategory
require.ErrorAs(t, err, &sqlErr)
require.Equal(t, sql.ErrCategoryTableNotFound, sqlErr.Category())
require.Error(t, err, "whole pipeline fails when selecting a dependency that does not exist")
// Metrics
require.Equal(t, 0.0, counterVal(t, s.metrics.SqlCommandCount, "ok", "none"))
require.Equal(t, 1.0, counterVal(t, s.metrics.SqlCommandCount, "error", sql.ErrCategoryTableNotFound))
})
t.Run("pipeline will fail if query is longer than the configured limit", func(t *testing.T) {
@@ -209,5 +238,10 @@ func TestSQLServiceErrors(t *testing.T) {
_, err := s.BuildPipeline(t.Context(), req)
require.ErrorContains(t, err, "exceeded the configured limit of 5 characters")
var sqlErr *sql.ErrorWithCategory
require.ErrorAs(t, err, &sqlErr)
require.Equal(t, sql.ErrCategoryQueryTooLong, sqlErr.Category())
require.Equal(t, 1.0, counterVal(t, s.metrics.SqlCommandCount, "error", sql.ErrCategoryQueryTooLong))
})
}