Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integration tests for grafana deployment #1156

Merged
merged 9 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions pkg/util/test/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ var (
opVer1_9_1, _ = version.NewVersion("1.9.1-")
opVer1_10, _ = version.NewVersion("1.10.0-")
opVer23_3, _ = version.NewVersion("23.3.0-")
opVer23_8, _ = version.NewVersion("23.8.0-")
opVer23_5, _ = version.NewVersion("23.5.0-")
opVer23_5_1, _ = version.NewVersion("23.5.1-")
opVer23_7, _ = version.NewVersion("23.7.0-")
Expand Down Expand Up @@ -2926,6 +2927,9 @@ func ValidateMonitoring(pxImageList map[string]string, cluster *corev1.StorageCl
if err := ValidateAlertManager(pxImageList, cluster, timeout, interval); err != nil {
return err
}
if err := ValidateGrafana(pxImageList, cluster); err != nil {
return err
}

return nil
}
Expand Down Expand Up @@ -2983,6 +2987,110 @@ func ValidatePrometheus(pxImageList map[string]string, cluster *corev1.StorageCl
return nil
}

func ValidateGrafana(pxImageList map[string]string, cluster *corev1.StorageCluster) error {
opVersion, err := GetPxOperatorVersion()
if err != nil {
return err
}
if opVersion.LessThan(opVer23_8) {
logrus.Infof("Skipping grafana validation for operation version: [%s]", opVersion.String())
return nil
}

shouldBeInstalled := cluster.Spec.Monitoring != nil &&
cluster.Spec.Monitoring.Grafana != nil && cluster.Spec.Monitoring.Grafana.Enabled &&
cluster.Spec.Monitoring.Prometheus != nil && cluster.Spec.Monitoring.Prometheus.Enabled
err = ValidateGrafanaDeployment(cluster, shouldBeInstalled, pxImageList)
if err != nil {
return err
}
err = ValidateGrafanaService(cluster, shouldBeInstalled)
if err != nil {
return err
}
err = ValidateGrafanaConfigmaps(cluster, shouldBeInstalled)
if err != nil {
return err
}

return nil
}

func ValidateGrafanaDeployment(cluster *corev1.StorageCluster, shouldBeInstalled bool, pxImageList map[string]string) error {

// Deployment to validate
deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: "px-grafana",
Namespace: cluster.Namespace,
},
}
if shouldBeInstalled {
if err := appops.Instance().ValidateDeployment(deployment, 2*time.Minute, 10*time.Second); err != nil {
return fmt.Errorf("failed to validate deployment %s/%s. should be installed: %v. err: %v",
deployment.Namespace, deployment.Name, shouldBeInstalled, err)
}
} else {
if err := appops.Instance().ValidateTerminatedDeployment(deployment, 2*time.Minute, 10*time.Second); err != nil {
return fmt.Errorf("failed to validate terminated deployment %s/%s. should be installed: %v. err: %v",
deployment.Namespace, deployment.Name, shouldBeInstalled, err)
}
}

return nil
}

func ValidateGrafanaService(cluster *corev1.StorageCluster, shouldBeInstalled bool) error {
svcs, err := coreops.Instance().ListServices(cluster.Namespace, metav1.ListOptions{
LabelSelector: "app=grafana",
})
if err != nil {
return err
}

if shouldBeInstalled {
if len(svcs.Items) > 0 && svcs.Items[0].Spec.Ports[0].Port == 3000 {
return nil
} else {
return fmt.Errorf("grafana is not installed when it should be")
}
} else {
if len(svcs.Items) < 1 {
return nil
} else {
return fmt.Errorf("grafana svc is installed when it is expected to be uninstalled")
}
}
}

func ValidateGrafanaConfigmaps(cluster *corev1.StorageCluster, shouldBeInstalled bool) error {
cms, err := coreops.Instance().ListConfigMap(cluster.Namespace, metav1.ListOptions{})
if err != nil {
return err
}

var grafanaConfigmaps []v1.ConfigMap
for _, cm := range cms.Items {
if strings.Contains(cm.Name, "px-grafana-") {
grafanaConfigmaps = append(grafanaConfigmaps, cm)
}
}

if shouldBeInstalled {
if len(grafanaConfigmaps) == 3 {
return nil
} else {
return fmt.Errorf("grafana is not installed when it should be")
}
} else {
if len(grafanaConfigmaps) < 3 {
return nil
} else {
return fmt.Errorf("grafana configmaps are installed when it is expected to be uninstalled")
}
}
}

