Files
grafana/pkg/services/ngalert/store/json_test.go
T
Alexander Akhmetov 872ed5dc9d Alerting: Add plugins:hide backend rule search parameter (#113706)
Alerting: Add plugins filter to list rules API
2026-01-05 13:17:51 +01:00

224 lines
5.4 KiB
Go

package store
import (
"testing"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/stretchr/testify/require"
)
func TestJsonEquals(t *testing.T) {
tests := []struct {
name string
dialect migrator.Dialect
column string
key string
value string
wantSQL string
wantArgs []any
}{
{
name: "MySQL",
dialect: migrator.NewMysqlDialect(),
column: "labels",
key: "team",
value: "alerting",
wantSQL: "JSON_UNQUOTE(JSON_EXTRACT(NULLIF(labels, ''), CONCAT('$.', ?))) = ?",
wantArgs: []any{"team", "alerting"},
},
{
name: "PostgreSQL",
dialect: migrator.NewPostgresDialect(),
column: "labels",
key: "team",
value: "alerting",
wantSQL: "jsonb_extract_path_text(NULLIF(labels, '')::jsonb, ?) = ?",
wantArgs: []any{"team", "alerting"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sql, args := jsonEquals(tt.dialect, tt.column, tt.key, tt.value)
require.Equal(t, tt.wantSQL, sql)
require.Equal(t, tt.wantArgs, args)
})
}
}
func TestJsonNotEquals(t *testing.T) {
tests := []struct {
name string
dialect migrator.Dialect
column string
key string
value string
wantSQL string
wantArgs []any
}{
{
name: "MySQL",
dialect: migrator.NewMysqlDialect(),
column: "labels",
key: "team",
value: "alerting",
wantSQL: "(JSON_UNQUOTE(JSON_EXTRACT(NULLIF(labels, ''), CONCAT('$.', ?))) IS NULL OR JSON_UNQUOTE(JSON_EXTRACT(NULLIF(labels, ''), CONCAT('$.', ?))) != ?)",
wantArgs: []any{"team", "team", "alerting"},
},
{
name: "PostgreSQL",
dialect: migrator.NewPostgresDialect(),
column: "labels",
key: "team",
value: "alerting",
wantSQL: "(jsonb_extract_path_text(NULLIF(labels, '')::jsonb, ?) IS NULL OR jsonb_extract_path_text(NULLIF(labels, '')::jsonb, ?) != ?)",
wantArgs: []any{"team", "team", "alerting"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sql, args := jsonNotEquals(tt.dialect, tt.column, tt.key, tt.value)
require.Equal(t, tt.wantSQL, sql)
require.Equal(t, tt.wantArgs, args)
})
}
}
func TestJsonKeyMissing(t *testing.T) {
tests := []struct {
name string
dialect migrator.Dialect
column string
key string
wantSQL string
wantArgs []any
}{
{
name: "MySQL",
dialect: migrator.NewMysqlDialect(),
column: "labels",
key: "team",
wantSQL: "JSON_EXTRACT(NULLIF(labels, ''), CONCAT('$.', ?)) IS NULL",
wantArgs: []any{"team"},
},
{
name: "PostgreSQL",
dialect: migrator.NewPostgresDialect(),
column: "labels",
key: "team",
wantSQL: "jsonb_extract_path_text(NULLIF(labels, '')::jsonb, ?) IS NULL",
wantArgs: []any{"team"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sql, args, err := jsonKeyMissing(tt.dialect, tt.column, tt.key)
require.NoError(t, err)
require.Equal(t, tt.wantSQL, sql)
require.Equal(t, tt.wantArgs, args)
})
}
}
func TestJsonKeyExists(t *testing.T) {
tests := []struct {
name string
dialect migrator.Dialect
column string
key string
wantSQL string
wantArgs []any
}{
{
name: "MySQL",
dialect: migrator.NewMysqlDialect(),
column: "labels",
key: "__grafana_origin",
wantSQL: "JSON_EXTRACT(NULLIF(labels, ''), CONCAT('$.', ?)) IS NOT NULL",
wantArgs: []any{"__grafana_origin"},
},
{
name: "PostgreSQL",
dialect: migrator.NewPostgresDialect(),
column: "labels",
key: "__grafana_origin",
wantSQL: "jsonb_extract_path_text(NULLIF(labels, '')::jsonb, ?) IS NOT NULL",
wantArgs: []any{"__grafana_origin"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sql, args, err := jsonKeyExists(tt.dialect, tt.column, tt.key)
require.NoError(t, err)
require.Equal(t, tt.wantSQL, sql)
require.Equal(t, tt.wantArgs, args)
})
}
}
func TestGlobEquals(t *testing.T) {
sql, args, err := globEquals("labels", "team", "alerting")
require.NoError(t, err)
require.Equal(t, "labels GLOB ?", sql)
require.Equal(t, []any{`*"team":"alerting"*`}, args)
}
func TestGlobNotEquals(t *testing.T) {
sql, args, err := globNotEquals("labels", "team", "alerting")
require.NoError(t, err)
require.Equal(t, "labels NOT GLOB ?", sql)
require.Equal(t, []any{`*"team":"alerting"*`}, args)
}
func TestGlobKeyMissing(t *testing.T) {
sql, args, err := globKeyMissing("labels", "team")
require.NoError(t, err)
require.Equal(t, "labels NOT GLOB ?", sql)
require.Equal(t, []any{`*"team":*`}, args)
}
func TestBuildGlobPattern(t *testing.T) {
tests := []struct {
name string
key string
value string
expected string
}{
{
name: "simple key-value",
key: "team",
value: "alerting",
expected: `"team":"alerting"`,
},
{
name: "empty value",
key: "empty",
value: "",
expected: `"empty":""`,
},
{
name: "special GLOB chars are escaped",
key: "key",
value: "*[?]",
expected: `"key":"[*][[][?]]"`,
},
{
name: "special chars are escaped",
key: "key",
value: "line1\nline2\\end\"quote",
expected: `"key":"line1\nline2\\end\"quote"`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pattern, err := buildGlobPattern(tt.key, tt.value)
require.NoError(t, err)
require.Equal(t, tt.expected, pattern)
})
}
}