From 6e408f19fa576d45483deacc88508af92efbe58c Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 14 Nov 2024 11:24:33 +0300 Subject: [PATCH] POC/Provisioning: Add basic integration tests (#96424) --- .../apis/provisioning/provisioning_test.go | 102 ++++++++++++++++++ .../provisioning/testdata/local-devenv.yaml | 13 +++ 2 files changed, 115 insertions(+) create mode 100644 pkg/tests/apis/provisioning/provisioning_test.go create mode 100644 pkg/tests/apis/provisioning/testdata/local-devenv.yaml diff --git a/pkg/tests/apis/provisioning/provisioning_test.go b/pkg/tests/apis/provisioning/provisioning_test.go new file mode 100644 index 00000000000..7811dafe2fb --- /dev/null +++ b/pkg/tests/apis/provisioning/provisioning_test.go @@ -0,0 +1,102 @@ +package provisioning + +import ( + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/tests/apis" + "github.com/grafana/grafana/pkg/tests/testinfra" + "github.com/grafana/grafana/pkg/tests/testsuite" +) + +func TestMain(m *testing.M) { + testsuite.Run(m) +} + +func TestIntegrationProvisioning(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + + ctx := context.Background() + helper := apis.NewK8sTestHelper(t, testinfra.GrafanaOpts{ + AppModeProduction: false, // required for experimental APIs + EnableFeatureToggles: []string{ + featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs, // Required to start the example service + }, + }) + + t.Run("Check discovery client", func(t *testing.T) { + disco := helper.NewDiscoveryClient() + resources, err := disco.ServerResourcesForGroupVersion("provisioning.grafana.app/v0alpha1") + require.NoError(t, err) + + v1Disco, err := json.MarshalIndent(resources, "", " ") + require.NoError(t, err) + //fmt.Printf("%s", string(v1Disco)) + require.JSONEq(t, `{ + "kind": "APIResourceList", + "apiVersion": "v1", + "groupVersion": "provisioning.grafana.app/v0alpha1", + "resources": [ + { + "name": "repositories", + "singularName": "repository", + "namespaced": true, + "kind": "Repository", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + } + ] + }`, string(v1Disco)) + }) + + t.Run("Check basic create and get", func(t *testing.T) { + // Scope create+get + client := helper.GetResourceClient(apis.ResourceClientArgs{ + User: helper.Org1.Admin, + Namespace: "default", // actually org1 + GVR: schema.GroupVersionResource{ + Group: "provisioning.grafana.app", Version: "v0alpha1", Resource: "repositories", + }, + }) + createOptions := metav1.CreateOptions{FieldValidation: "Strict"} + r0, err := client.Resource.Create(ctx, + helper.LoadYAMLOrJSONFile("testdata/local-devenv.yaml"), + createOptions, + ) + + require.NoError(t, err) + require.Equal(t, "devenv", r0.GetName()) + r1, err := client.Resource.Get(ctx, "devenv", metav1.GetOptions{}) + require.NoError(t, err) + require.Equal(t, + mustNestedString(r0.Object, "spec", "local", "path"), + mustNestedString(r1.Object, "spec", "local", "path"), + ) + require.Equal(t, + "path/to/folder", // + mustNestedString(r1.Object, "spec", "local", "path"), + ) + }) +} + +func mustNestedString(obj map[string]interface{}, fields ...string) string { + v, _, _ := unstructured.NestedString(obj, fields...) + return v +} diff --git a/pkg/tests/apis/provisioning/testdata/local-devenv.yaml b/pkg/tests/apis/provisioning/testdata/local-devenv.yaml new file mode 100644 index 00000000000..8a9c3c382be --- /dev/null +++ b/pkg/tests/apis/provisioning/testdata/local-devenv.yaml @@ -0,0 +1,13 @@ +apiVersion: provisioning.grafana.app/v0alpha1 +kind: Repository +metadata: + name: devenv # anything is ok here... except yes or true -- they become boolean! +spec: + # title: Local devenv + # description: files from devenv + folder: abc # do we create a file with k8s name abc??? + + # provider: local + + local: + path: path/to/folder