// ValidateTelemetryV1Disabled validates telemetry components are uninstalled as expected
func ValidateTelemetryV1Disabled(cluster *corev1.StorageCluster, timeout, interval time.Duration) error {
t := func() (interface{}, bool, error) {
Expand Down
158 changes: 158 additions & 0 deletions test/integration_test/basic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ var testStorageClusterBasicCases = []types.TestCase{
}),
TestFunc: BasicAutopilotRegression,
},
{
TestName: "BasicGrafanaRegression",
TestrailCaseIDs: []string{},
TestSpec: ci_utils.CreateStorageClusterTestSpecFunc(&corev1.StorageCluster{
ObjectMeta: metav1.ObjectMeta{Name: "test-stc"},
}),
TestFunc: BasicGrafanaRegression,
ShouldSkip: func(tc *types.TestCase) bool {
skip := ci_utils.PxOperatorVersion.LessThan(ci_utils.PxOperatorVer23_8)
if skip {
logrus.Info("Skipping BasicGrafanaRegression since operator version is less than 23.8.x")
}
return skip
},
},
{
TestName: "BasicPvcControllerRegression",
TestrailCaseIDs: []string{"C58438", "C54697", "C54698", "C54707", "C58437", "C54476", "C54477"},
Expand Down Expand Up @@ -1127,3 +1142,146 @@ func InstallWithNodeTopologyLabels(tc *types.TestCase) func(*testing.T) {
}
}
}

