Skip to content

Commit

Permalink
test(scorecard): cryostat dashboard validations
Browse files Browse the repository at this point in the history
  • Loading branch information
tthvo committed Jul 4, 2024
1 parent 83cf119 commit 9f43ae6
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
23 changes: 23 additions & 0 deletions internal/test/scorecard/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions internal/test/scorecard/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
58 changes: 57 additions & 1 deletion internal/test/scorecard/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`

Expand Down Expand Up @@ -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
}

0 comments on commit 9f43ae6

Please sign in to comment.