From cf2e0ff51b75965740bdb7c955f691d59095aa85 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 25 Jun 2024 14:48:06 -0700 Subject: [PATCH 01/10] test(scorecard): add sample jfr for scorecard --- Makefile | 1 + .../scorecard/testdata/scorecard_sample.jfr | Bin 0 -> 359714 bytes 2 files changed, 1 insertion(+) create mode 100644 internal/test/scorecard/testdata/scorecard_sample.jfr diff --git a/Makefile b/Makefile index d8522d72f..ea9ba4df1 100644 --- a/Makefile +++ b/Makefile @@ -226,6 +226,7 @@ $(KUSTOMIZE) build internal/images/custom-scorecard-tests/rbac/ | $(CLUSTER_CLIE --docker-username="$(SCORECARD_REGISTRY_USERNAME)" --docker-password="$(SCORECARD_REGISTRY_PASSWORD)"; \ $(CLUSTER_CLIENT) patch sa cryostat-scorecard -n $(SCORECARD_NAMESPACE) -p '{"imagePullSecrets": [{"name": "registry-key"}]}'; \ fi +$(CLUSTER_CLIENT) create -n $(SCORECARD_NAMESPACE) configmap scorecard-jfr-cm --from-file=internal/test/scorecard/testdata/scorecard_sample.jfr $(OPERATOR_SDK) run bundle -n $(SCORECARD_NAMESPACE) --timeout 20m $(BUNDLE_IMG) --security-context-config=restricted $(SCORECARD_ARGS) endef diff --git a/internal/test/scorecard/testdata/scorecard_sample.jfr b/internal/test/scorecard/testdata/scorecard_sample.jfr new file mode 100644 index 0000000000000000000000000000000000000000..8cb669b33e322471ac25c534c0bdad88d010b089 GIT binary patch literal 359714 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𝔚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 literal 0 HcmV?d00001 From 99247ac3d1978ca8b48f6359500d8f4abf6b64e4 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 25 Jun 2024 14:56:42 -0700 Subject: [PATCH 02/10] test(scorecard): registry grafana scorecard tests --- ...yostat-operator.clusterserviceversion.yaml | 2 +- bundle/tests/scorecard/config.yaml | 22 ++++++++++++++----- config/scorecard/patches/custom.config.yaml | 22 ++++++++++++++----- hack/custom.config.yaml.in | 10 +++++++++ .../images/custom-scorecard-tests/main.go | 4 ++++ internal/test/scorecard/tests.go | 14 ++++++++++++ 6 files changed, 61 insertions(+), 13 deletions(-) diff --git a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml index be7702234..28beac79f 100644 --- a/bundle/manifests/cryostat-operator.clusterserviceversion.yaml +++ b/bundle/manifests/cryostat-operator.clusterserviceversion.yaml @@ -30,7 +30,7 @@ metadata: capabilities: Seamless Upgrades categories: Monitoring, Developer Tools containerImage: quay.io/cryostat/cryostat-operator:4.0.0-dev - createdAt: "2024-09-11T17:33:08Z" + createdAt: "2024-09-12T23:20:42Z" description: JVM monitoring and profiling tool operatorframework.io/initialization-resource: |- { diff --git a/bundle/tests/scorecard/config.yaml b/bundle/tests/scorecard/config.yaml index cc6e4cb49..cdb33e165 100644 --- a/bundle/tests/scorecard/config.yaml +++ b/bundle/tests/scorecard/config.yaml @@ -70,7 +70,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - operator-install - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: operator-install @@ -80,7 +80,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: cryostat-cr @@ -90,7 +90,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: cryostat-multi-namespace @@ -100,7 +100,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: cryostat-recording @@ -110,7 +110,7 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: cryostat-config-change @@ -120,13 +120,23 @@ stages: - entrypoint: - cryostat-scorecard-tests - cryostat-report - image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313 + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 labels: suite: cryostat test: cryostat-report storage: spec: mountPath: {} + - entrypoint: + - cryostat-scorecard-tests + - cryostat-grafana + image: quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617 + labels: + suite: cryostat + test: cryostat-grafana + storage: + spec: + mountPath: {} storage: spec: mountPath: {} diff --git a/config/scorecard/patches/custom.config.yaml b/config/scorecard/patches/custom.config.yaml index bec7ea861..38432bfc8 100644 --- a/config/scorecard/patches/custom.config.yaml +++ b/config/scorecard/patches/custom.config.yaml @@ -8,7 +8,7 @@ entrypoint: - cryostat-scorecard-tests - operator-install - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: operator-install @@ -18,7 +18,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-cr - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: cryostat-cr @@ -28,7 +28,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-multi-namespace - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: cryostat-multi-namespace @@ -38,7 +38,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-recording - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: cryostat-recording @@ -48,7 +48,7 @@ entrypoint: - cryostat-scorecard-tests - cryostat-config-change - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: cryostat-config-change @@ -58,7 +58,17 @@ entrypoint: - cryostat-scorecard-tests - cryostat-report - image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240911172313" + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" labels: suite: cryostat test: cryostat-report +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-grafana + image: "quay.io/cryostat/cryostat-operator-scorecard:4.0.0-20240912231617" + labels: + suite: cryostat + test: cryostat-grafana diff --git a/hack/custom.config.yaml.in b/hack/custom.config.yaml.in index 75306a910..464dcbbcd 100644 --- a/hack/custom.config.yaml.in +++ b/hack/custom.config.yaml.in @@ -61,3 +61,13 @@ labels: suite: cryostat test: cryostat-report +- op: add + path: /stages/1/tests/- + value: + entrypoint: + - cryostat-scorecard-tests + - cryostat-grafana + image: "${CUSTOM_SCORECARD_IMG}" + labels: + suite: cryostat + test: cryostat-grafana diff --git a/internal/images/custom-scorecard-tests/main.go b/internal/images/custom-scorecard-tests/main.go index 3ef4d98e4..1091d5276 100644 --- a/internal/images/custom-scorecard-tests/main.go +++ b/internal/images/custom-scorecard-tests/main.go @@ -90,6 +90,7 @@ func printValidTests() []scapiv1alpha3.TestResult { tests.CryostatRecordingTestName, tests.CryostatConfigChangeTestName, tests.CryostatReportTestName, + tests.CryostatGrafanaTestName, }, ",")) result.Errors = append(result.Errors, str) @@ -105,6 +106,7 @@ func validateTests(testNames []string) bool { case tests.CryostatRecordingTestName: case tests.CryostatConfigChangeTestName: case tests.CryostatReportTestName: + case tests.CryostatGrafanaTestName: default: return false } @@ -131,6 +133,8 @@ func runTests(testNames []string, bundle *apimanifests.Bundle, namespace string, results = append(results, *tests.CryostatConfigChangeTest(bundle, namespace, openShiftCertManager)) case tests.CryostatReportTestName: results = append(results, *tests.CryostatReportTest(bundle, namespace, openShiftCertManager)) + case tests.CryostatGrafanaTestName: + results = append(results, *tests.CryostatGrafanaTest(bundle, namespace, openShiftCertManager)) default: log.Fatalf("unknown test found: %s", testName) } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 55b90f899..4db9bacf7 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -32,6 +32,7 @@ const ( CryostatRecordingTestName string = "cryostat-recording" CryostatConfigChangeTestName string = "cryostat-config-change" CryostatReportTestName string = "cryostat-report" + CryostatGrafanaTestName string = "cryostat-grafana" ) // OperatorInstallTest checks that the operator installed correctly @@ -304,3 +305,16 @@ func CryostatReportTest(bundle *apimanifests.Bundle, namespace string, openShift return r.TestResult } + +func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShiftCertManager bool) *scapiv1alpha3.TestResult { + r := newTestResources(CryostatGrafanaTestName, namespace) + + err := r.setupCRTestResources(openShiftCertManager) + if err != nil { + return r.fail(fmt.Sprintf("failed to set up %s test: %s", CryostatGrafanaTestName, err.Error())) + } + + defer r.cleanupAndLogs() + + return r.TestResult +} From d97495f743221a0396bc72ae77931ca101d01489 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 27 Jun 2024 03:22:06 -0700 Subject: [PATCH 03/10] test(scorecard): added archive upload fn to recording client --- Makefile | 1 - internal/test/scorecard/clients.go | 61 +++++++++++++++++++------ internal/test/scorecard/common_utils.go | 2 + internal/test/scorecard/tests.go | 35 ++++++++++++++ 4 files changed, 84 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index ea9ba4df1..e75ff2607 100644 --- a/Makefile +++ b/Makefile @@ -236,7 +236,6 @@ function cleanup { \ set +e; \ $(OPERATOR_SDK) cleanup -n $(SCORECARD_NAMESPACE) $(OPERATOR_NAME); \ $(KUSTOMIZE) build internal/images/custom-scorecard-tests/rbac/ | $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -f -; \ - $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) -n $(SCORECARD_NAMESPACE) secret registry-key; \ $(CLUSTER_CLIENT) delete --ignore-not-found=$(ignore-not-found) namespace $(SCORECARD_NAMESPACE); \ )\ } diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 734a4e42f..711501484 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -15,11 +15,13 @@ package scorecard import ( + "bytes" "context" "encoding/json" "errors" "fmt" "io" + "mime/multipart" "net/http" "net/url" "strings" @@ -271,7 +273,7 @@ func (client *TargetClient) Create(ctx context.Context, options *Target) (*Targe header.Add("Accept", "*/*") body := options.ToFormData() - resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), strings.NewReader(body), header) if err != nil { return nil, err } @@ -341,7 +343,7 @@ func (client *RecordingClient) Create(ctx context.Context, target *Target, optio header.Add("Content-Type", "application/x-www-form-urlencoded") header.Add("Accept", "*/*") - resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), strings.NewReader(body), header) if err != nil { return nil, err } @@ -367,7 +369,7 @@ func (client *RecordingClient) Archive(ctx context.Context, target *Target, reco header.Add("Content-Type", "text/plain") header.Add("Accept", "*/*") - resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), strings.NewReader(body), header) if err != nil { return "", err } @@ -392,7 +394,7 @@ func (client *RecordingClient) Stop(ctx context.Context, target *Target, recordi header.Add("Content-Type", "text/plain") header.Add("Accept", "*/*") - resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPatch, url.String(), strings.NewReader(body), header) if err != nil { return err } @@ -485,13 +487,12 @@ func (client *RecordingClient) ListArchives(ctx context.Context, target *Target) if err != nil { return nil, fmt.Errorf("failed to construct graph query: %s", err.Error()) } - body := string(queryJSON) header := make(http.Header) header.Add("Content-Type", "application/json") header.Add("Accept", "*/*") - resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), bytes.NewReader(queryJSON), header) if err != nil { return nil, err } @@ -510,6 +511,42 @@ func (client *RecordingClient) ListArchives(ctx context.Context, target *Target) return graphQLResponse.Data.TargetNodes[0].Target.ArchivedRecordings.Data, nil } +func (client *RecordingClient) UploadArchive(ctx context.Context, archiveContent []byte) error { + url := client.Base.JoinPath("/api/v1/recordings") + + body := &bytes.Buffer{} + mp := multipart.NewWriter(body) + + part, err := mp.CreateFormFile("recording", jfrFilename) + if err != nil { + return err + } + + if _, err = part.Write(archiveContent); err != nil { + return err + } + + if err = mp.Close(); err != nil { + return err + } + + header := make(http.Header) + header.Add("Content-Type", mp.FormDataContentType()) + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), body, header) + if err != nil { + return err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + return nil +} + type CredentialClient struct { *commonCryostatRESTClient } @@ -520,7 +557,7 @@ func (client *CredentialClient) Create(ctx context.Context, credential *Credenti header := make(http.Header) header.Add("Content-Type", "application/x-www-form-urlencoded") - resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), &body, header) + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), strings.NewReader(body), header) if err != nil { return err } @@ -582,12 +619,8 @@ func NewHttpClient() *http.Client { return client } -func NewHttpRequest(ctx context.Context, method string, url string, body *string, header http.Header) (*http.Request, error) { - var reqBody io.Reader - if body != nil { - reqBody = strings.NewReader(*body) - } - req, err := http.NewRequestWithContext(ctx, method, url, reqBody) +func NewHttpRequest(ctx context.Context, method string, url string, body io.Reader, header http.Header) (*http.Request, error) { + req, err := http.NewRequestWithContext(ctx, method, url, body) if err != nil { return nil, err } @@ -611,7 +644,7 @@ func StatusOK(statusCode int) bool { return statusCode >= 200 && statusCode < 300 } -func SendRequest(ctx context.Context, httpClient *http.Client, method string, url string, body *string, header http.Header) (*http.Response, error) { +func SendRequest(ctx context.Context, httpClient *http.Client, method string, url string, body io.Reader, header http.Header) (*http.Response, error) { var response *http.Response err := wait.PollUntilContextCancel(ctx, time.Second, true, func(ctx context.Context) (done bool, err error) { // Create a new request diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index 1ee9ecc93..d56bcb0e2 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -42,6 +42,8 @@ import ( const ( operatorDeploymentName string = "cryostat-operator-controller" + jfrConfigMapName string = "scorecard-jfr-cm" + jfrFilename string = "scorecard_sample.jfr" testTimeout time.Duration = time.Minute * 10 ) diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 4db9bacf7..c1b7bfb2b 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -23,6 +23,7 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -316,5 +317,39 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif defer r.cleanupAndLogs() + // Create a default Cryostat CR + cr, err := r.createAndWaitTillCryostatAvailable(r.newCryostatCR()) + if err != nil { + return r.fail(fmt.Sprintf("failed to determine application URL: %s", err.Error())) + } + + err = r.StartLogs(cr) + if err != nil { + r.Log += fmt.Sprintf("failed to retrieve logs for the application: %s", err.Error()) + } + + base, err := url.Parse(cr.Status.ApplicationURL) + if err != nil { + return r.fail(fmt.Sprintf("application URL is invalid: %s", err.Error())) + } + + err = r.waitTillCryostatReady(base) + if err != nil { + return r.fail(fmt.Sprintf("failed to reach the application: %s", err.Error())) + } + + apiClient := NewCryostatRESTClientset(base) + + // Get JFR data + cm, err := r.Client.CoreV1().ConfigMaps(namespace).Get(context.Background(), jfrConfigMapName, v1.GetOptions{}) + if err != nil { + return r.fail(fmt.Sprintf("failed to get ConfigMap containing JFR data: %s", err.Error())) + } + + err = apiClient.Recordings().UploadArchive(context.Background(), cm.BinaryData[jfrFilename]) + if err != nil { + return r.fail(fmt.Sprintf("failed to upload archive: %s", err.Error())) + } + return r.TestResult } From 1b4986f00ec4a9f417b1657bd93521550c9c790c Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Thu, 27 Jun 2024 22:33:01 -0700 Subject: [PATCH 04/10] test(scorecard): added fn to load uploaded jfr for viewing in Grafana --- internal/test/scorecard/clients.go | 17 +++++++++++++++++ internal/test/scorecard/tests.go | 7 ++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 711501484..fe4ff0bc9 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -547,6 +547,23 @@ func (client *RecordingClient) UploadArchive(ctx context.Context, archiveContent return nil } +func (client *RecordingClient) LoadUploadedArchiveToGrafana(ctx context.Context, archiveName string) error { + url := client.Base.JoinPath(fmt.Sprintf("/api/beta/recordings/uploads/%s/upload", archiveName)) + header := make(http.Header) + + resp, err := SendRequest(ctx, client.Client, http.MethodPost, url.String(), nil, header) + if err != nil { + return err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + return nil +} + type CredentialClient struct { *commonCryostatRESTClient } diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index c1b7bfb2b..05ee61513 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -348,7 +348,12 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif err = apiClient.Recordings().UploadArchive(context.Background(), cm.BinaryData[jfrFilename]) if err != nil { - return r.fail(fmt.Sprintf("failed to upload archive: %s", err.Error())) + return r.fail(fmt.Sprintf("failed to upload archive %s: %s", jfrFilename, err.Error())) + } + + err = apiClient.Recordings().LoadUploadedArchiveToGrafana(context.Background(), jfrFilename) + if err != nil { + return r.fail(fmt.Sprintf("failed to load archive %s to grafana: %s", jfrFilename, err.Error())) } return r.TestResult From bcb03070c65b29b8819ea110d4a82c8dbd888ac5 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 3 Jul 2024 18:14:30 -0700 Subject: [PATCH 05/10] test(scorecard): jfr-datasource validations --- internal/test/scorecard/clients.go | 38 +++++++++++++++++++++++ internal/test/scorecard/tests.go | 10 +++++++ internal/test/scorecard/types.go | 48 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index fe4ff0bc9..3e8e513af 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -199,6 +199,7 @@ type CryostatRESTClientset struct { TargetClient *TargetClient RecordingClient *RecordingClient CredentialClient *CredentialClient + GrafanaClient *GrafanaClient } func (c *CryostatRESTClientset) Targets() *TargetClient { @@ -213,6 +214,10 @@ func (c *CryostatRESTClientset) Credential() *CredentialClient { return c.CredentialClient } +func (c *CryostatRESTClientset) Grafana() *GrafanaClient { + return c.GrafanaClient +} + func NewCryostatRESTClientset(base *url.URL) *CryostatRESTClientset { commonClient := &commonCryostatRESTClient{ Base: base, @@ -229,6 +234,10 @@ func NewCryostatRESTClientset(base *url.URL) *CryostatRESTClientset { CredentialClient: &CredentialClient{ commonCryostatRESTClient: commonClient, }, + GrafanaClient: &GrafanaClient{ + commonCryostatRESTClient: commonClient, + Prefix: "grafana", + }, } } @@ -587,6 +596,35 @@ func (client *CredentialClient) Create(ctx context.Context, credential *Credenti return nil } +// Client for Grafana API +type GrafanaClient struct { + Prefix string + *commonCryostatRESTClient +} + +func (client *GrafanaClient) GetDatasourceByName(ctx context.Context, name string) (*DataSource, error) { + url := client.Base.JoinPath(client.Prefix, "api/datasources/name", GRAFANA_DATASOURCE_NAME) + header := make(http.Header) + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodGet, url.String(), nil, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + datasource := &DataSource{} + if err = ReadJSON(resp, datasource); err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return datasource, nil +} + func ReadJSON(resp *http.Response, result interface{}) error { body, err := io.ReadAll(resp.Body) if err != nil { diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index 05ee61513..cf011c0ca 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -356,5 +356,15 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif return r.fail(fmt.Sprintf("failed to load archive %s to grafana: %s", jfrFilename, err.Error())) } + // Validate datasource + datasource, err := apiClient.Grafana().GetDatasourceByName(context.Background(), GRAFANA_DATASOURCE_NAME) + if err != nil { + return r.fail(fmt.Sprintf("failed to get datasource %s: %s", GRAFANA_DATASOURCE_NAME, err.Error())) + } + + if err = datasource.Valid(); err != nil { + return r.fail(fmt.Sprintf("datasource %s is invalid: %s", GRAFANA_DATASOURCE_NAME, err.Error())) + } + return r.TestResult } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index 8c26603de..42b65ae13 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -17,6 +17,7 @@ package scorecard import ( "encoding/json" "errors" + "fmt" "net/url" "strconv" ) @@ -152,3 +153,50 @@ type ArchiveGraphQLResponse struct { } `json:"targetNodes"` } `json:"data"` } + +const ( + GRAFANA_DATASOURCE_NAME = "jfr-datasource" + GRAFANA_DATASOURCE_URL = "http://127.0.0.1:8989" + GRAFANA_DATASOURCE_TYPE = "grafana-simple-json-datasource" + GRAFANA_DATASOURCE_ACCESS = "proxy" +) + +// Grafana types +type DataSource struct { + ID int64 `json:"id"` + UID string `json:"uid"` + Name string `json:"name"` + + Type string `json:"type"` + + URL string `json:"url"` + Access string `json:"access"` + + ReadOnly bool `json:"readOnly"` + IsDefault bool `json:"isDefault"` + BasicAuth bool `json:"basicAuth"` +} + +func (ds *DataSource) Valid() error { + if ds.Name != GRAFANA_DATASOURCE_NAME { + return fmt.Errorf("expected datasource name %s, but got %s", GRAFANA_DATASOURCE_NAME, ds.Name) + } + + if ds.Type != GRAFANA_DATASOURCE_TYPE { + return fmt.Errorf("expected datasource type %s, but got %s", GRAFANA_DATASOURCE_TYPE, ds.Type) + } + + if ds.URL != GRAFANA_DATASOURCE_URL { + return fmt.Errorf("expected datasource url %s, but got %s", GRAFANA_DATASOURCE_URL, ds.URL) + } + + if ds.Access != GRAFANA_DATASOURCE_ACCESS { + return fmt.Errorf("expected datasource access %s, but got %s", GRAFANA_DATASOURCE_ACCESS, ds.Access) + } + + if ds.BasicAuth { + return errors.New("expected basicAuth to be disabled, but got enabled") + } + + return nil +} From b608152ea70d71dd0a0c85c054ede7ca282e0630 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 3 Jul 2024 23:15:29 -0700 Subject: [PATCH 06/10] test(scorecard): increase nginx proxy size limit --- internal/test/scorecard/clients.go | 6 +++--- internal/test/scorecard/common_utils.go | 1 + internal/test/scorecard/tests.go | 4 ++-- internal/test/scorecard/types.go | 13 ++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 3e8e513af..108394d31 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -236,7 +236,7 @@ func NewCryostatRESTClientset(base *url.URL) *CryostatRESTClientset { }, GrafanaClient: &GrafanaClient{ commonCryostatRESTClient: commonClient, - Prefix: "grafana", + BasePath: "grafana", }, } } @@ -598,12 +598,12 @@ func (client *CredentialClient) Create(ctx context.Context, credential *Credenti // Client for Grafana API type GrafanaClient struct { - Prefix string + BasePath string *commonCryostatRESTClient } func (client *GrafanaClient) GetDatasourceByName(ctx context.Context, name string) (*DataSource, error) { - url := client.Base.JoinPath(client.Prefix, "api/datasources/name", GRAFANA_DATASOURCE_NAME) + url := client.Base.JoinPath(client.BasePath, "api/datasources/name", GRAFANA_DATASOURCE_NAME) header := make(http.Header) header.Add("Accept", "*/*") diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index d56bcb0e2..c7d959ac3 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -299,6 +299,7 @@ func configureIngress(name string, cryostatSpec *operatorv1beta2.CryostatSpec) { CoreConfig: &operatorv1beta2.NetworkConfiguration{ Annotations: map[string]string{ "nginx.ingress.kubernetes.io/backend-protocol": "HTTPS", + "nginx.ingress.kubernetes.io/proxy-body-size": "10m", }, IngressSpec: &netv1.IngressSpec{ TLS: []netv1.IngressTLS{{}}, diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index cf011c0ca..ad6c986ef 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -23,7 +23,7 @@ import ( operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -341,7 +341,7 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif apiClient := NewCryostatRESTClientset(base) // Get JFR data - cm, err := r.Client.CoreV1().ConfigMaps(namespace).Get(context.Background(), jfrConfigMapName, v1.GetOptions{}) + cm, err := r.Client.CoreV1().ConfigMaps(namespace).Get(context.Background(), jfrConfigMapName, metav1.GetOptions{}) if err != nil { return r.fail(fmt.Sprintf("failed to get ConfigMap containing JFR data: %s", err.Error())) } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index 42b65ae13..e8b9cf722 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -155,13 +155,14 @@ type ArchiveGraphQLResponse struct { } const ( + GRAFANA_DASHBOARD_UID = "main" + GRAFANA_DASHBOARD_TITLE = "Cryostat Dashboard" GRAFANA_DATASOURCE_NAME = "jfr-datasource" - GRAFANA_DATASOURCE_URL = "http://127.0.0.1:8989" GRAFANA_DATASOURCE_TYPE = "grafana-simple-json-datasource" GRAFANA_DATASOURCE_ACCESS = "proxy" ) -// Grafana types +// DataSource represents a Grafana data source type DataSource struct { ID int64 `json:"id"` UID string `json:"uid"` @@ -172,8 +173,6 @@ type DataSource struct { URL string `json:"url"` Access string `json:"access"` - ReadOnly bool `json:"readOnly"` - IsDefault bool `json:"isDefault"` BasicAuth bool `json:"basicAuth"` } @@ -186,12 +185,12 @@ func (ds *DataSource) Valid() error { return fmt.Errorf("expected datasource type %s, but got %s", GRAFANA_DATASOURCE_TYPE, ds.Type) } - if ds.URL != GRAFANA_DATASOURCE_URL { - return fmt.Errorf("expected datasource url %s, but got %s", GRAFANA_DATASOURCE_URL, ds.URL) + if len(ds.URL) == 0 { + return errors.New("expected datasource url, but got empty") } if ds.Access != GRAFANA_DATASOURCE_ACCESS { - return fmt.Errorf("expected datasource access %s, but got %s", GRAFANA_DATASOURCE_ACCESS, ds.Access) + return fmt.Errorf("expected datasource access mode %s, but got %s", GRAFANA_DATASOURCE_ACCESS, ds.Access) } if ds.BasicAuth { From 9109a88ef7098fc6cddf446f3770e4491c44136f Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 3 Jul 2024 23:28:48 -0700 Subject: [PATCH 07/10] test(scorecard): cryostat dashboard validations --- internal/test/scorecard/clients.go | 23 ++++++++++++ internal/test/scorecard/tests.go | 9 +++++ internal/test/scorecard/types.go | 58 +++++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 108394d31..6d786fa0f 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -602,6 +602,29 @@ type GrafanaClient struct { *commonCryostatRESTClient } +func (client *GrafanaClient) GetDashboardByUID(ctx context.Context, uid string) (*DashBoard, error) { + url := client.Base.JoinPath(client.BasePath, "api/dashboards/uid", uid) + header := make(http.Header) + header.Add("Accept", "*/*") + + resp, err := SendRequest(ctx, client.Client, http.MethodGet, url.String(), nil, header) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if !StatusOK(resp.StatusCode) { + return nil, fmt.Errorf("API request failed with status code: %d, response body: %s, and headers:\n%s", resp.StatusCode, ReadError(resp), ReadHeader(resp)) + } + + dashboard := &DashBoard{} + if err = ReadJSON(resp, dashboard); err != nil { + return nil, fmt.Errorf("failed to read response body: %s", err.Error()) + } + + return dashboard, nil +} + func (client *GrafanaClient) GetDatasourceByName(ctx context.Context, name string) (*DataSource, error) { url := client.Base.JoinPath(client.BasePath, "api/datasources/name", GRAFANA_DATASOURCE_NAME) header := make(http.Header) diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index ad6c986ef..cf0e2687d 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -366,5 +366,14 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif return r.fail(fmt.Sprintf("datasource %s is invalid: %s", GRAFANA_DATASOURCE_NAME, err.Error())) } + dashboard, err := apiClient.Grafana().GetDashboardByUID(context.Background(), GRAFANA_DASHBOARD_UID) + if err != nil { + return r.fail(fmt.Sprintf("failed to get dashboard %s: %s", GRAFANA_DASHBOARD_UID, err.Error())) + } + + if err = dashboard.Valid(); err != nil { + return r.fail(fmt.Sprintf("dashboard %s is invalid: %s", GRAFANA_DASHBOARD_UID, err.Error())) + } + return r.TestResult } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index e8b9cf722..132d356dd 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -164,7 +164,7 @@ const ( // DataSource represents a Grafana data source type DataSource struct { - ID int64 `json:"id"` + ID uint32 `json:"id"` UID string `json:"uid"` Name string `json:"name"` @@ -199,3 +199,59 @@ func (ds *DataSource) Valid() error { return nil } + +// DashBoard represents a Grafana dashboard +type DashBoard struct { + DashBoardMeta `json:"meta"` + DashBoardInfo `json:"dashboard"` +} + +type DashBoardMeta struct { + Slug string `json:"slug"` + URL string `json:"url"` + Provisioned bool `json:"provisioned"` +} + +type DashBoardInfo struct { + UID string `json:"uid"` + Title string `json:"title"` + Annotations map[string]interface{} `json:"annotations"` + Panels []Panel `json:"panels"` +} + +// Panel represents a Grafana panel. +// A panel can be used either for displaying data or separating groups +type Panel struct { + ID uint32 `json:"id"` + Title string `json:"title"` + Type string `json:"type"` + Targets []PanelQuery `json:"targets"` + Panels []Panel `json:"panels"` +} + +type PanelQuery struct { + RawQuery bool `json:"rawQuery"` + RefID string `json:"refId"` + Target string `json:"target"` + Type string `json:"table"` +} + +func (db *DashBoard) Valid() error { + if db.UID != GRAFANA_DASHBOARD_UID { + return fmt.Errorf("expected dashboard uid %s, but got %s", GRAFANA_DASHBOARD_UID, db.UID) + } + + if db.Title != GRAFANA_DASHBOARD_TITLE { + return fmt.Errorf("expected dashboard title %s, but got %s", GRAFANA_DASHBOARD_TITLE, db.Title) + } + + if !db.Provisioned { + return errors.New("expected dashboard to be provisioned, but got unprovisioned") + } + + if len(db.Panels) == 0 { + return errors.New("expected dashboard to have panels, but got 0") + } + + return nil +} From 10d35b43f42e65db4ecd60eea7c3e66eb0db38fb Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 23 Jul 2024 16:27:32 -0700 Subject: [PATCH 08/10] test(scorecard): update for new dashboard configs --- internal/test/scorecard/types.go | 54 +++++++++++++++++++------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index 132d356dd..fc34e2d74 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -158,7 +158,8 @@ const ( GRAFANA_DASHBOARD_UID = "main" GRAFANA_DASHBOARD_TITLE = "Cryostat Dashboard" GRAFANA_DATASOURCE_NAME = "jfr-datasource" - GRAFANA_DATASOURCE_TYPE = "grafana-simple-json-datasource" + GRAFANA_DATASOURCE_TYPE = "yesoreyeram-infinity-datasource" + GRAFANA_DATASOURCE_URL = "http://127.0.0.1:8989" GRAFANA_DATASOURCE_ACCESS = "proxy" ) @@ -176,24 +177,24 @@ type DataSource struct { BasicAuth bool `json:"basicAuth"` } -func (ds *DataSource) Valid() error { - if ds.Name != GRAFANA_DATASOURCE_NAME { - return fmt.Errorf("expected datasource name %s, but got %s", GRAFANA_DATASOURCE_NAME, ds.Name) +func (datasource *DataSource) Valid() error { + if datasource.Name != GRAFANA_DATASOURCE_NAME { + return fmt.Errorf("expected datasource name %s, but got %s", GRAFANA_DATASOURCE_NAME, datasource.Name) } - if ds.Type != GRAFANA_DATASOURCE_TYPE { - return fmt.Errorf("expected datasource type %s, but got %s", GRAFANA_DATASOURCE_TYPE, ds.Type) + if datasource.Type != GRAFANA_DATASOURCE_TYPE { + return fmt.Errorf("expected datasource type %s, but got %s", GRAFANA_DATASOURCE_TYPE, datasource.Type) } - if len(ds.URL) == 0 { - return errors.New("expected datasource url, but got empty") + if datasource.URL != GRAFANA_DATASOURCE_URL { + return fmt.Errorf("expected datasource url %s, but got %s", GRAFANA_DATASOURCE_URL, datasource.URL) } - if ds.Access != GRAFANA_DATASOURCE_ACCESS { - return fmt.Errorf("expected datasource access mode %s, but got %s", GRAFANA_DATASOURCE_ACCESS, ds.Access) + if datasource.Access != GRAFANA_DATASOURCE_ACCESS { + return fmt.Errorf("expected datasource access mode %s, but got %s", GRAFANA_DATASOURCE_ACCESS, datasource.Access) } - if ds.BasicAuth { + if datasource.BasicAuth { return errors.New("expected basicAuth to be disabled, but got enabled") } @@ -229,27 +230,36 @@ type Panel struct { Panels []Panel `json:"panels"` } +// PanelQuery represents a query for datapoints type PanelQuery struct { - RawQuery bool `json:"rawQuery"` - RefID string `json:"refId"` - Target string `json:"target"` - Type string `json:"table"` + RefID string `json:"refId"` + Target string `json:"target"` + Type string `json:"type"` + URL string `json:"url"` + URLOptions PanelQueryOptions `json:"url_options"` } -func (db *DashBoard) Valid() error { - if db.UID != GRAFANA_DASHBOARD_UID { - return fmt.Errorf("expected dashboard uid %s, but got %s", GRAFANA_DASHBOARD_UID, db.UID) +type PanelQueryOptions struct { + BodyContentType string `json:"body_content_type"` + BodyType string `json:"body_type"` + Method string `json:"method"` + Data string `json:"data"` +} + +func (dashboard *DashBoard) Valid() error { + if dashboard.UID != GRAFANA_DASHBOARD_UID { + return fmt.Errorf("expected dashboard uid %s, but got %s", GRAFANA_DASHBOARD_UID, dashboard.UID) } - if db.Title != GRAFANA_DASHBOARD_TITLE { - return fmt.Errorf("expected dashboard title %s, but got %s", GRAFANA_DASHBOARD_TITLE, db.Title) + if dashboard.Title != GRAFANA_DASHBOARD_TITLE { + return fmt.Errorf("expected dashboard title %s, but got %s", GRAFANA_DASHBOARD_TITLE, dashboard.Title) } - if !db.Provisioned { + if !dashboard.Provisioned { return errors.New("expected dashboard to be provisioned, but got unprovisioned") } - if len(db.Panels) == 0 { + if len(dashboard.Panels) == 0 { return errors.New("expected dashboard to have panels, but got 0") } From 276bc45a49eff9f3090a48bcd438219087e460a7 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Tue, 23 Jul 2024 19:41:06 -0700 Subject: [PATCH 09/10] test(scorecard): use testdata from local filesystem instead of cm. Notes: Dockerfile needs updating to include the testdata directory. --- Makefile | 6 ++++-- internal/test/scorecard/clients.go | 11 +++++++++-- internal/test/scorecard/common_utils.go | 1 + internal/test/scorecard/tests.go | 18 ++++++++++-------- internal/test/scorecard/types.go | 4 ++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index e75ff2607..302a16ad5 100644 --- a/Makefile +++ b/Makefile @@ -226,7 +226,6 @@ $(KUSTOMIZE) build internal/images/custom-scorecard-tests/rbac/ | $(CLUSTER_CLIE --docker-username="$(SCORECARD_REGISTRY_USERNAME)" --docker-password="$(SCORECARD_REGISTRY_PASSWORD)"; \ $(CLUSTER_CLIENT) patch sa cryostat-scorecard -n $(SCORECARD_NAMESPACE) -p '{"imagePullSecrets": [{"name": "registry-key"}]}'; \ fi -$(CLUSTER_CLIENT) create -n $(SCORECARD_NAMESPACE) configmap scorecard-jfr-cm --from-file=internal/test/scorecard/testdata/scorecard_sample.jfr $(OPERATOR_SDK) run bundle -n $(SCORECARD_NAMESPACE) --timeout 20m $(BUNDLE_IMG) --security-context-config=restricted $(SCORECARD_ARGS) endef @@ -244,7 +243,10 @@ endef define scorecard-local for test in $${SCORECARD_TEST_SELECTION//,/ }; do \ echo "Running scorecard test \"$${test}\""; \ - SCORECARD_NAMESPACE=$(SCORECARD_NAMESPACE) BUNDLE_DIR=./bundle go run internal/images/custom-scorecard-tests/main.go $${test} | sed 's/\\n/\n/g'; \ + SCORECARD_NAMESPACE=$(SCORECARD_NAMESPACE) \ + BUNDLE_DIR=./bundle \ + TESTDATA_DIR=./internal/test/scorecard/testdata \ + go run internal/images/custom-scorecard-tests/main.go $${test} | sed 's/\\n/\n/g'; \ done endef diff --git a/internal/test/scorecard/clients.go b/internal/test/scorecard/clients.go index 6d786fa0f..6dcb74258 100644 --- a/internal/test/scorecard/clients.go +++ b/internal/test/scorecard/clients.go @@ -24,6 +24,7 @@ import ( "mime/multipart" "net/http" "net/url" + "os" "strings" "time" @@ -520,7 +521,7 @@ func (client *RecordingClient) ListArchives(ctx context.Context, target *Target) return graphQLResponse.Data.TargetNodes[0].Target.ArchivedRecordings.Data, nil } -func (client *RecordingClient) UploadArchive(ctx context.Context, archiveContent []byte) error { +func (client *RecordingClient) UploadArchive(ctx context.Context, filePath string) error { url := client.Base.JoinPath("/api/v1/recordings") body := &bytes.Buffer{} @@ -531,7 +532,13 @@ func (client *RecordingClient) UploadArchive(ctx context.Context, archiveContent return err } - if _, err = part.Write(archiveContent); err != nil { + file, err := os.Open(filePath) + if err != nil { + return err + } + defer file.Close() + + if _, err = io.Copy(part, file); err != nil { return err } diff --git a/internal/test/scorecard/common_utils.go b/internal/test/scorecard/common_utils.go index c7d959ac3..013d288df 100644 --- a/internal/test/scorecard/common_utils.go +++ b/internal/test/scorecard/common_utils.go @@ -44,6 +44,7 @@ const ( operatorDeploymentName string = "cryostat-operator-controller" jfrConfigMapName string = "scorecard-jfr-cm" jfrFilename string = "scorecard_sample.jfr" + podTestDataRoot string = "/testdata" testTimeout time.Duration = time.Minute * 10 ) diff --git a/internal/test/scorecard/tests.go b/internal/test/scorecard/tests.go index cf0e2687d..ac957a65e 100644 --- a/internal/test/scorecard/tests.go +++ b/internal/test/scorecard/tests.go @@ -18,12 +18,13 @@ import ( "context" "fmt" "net/url" + "os" + "path" "time" operatorv1beta2 "github.com/cryostatio/cryostat-operator/api/v1beta2" scapiv1alpha3 "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3" apimanifests "github.com/operator-framework/api/pkg/manifests" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -340,13 +341,14 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif apiClient := NewCryostatRESTClientset(base) - // Get JFR data - cm, err := r.Client.CoreV1().ConfigMaps(namespace).Get(context.Background(), jfrConfigMapName, metav1.GetOptions{}) - if err != nil { - return r.fail(fmt.Sprintf("failed to get ConfigMap containing JFR data: %s", err.Error())) + // Get the path to the testdata directory from fromTESTDATA_DIR environment variable + // If empty, assume running within a pod and use "/testdata" + testDataDir := os.Getenv("TESTDATA_DIR") + if len(testDataDir) == 0 { + testDataDir = podTestDataRoot } - err = apiClient.Recordings().UploadArchive(context.Background(), cm.BinaryData[jfrFilename]) + err = apiClient.Recordings().UploadArchive(context.Background(), path.Join(testDataDir, jfrFilename)) if err != nil { return r.fail(fmt.Sprintf("failed to upload archive %s: %s", jfrFilename, err.Error())) } @@ -362,7 +364,7 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif return r.fail(fmt.Sprintf("failed to get datasource %s: %s", GRAFANA_DATASOURCE_NAME, err.Error())) } - if err = datasource.Valid(); err != nil { + if err = datasource.IsValid(); err != nil { return r.fail(fmt.Sprintf("datasource %s is invalid: %s", GRAFANA_DATASOURCE_NAME, err.Error())) } @@ -371,7 +373,7 @@ func CryostatGrafanaTest(bundle *apimanifests.Bundle, namespace string, openShif return r.fail(fmt.Sprintf("failed to get dashboard %s: %s", GRAFANA_DASHBOARD_UID, err.Error())) } - if err = dashboard.Valid(); err != nil { + if err = dashboard.IsValid(); err != nil { return r.fail(fmt.Sprintf("dashboard %s is invalid: %s", GRAFANA_DASHBOARD_UID, err.Error())) } diff --git a/internal/test/scorecard/types.go b/internal/test/scorecard/types.go index fc34e2d74..cbbc89b65 100644 --- a/internal/test/scorecard/types.go +++ b/internal/test/scorecard/types.go @@ -177,7 +177,7 @@ type DataSource struct { BasicAuth bool `json:"basicAuth"` } -func (datasource *DataSource) Valid() error { +func (datasource *DataSource) IsValid() error { if datasource.Name != GRAFANA_DATASOURCE_NAME { return fmt.Errorf("expected datasource name %s, but got %s", GRAFANA_DATASOURCE_NAME, datasource.Name) } @@ -246,7 +246,7 @@ type PanelQueryOptions struct { Data string `json:"data"` } -func (dashboard *DashBoard) Valid() error { +func (dashboard *DashBoard) IsValid() error { if dashboard.UID != GRAFANA_DASHBOARD_UID { return fmt.Errorf("expected dashboard uid %s, but got %s", GRAFANA_DASHBOARD_UID, dashboard.UID) } From 7a86ff2e813befa4273325f4c77206e360e33a35 Mon Sep 17 00:00:00 2001 From: Thuan Vo Date: Wed, 24 Jul 2024 11:33:53 -0700 Subject: [PATCH 10/10] tmp --- scripts/generate_datapoints.bash | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 scripts/generate_datapoints.bash diff --git a/scripts/generate_datapoints.bash b/scripts/generate_datapoints.bash new file mode 100644 index 000000000..cf65ac542 --- /dev/null +++ b/scripts/generate_datapoints.bash @@ -0,0 +1,21 @@ +#!/usr/local/env bash + +set -xe + +CRYOSTAT_URL="$1" + +if [ -z $CRYOSTAT_URL ]; then + echo "Cryostat URL is expected as an argument. Found none"; exit 2 +fi + +# Get datasource UID + +DATASOURCE_UID=$(curl -kLs ${CRYOSTAT_URL}/grafana/api/datasources/name/jfr-datasource | jq .uid) + +echo $DATASOURCE_UID + + +BODY="$(curl -ksL https://localhost:8080/grafana/api/dashboards/uid/main | jq .dashboard.panels[0].targets[0].url_options.data | sed -e 's/${__timeTo:date}/2024-08-28T20:23:35.127Z/' -e 's/${__timeFrom:date}/2024-05-01T20:23:35.127Z/')" + + +curl -kL --data $BODY ${CRYOSTAT_URL}/grafana/api/datasources/proxy/uid/$DATASOURCE_UID