mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 17:02:20 +08:00

--------- Co-authored-by: Todd Treece <360020+toddtreece@users.noreply.github.com> Co-authored-by: Haris Rozajac <haris.rozajac12@gmail.com> Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com>
215 lines
6.1 KiB
Go
215 lines
6.1 KiB
Go
package dashboard
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
"k8s.io/apiserver/pkg/admission"
|
|
|
|
dashv0 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v0alpha1"
|
|
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1beta1"
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v2alpha1"
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/migration"
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/migration/testutil"
|
|
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
)
|
|
|
|
func TestDashboardAPIBuilder_Mutate(t *testing.T) {
|
|
migration.Initialize(testutil.GetTestProvider())
|
|
tests := []struct {
|
|
name string
|
|
inputObj runtime.Object
|
|
operation admission.Operation
|
|
expectedID int64
|
|
migrationExpected bool
|
|
expectedTitle string
|
|
expectedError bool
|
|
fieldValidationMode string
|
|
}{
|
|
{
|
|
name: "should skip non-create/update operations",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(123),
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Delete,
|
|
expectedID: 0,
|
|
},
|
|
{
|
|
name: "v0 should extract id and set as label",
|
|
inputObj: &dashv0.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(123),
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedID: 123,
|
|
},
|
|
{
|
|
name: "v0 should not fail with invalid schema",
|
|
inputObj: &dashv0.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(123),
|
|
"revision": "revision-is-a-number",
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedID: 123,
|
|
},
|
|
{
|
|
name: "v1 should fail with invalid schema",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(123),
|
|
"revision": "revision-is-a-number",
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "v1 should not fail with invalid schema and FieldValidationIgnore is set",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(123),
|
|
"revision": "revision-is-a-number",
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
fieldValidationMode: metav1.FieldValidationIgnore,
|
|
expectedError: false,
|
|
expectedID: 123,
|
|
},
|
|
{
|
|
name: "v1 should migrate dashboard to the latest version, if possible, and set as label",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(456),
|
|
"schemaVersion": schemaversion.MIN_VERSION,
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedID: 456,
|
|
migrationExpected: true,
|
|
},
|
|
{
|
|
name: "v1 should error mutation hook if migration fails",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(456),
|
|
"schemaVersion": schemaversion.MIN_VERSION - 1,
|
|
},
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedError: true,
|
|
},
|
|
{
|
|
name: "v1 should not error mutation hook if migration fails and FieldValidationIgnore is set",
|
|
inputObj: &dashv1.Dashboard{
|
|
Spec: common.Unstructured{
|
|
Object: map[string]interface{}{
|
|
"id": float64(456),
|
|
"schemaVersion": schemaversion.MIN_VERSION - 1,
|
|
},
|
|
},
|
|
},
|
|
expectedID: 456,
|
|
operation: admission.Create,
|
|
fieldValidationMode: metav1.FieldValidationIgnore,
|
|
expectedError: false,
|
|
},
|
|
{
|
|
name: "v2 should set layout if it is not set",
|
|
inputObj: &v2alpha1.Dashboard{
|
|
Spec: v2alpha1.DashboardSpec{
|
|
Title: "test123",
|
|
},
|
|
},
|
|
operation: admission.Create,
|
|
expectedTitle: "test123",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
b := &DashboardsAPIBuilder{
|
|
features: featuremgmt.WithFeatures(),
|
|
}
|
|
var operationOptions runtime.Object
|
|
switch tt.operation {
|
|
case admission.Create:
|
|
operationOptions = &metav1.CreateOptions{FieldValidation: tt.fieldValidationMode}
|
|
case admission.Update:
|
|
operationOptions = &metav1.UpdateOptions{FieldValidation: tt.fieldValidationMode}
|
|
default:
|
|
operationOptions = nil
|
|
}
|
|
err := b.Mutate(context.Background(), admission.NewAttributesRecord(
|
|
tt.inputObj,
|
|
nil,
|
|
schema.GroupVersionKind{},
|
|
"",
|
|
"test",
|
|
schema.GroupVersionResource{},
|
|
"",
|
|
tt.operation,
|
|
operationOptions,
|
|
false,
|
|
nil,
|
|
), nil)
|
|
|
|
if tt.expectedError {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
|
|
if tt.operation == admission.Create || tt.operation == admission.Update {
|
|
meta, err := utils.MetaAccessor(tt.inputObj)
|
|
require.NoError(t, err)
|
|
require.Equal(t, tt.expectedID, meta.GetDeprecatedInternalID()) //nolint:staticcheck
|
|
|
|
switch v := tt.inputObj.(type) {
|
|
case *dashv0.Dashboard:
|
|
_, exists := v.Spec.Object["id"]
|
|
require.False(t, exists, "id should be removed from spec")
|
|
case *dashv1.Dashboard:
|
|
_, exists := v.Spec.Object["id"]
|
|
require.False(t, exists, "id should be removed from spec")
|
|
schemaVersion, ok := v.Spec.Object["schemaVersion"].(int)
|
|
require.True(t, ok, "schemaVersion should be an integer")
|
|
if tt.migrationExpected {
|
|
require.Equal(t, schemaversion.LATEST_VERSION, schemaVersion, "dashboard should be migrated to the latest version")
|
|
}
|
|
case *v2alpha1.Dashboard:
|
|
require.Equal(t, tt.expectedTitle, v.Spec.Title, "title should be set")
|
|
require.NotNil(t, v.Spec.Layout, "layout should be set")
|
|
require.NotNil(t, v.Spec.Layout.GridLayoutKind, "layout should be a GridLayout")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|