github.com/verrazzano/verrazzano@v1.7.1/tools/psr/psrctl/cmd/start/start_test.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package start 5 6 import ( 7 "bytes" 8 "encoding/base64" 9 "fmt" 10 "os" 11 "testing" 12 13 "github.com/stretchr/testify/assert" 14 helmcli "github.com/verrazzano/verrazzano/pkg/helm" 15 "github.com/verrazzano/verrazzano/pkg/k8sutil" 16 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 17 "github.com/verrazzano/verrazzano/tools/psr/psrctl/cmd/constants" 18 "github.com/verrazzano/verrazzano/tools/psr/psrctl/pkg/manifest" 19 "github.com/verrazzano/verrazzano/tools/psr/psrctl/pkg/scenario" 20 "github.com/verrazzano/verrazzano/tools/vz/test/helpers" 21 "helm.sh/helm/v3/pkg/release" 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/cli-runtime/pkg/genericclioptions" 25 k8sfake "k8s.io/client-go/kubernetes/fake" 26 corev1cli "k8s.io/client-go/kubernetes/typed/core/v1" 27 ) 28 29 const psrRoot = "../../.." 30 31 var ID = "ops-s1" 32 33 // TestStartCmd tests the NewCmdStart and RunCmdStart functions 34 // 35 // WHEN 'psrctl start -s ops-s1 -n psr' is called 36 // THEN ensure the new scenario gets started 37 func TestStartCmd(t *testing.T) { 38 manifest.Manifests = &manifest.PsrManifests{ 39 RootTmpDir: psrRoot, 40 WorkerChartAbsDir: psrRoot + "/manifests/charts/worker", 41 UseCasesAbsDir: psrRoot + "/manifests/usecases", 42 ScenarioAbsDir: psrRoot + "/manifests/scenarios", 43 } 44 45 defer manifest.ResetManifests() 46 47 defer func() { k8sutil.GetCoreV1Func = k8sutil.GetCoreV1Client }() 48 k8sutil.GetCoreV1Func = func(log ...vzlog.VerrazzanoLogger) (corev1cli.CoreV1Interface, error) { 49 return k8sfake.NewSimpleClientset().CoreV1(), nil 50 } 51 52 defer func() { scenario.StartUpgradeFunc = helmcli.Upgrade }() 53 scenario.StartUpgradeFunc = func(log vzlog.VerrazzanoLogger, releaseName string, namespace string, chartDir string, wait bool, dryRun bool, overrides []helmcli.HelmOverrides) (*release.Release, error) { 54 assert.Equal(t, 4, len(overrides)) 55 assert.Equal(t, "psr-ops-s1-ops-writelogs-0", releaseName) 56 assert.Equal(t, "psr", namespace) 57 assert.Contains(t, chartDir, "manifests/charts/worker") 58 59 return nil, nil 60 } 61 62 // Send the command output to a byte buffer 63 buf := new(bytes.Buffer) 64 errBuf := new(bytes.Buffer) 65 rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 66 67 cmd := NewCmdStart(rc) 68 cmd.PersistentFlags().Set(constants.FlagScenario, "ops-s1") 69 cmd.PersistentFlags().Set(constants.FlagNamespace, "psr") 70 assert.NotNil(t, cmd) 71 72 // Run start command, check for the expected status results to be displayed 73 err := cmd.Execute() 74 assert.NoError(t, err) 75 result := buf.String() 76 77 assert.Contains(t, result, fmt.Sprintf("Starting scenario %s", ID)) 78 assert.Contains(t, result, fmt.Sprintf("Scenario %s successfully started", ID)) 79 } 80 81 // TestStartExisting tests the NewCmdStart and RunCmdStart functions 82 // 83 // WHEN 'psrctl start -s ops-s1 -n psr' is called when the scenario is already running 84 // THEN ensure the output correctly tells the user their operation is invalid 85 func TestStartExisting(t *testing.T) { 86 manifest.Manifests = &manifest.PsrManifests{ 87 RootTmpDir: psrRoot, 88 WorkerChartAbsDir: psrRoot + "/manifests/charts/worker", 89 UseCasesAbsDir: psrRoot + "/manifests/usecases", 90 ScenarioAbsDir: psrRoot + "/manifests/scenarios", 91 } 92 93 // create scenario ConfigMap 94 cm := &corev1.ConfigMap{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Name: "psr-ops-s1", 97 Namespace: "psr", 98 Labels: map[string]string{ 99 "psr.verrazzano.io/scenario": "true", 100 "psr.verrazzano.io/scenario-id": "ops-s1", 101 }, 102 }, 103 Data: map[string]string{ 104 "scenario": base64.StdEncoding.EncodeToString([]byte(`Description: "This is a scenario that writes logs to STDOUT and gets logs from OpenSearch 105 at a moderated rate. \nThe purpose of the scenario is to test a moderate load on 106 both Fluend and OpenSearch by logging records.\n" 107 HelmReleases: 108 - Description: write logs to STDOUT 10 times a second 109 Name: psr-ops-s1-writelogs-0 110 Namespace: psr 111 OverrideFile: writelogs.yaml 112 UsecasePath: opensearch/writelogs.yaml 113 ID: ops-s1 114 Name: opensearch-s1 115 Namespace: default 116 ScenarioUsecaseOverridesAbsDir: temp-dir 117 Usecases: 118 - Description: write logs to STDOUT 10 times a second 119 OverrideFile: writelogs.yaml 120 UsecasePath: opensearch/writelogs.yaml 121 `)), 122 }, 123 } 124 125 defer func() { k8sutil.GetCoreV1Func = k8sutil.GetCoreV1Client }() 126 k8sutil.GetCoreV1Func = func(log ...vzlog.VerrazzanoLogger) (corev1cli.CoreV1Interface, error) { 127 return k8sfake.NewSimpleClientset(cm).CoreV1(), nil 128 } 129 130 // Send the command output to a byte buffer 131 buf := new(bytes.Buffer) 132 errBuf := new(bytes.Buffer) 133 rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 134 135 cmd := NewCmdStart(rc) 136 cmd.PersistentFlags().Set(constants.FlagScenario, "ops-s1") 137 cmd.PersistentFlags().Set(constants.FlagNamespace, "psr") 138 assert.NotNil(t, cmd) 139 140 // Run start command, check for the expected error to be thrown 141 err := cmd.Execute() 142 assert.Error(t, err) 143 assert.Contains(t, err.Error(), fmt.Sprintf("Scenario %s already running in namespace psr", ID)) 144 145 result := buf.String() 146 assert.Contains(t, result, fmt.Sprintf("Starting scenario %s", ID)) 147 } 148 149 // TestStartInvalid tests the NewCmdStart and RunCmdStart functions 150 // 151 // WHEN 'psrctl start -s bad-manifest -n psr' is called when the scenario does not exist 152 // THEN ensure the output correctly tells the user their operation is invalid 153 func TestStartInvalid(t *testing.T) { 154 155 manifest.Manifests = &manifest.PsrManifests{ 156 RootTmpDir: psrRoot, 157 WorkerChartAbsDir: psrRoot + "/manifests/charts/worker", 158 UseCasesAbsDir: psrRoot + "/manifests/usecases", 159 ScenarioAbsDir: psrRoot + "/manifests/scenarios", 160 } 161 162 defer func() { k8sutil.GetCoreV1Func = k8sutil.GetCoreV1Client }() 163 k8sutil.GetCoreV1Func = func(log ...vzlog.VerrazzanoLogger) (corev1cli.CoreV1Interface, error) { 164 return k8sfake.NewSimpleClientset().CoreV1(), nil 165 } 166 167 // Send the command output to a byte buffer 168 buf := new(bytes.Buffer) 169 errBuf := new(bytes.Buffer) 170 rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 171 172 cmd := NewCmdStart(rc) 173 cmd.PersistentFlags().Set(constants.FlagScenario, "bad-manifest") 174 cmd.PersistentFlags().Set(constants.FlagNamespace, "psr") 175 assert.NotNil(t, cmd) 176 177 // Run start command, check for the expected status results to be displayed 178 err := cmd.Execute() 179 assert.Error(t, err) 180 result := err.Error() 181 182 assert.Contains(t, result, "Failed to find scenario manifest with ID bad-manifest") 183 } 184 185 // TestStartDir tests the NewCmdStart and RunCmdStart functions 186 // 187 // WHEN 'psrctl start -s ops-test -d psrctl/testdata/ops-test' is called 188 // THEN ensure the new scenario gets started 189 func TestStartDir(t *testing.T) { 190 manifest.Manifests = &manifest.PsrManifests{ 191 RootTmpDir: psrRoot, 192 WorkerChartAbsDir: psrRoot + "/manifests/charts/worker", 193 UseCasesAbsDir: psrRoot + "/manifests/usecases", 194 ScenarioAbsDir: psrRoot + "/manifests/scenarios", 195 } 196 197 defer manifest.ResetManifests() 198 199 defer func() { k8sutil.GetCoreV1Func = k8sutil.GetCoreV1Client }() 200 k8sutil.GetCoreV1Func = func(log ...vzlog.VerrazzanoLogger) (corev1cli.CoreV1Interface, error) { 201 return k8sfake.NewSimpleClientset().CoreV1(), nil 202 } 203 204 defer func() { scenario.StartUpgradeFunc = helmcli.Upgrade }() 205 scenario.StartUpgradeFunc = func(log vzlog.VerrazzanoLogger, releaseName string, namespace string, chartDir string, wait bool, dryRun bool, overrides []helmcli.HelmOverrides) (*release.Release, error) { 206 assert.Equal(t, 4, len(overrides)) 207 assert.Equal(t, "psr-ops-test-ops-writelogs-0", releaseName) 208 assert.Equal(t, "default", namespace) 209 assert.Contains(t, chartDir, "manifests/charts/worker") 210 211 return nil, nil 212 } 213 214 // Send the command output to a byte buffer 215 buf := new(bytes.Buffer) 216 errBuf := new(bytes.Buffer) 217 rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 218 219 cmd := NewCmdStart(rc) 220 cmd.PersistentFlags().Set(constants.FlagScenario, "ops-test") 221 cmd.PersistentFlags().Set(constants.FlagScenarioDir, "../../testdata/ops-test") 222 assert.NotNil(t, cmd) 223 224 // Run start command, check for the expected status results to be displayed 225 err := cmd.Execute() 226 assert.NoError(t, err) 227 result := buf.String() 228 229 assert.Contains(t, result, "Starting scenario ops-test") 230 assert.Contains(t, result, "Scenario ops-test successfully started") 231 } 232 233 // TestStartDirError tests the NewCmdStart and RunCmdStart functions 234 // 235 // WHEN 'psrctl start -d psrctl/testdata/ops-test' is called without the scenario name 236 // THEN ensure the output correctly tells the user their operation is invalid 237 func TestStartDirError(t *testing.T) { 238 manifest.Manifests = &manifest.PsrManifests{ 239 RootTmpDir: psrRoot, 240 WorkerChartAbsDir: psrRoot + "/manifests/charts/worker", 241 UseCasesAbsDir: psrRoot + "/manifests/usecases", 242 ScenarioAbsDir: psrRoot + "/manifests/scenarios", 243 } 244 245 defer func() { k8sutil.GetCoreV1Func = k8sutil.GetCoreV1Client }() 246 k8sutil.GetCoreV1Func = func(log ...vzlog.VerrazzanoLogger) (corev1cli.CoreV1Interface, error) { 247 return k8sfake.NewSimpleClientset().CoreV1(), nil 248 } 249 250 // Send the command output to a byte buffer 251 buf := new(bytes.Buffer) 252 errBuf := new(bytes.Buffer) 253 rc := helpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 254 255 cmd := NewCmdStart(rc) 256 cmd.PersistentFlags().Set(constants.FlagScenarioDir, "../../testdata/ops-test") 257 assert.NotNil(t, cmd) 258 259 // Run start command, check for the expected status results to be displayed 260 err := cmd.Execute() 261 assert.Error(t, err) 262 result := err.Error() 263 264 assert.Contains(t, result, "Failed to find scenario manifest with ID") 265 }