// BasicGrafanaRegression does the following steps:
// 1. Test Case: Install initial cluster and grafana disabled by default
// 2. Test Case: Grafana disabled by default even with prometheus enabled
// 3. Test Case: Grafana not installed when prometheus isn't enabled
// 4. Test Case: Grafana installed once enabled with prometheus
// 5. Test Case: Grafana disabled once prometheus is disabled
// 6. Test Case: Grafana disabled if grafana is disabled as well
// 7. Test Case: Grafana disabled if prometheus spec is removed
// 8. Test Case: Grafana disabled if grafana spec is removed
// 9. Test Case: Grafana disabled if monitoring spec is removed
func BasicGrafanaRegression(tc *types.TestCase) func(*testing.T) {
return func(t *testing.T) {
testSpec := tc.TestSpec(t)
cluster, ok := testSpec.(*corev1.StorageCluster)
require.True(t, ok)

// 1. Test Case: Install initial cluster and grafana disabled by default
cluster = ci_utils.DeployAndValidateStorageCluster(cluster, ci_utils.PxSpecImages, t)
require.Nil(t, cluster.Spec.Monitoring.Grafana, "failed to validate grafana block, it should be nil by default, but it seems there is something set in there %+v", cluster.Spec.Monitoring)

// 2. Test Case: Grafana disabled by default even with prometheus enabled
logrus.Info("Enable prometheus and validate StorageCluster")
updateParamFunc := func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = &corev1.MonitoringSpec{
Prometheus: &corev1.PrometheusSpec{
Enabled: true,
},
}
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.NotNil(t, cluster.Spec.Monitoring, "failed to validate monitoring block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring)
require.NotNil(t, cluster.Spec.Monitoring.Prometheus, "failed to validate prometheus block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Prometheus)
require.True(t, cluster.Spec.Monitoring.Prometheus.Enabled, "failed to validate Prometheus is enabled: expected: true, actual: %v", cluster.Spec.Monitoring.Prometheus.Enabled)

// 3. Test Case: Grafana not installed when prometheus isn't enabled
logrus.Info("Enable only grafana and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = &corev1.MonitoringSpec{
Prometheus: &corev1.PrometheusSpec{
Enabled: false,
},
Grafana: &corev1.GrafanaSpec{
Enabled: true,
},
}
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.NotNil(t, cluster.Spec.Monitoring, "failed to validate monitoring block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring)
require.NotNil(t, cluster.Spec.Monitoring.Grafana, "failed to validate Grafana block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Grafana)
require.True(t, cluster.Spec.Monitoring.Grafana.Enabled, "failed to validate Grafana is enabled: expected: true, actual: %v", cluster.Spec.Monitoring.Grafana.Enabled)

// 4. Test Case: Grafana installed once enabled with prometheus
logrus.Info("Enable both grafana and prometheus and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = &corev1.MonitoringSpec{
Prometheus: &corev1.PrometheusSpec{
Enabled: true,
},
Grafana: &corev1.GrafanaSpec{
Enabled: true,
},
}
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.NotNil(t, cluster.Spec.Monitoring, "failed to validate monitoring block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring)
require.NotNil(t, cluster.Spec.Monitoring.Grafana, "failed to validate Grafana block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Grafana)
require.True(t, cluster.Spec.Monitoring.Grafana.Enabled, "failed to validate Grafana is enabled: expected: true, actual: %v", cluster.Spec.Monitoring.Grafana.Enabled)
require.NotNil(t, cluster.Spec.Monitoring.Prometheus, "failed to validate Prometheus block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Prometheus)
require.True(t, cluster.Spec.Monitoring.Prometheus.Enabled, "failed to validate Prometheus is enabled: expected: true, actual: %v", cluster.Spec.Monitoring.Prometheus.Enabled)

// 5. Test Case: Grafana disabled once prometheus is disabled
logrus.Info("Disable prometheus and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = &corev1.MonitoringSpec{
Prometheus: &corev1.PrometheusSpec{
Enabled: false,
},
Grafana: &corev1.GrafanaSpec{
Enabled: true,
},
}
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.NotNil(t, cluster.Spec.Monitoring, "failed to validate monitoring block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring)
require.NotNil(t, cluster.Spec.Monitoring.Grafana, "failed to validate Grafana block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Grafana)
require.True(t, cluster.Spec.Monitoring.Grafana.Enabled, "failed to validate Grafana is enabled: expected: true, actual: %v", cluster.Spec.Monitoring.Grafana.Enabled)
require.NotNil(t, cluster.Spec.Monitoring.Prometheus, "failed to validate Prometheus block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Prometheus)
require.False(t, cluster.Spec.Monitoring.Prometheus.Enabled, "failed to validate Prometheus is disabled: expected: false, actual: %v", cluster.Spec.Monitoring.Prometheus.Enabled)

// 6. Test Case: Grafana disabled if grafana is disabled as well
logrus.Info("Disable grafana and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = &corev1.MonitoringSpec{
Prometheus: &corev1.PrometheusSpec{
Enabled: false,
},
Grafana: &corev1.GrafanaSpec{
Enabled: false,
},
}
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.NotNil(t, cluster.Spec.Monitoring, "failed to validate monitoring block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring)
require.NotNil(t, cluster.Spec.Monitoring.Grafana, "failed to validate Grafana block, it should not be nil here, but it is: %+v", cluster.Spec.Monitoring.Grafana)
require.False(t, cluster.Spec.Monitoring.Grafana.Enabled, "failed to validate Grafana is disabled: expected: false, actual: %v", cluster.Spec.Monitoring.Grafana.Enabled)

// 7. Test Case: Grafana disabled if prometheus spec is removed
logrus.Info("Remove Prometheus block (set it to nil) and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring.Prometheus = nil
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.Nil(t, cluster.Spec.Monitoring.Prometheus, "failed to validate Prometheus block, it should be nil here, but it is not: %+v", cluster.Spec.Monitoring.Prometheus)

// 8. Test Case: Grafana disabled if grafana spec is removed
logrus.Info("Remove Grafana block (set it to nil) and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring.Grafana = nil
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.Nil(t, cluster.Spec.Monitoring.Grafana, "failed to validate Grafana block, it should be nil here, but it is not: %+v", cluster.Spec.Monitoring.Grafana)

// 9. Test Case: Grafana disabled if monitoring spec is removed
logrus.Info("Remove Monitoring block (set it to nil) and validate StorageCluster")
updateParamFunc = func(cluster *corev1.StorageCluster) *corev1.StorageCluster {
cluster.Spec.Monitoring = nil
return cluster
}
cluster = ci_utils.UpdateAndValidateGrafana(cluster, updateParamFunc, ci_utils.PxSpecImages, t)
require.Nil(t, cluster.Spec.Monitoring, "failed to validate Monitoring block, it should be nil here, but it is not: %+v", cluster.Spec.Monitoring)

// Delete and validate StorageCluster deletion
ci_utils.UninstallAndValidateStorageCluster(cluster, t)
}
}
2 changes: 2 additions & 0 deletions test/integration_test/utils/px_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var (
PxOperatorVer1_8_1, _ = version.NewVersion("1.8.1-")
// PxOperatorVer23_3 portworx-operator 23.3 minimum version
PxOperatorVer23_3, _ = version.NewVersion("23.3-")
// PxOperatorVer23_8 portworx-operator 23.8 minimum version
PxOperatorVer23_8, _ = version.NewVersion("23.8-")
)

// TODO: Install portworx-operator in test automation
Expand Down
19 changes: 18 additions & 1 deletion test/integration_test/utils/storagecluster.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package utils

import (
"github.com/libopenstorage/cloudops"
"path"
"strings"
"testing"

"github.com/libopenstorage/cloudops"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -322,6 +323,22 @@ func UpdateAndValidateCSI(cluster *corev1.StorageCluster, f func(*corev1.Storage
return latestLiveCluster
}

// UpdateAndValidateGrafana update StorageCluster, validates grafana and return latest version of live StorageCluster
func UpdateAndValidateGrafana(cluster *corev1.StorageCluster, f func(*corev1.StorageCluster) *corev1.StorageCluster, pxSpecImages map[string]string, t *testing.T) *corev1.StorageCluster {
liveCluster, err := operator.Instance().GetStorageCluster(cluster.Name, cluster.Namespace)
require.NoError(t, err)

newCluster := f(liveCluster)

latestLiveCluster, err := UpdateStorageCluster(newCluster)
require.NoError(t, err)

err = testutil.ValidateGrafana(pxSpecImages, latestLiveCluster)
require.NoError(t, err)

return latestLiveCluster
}

// UninstallAndValidateStorageCluster uninstall and validate the cluster deletion
func UninstallAndValidateStorageCluster(cluster *corev1.StorageCluster, t *testing.T) {
// Delete cluster
Expand Down
Loading