github.com/verrazzano/verrazzano@v1.7.0/tools/vz/cmd/upgrade/upgrade_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 upgrade 5 6 import ( 7 "bytes" 8 "context" 9 "os" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1" 14 vpoconst "github.com/verrazzano/verrazzano/platform-operator/constants" 15 cmdHelpers "github.com/verrazzano/verrazzano/tools/vz/cmd/helpers" 16 "github.com/verrazzano/verrazzano/tools/vz/cmd/install" 17 "github.com/verrazzano/verrazzano/tools/vz/pkg/constants" 18 "github.com/verrazzano/verrazzano/tools/vz/pkg/helpers" 19 testhelpers "github.com/verrazzano/verrazzano/tools/vz/test/helpers" 20 corev1 "k8s.io/api/core/v1" 21 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 "k8s.io/apimachinery/pkg/types" 23 "k8s.io/cli-runtime/pkg/genericclioptions" 24 dynfake "k8s.io/client-go/dynamic/fake" 25 "sigs.k8s.io/controller-runtime/pkg/client" 26 "sigs.k8s.io/controller-runtime/pkg/client/fake" 27 ) 28 29 const ( 30 testKubeConfig = "kubeconfig" 31 testK8sContext = "testcontext" 32 testImageRegistry = "testreg.io" 33 testImagePrefix = "testrepo" 34 testVZMajorRelease = "v1.5.0" 35 testVZPatchRelease = "v1.5.2" 36 ) 37 38 // TestUpgradeCmdDefaultNoWait 39 // GIVEN a CLI upgrade command with all defaults and --wait==false 40 // 41 // WHEN I call cmd.Execute for upgrade 42 // THEN the CLI upgrade command is successful 43 func TestUpgradeCmdDefaultNoWait(t *testing.T) { 44 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 45 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 46 47 // Send stdout stderr to a byte buffer 48 buf := new(bytes.Buffer) 49 errBuf := new(bytes.Buffer) 50 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 51 rc.SetClient(c) 52 cmd := NewCmdUpgrade(rc) 53 assert.NotNil(t, cmd) 54 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 55 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 56 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 57 defer cmdHelpers.SetDefaultDeleteFunc() 58 59 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 60 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 61 62 // Run upgrade command 63 err := cmd.Execute() 64 assert.NoError(t, err) 65 assert.Equal(t, "", errBuf.String()) 66 67 // Verify the vz resource is as expected 68 vzResource := v1beta1.Verrazzano{} 69 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vzResource) 70 assert.NoError(t, err) 71 } 72 73 // TestUpgradeCmdDefaultTimeoutBugReport 74 // GIVEN a CLI upgrade command with all defaults and --timeout=2ms 75 // 76 // WHEN I call cmd.Execute for upgrade 77 // THEN the CLI upgrade command times out and a bug report is generated 78 func TestUpgradeCmdDefaultTimeoutBugReport(t *testing.T) { 79 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 80 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 81 82 // Send stdout stderr to a byte buffer 83 buf := new(bytes.Buffer) 84 errBuf := new(bytes.Buffer) 85 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 86 rc.SetClient(c) 87 rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme())) 88 cmd := NewCmdUpgrade(rc) 89 assert.NotNil(t, cmd) 90 cmd.PersistentFlags().Set(constants.TimeoutFlag, "2ms") 91 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 92 tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig) 93 cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "") 94 cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "") 95 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 96 defer cmdHelpers.SetDefaultDeleteFunc() 97 defer os.RemoveAll(tempKubeConfigPath.Name()) 98 99 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 100 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 101 102 // Run upgrade command 103 err := cmd.Execute() 104 assert.Error(t, err) 105 assert.Equal(t, "Error: Timeout 2ms exceeded waiting for upgrade to complete\n", errBuf.String()) 106 assert.Contains(t, buf.String(), "Upgrading Verrazzano to version v1.4.0") 107 if !helpers.CheckAndRemoveBugReportExistsInDir("") { 108 t.Fatal("cannot find bug report file in current directory") 109 } 110 } 111 112 // TestUpgradeCmdDefaultTimeoutNoBugReport 113 // GIVEN a CLI upgrade command with all --timeout=2ms and auto-bug-report=false 114 // 115 // WHEN I call cmd.Execute for upgrade 116 // THEN the CLI upgrade command times out and a bug report is not generated 117 func TestUpgradeCmdDefaultTimeoutNoBugReport(t *testing.T) { 118 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 119 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 120 121 // Send stdout stderr to a byte buffer 122 buf := new(bytes.Buffer) 123 errBuf := new(bytes.Buffer) 124 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 125 rc.SetClient(c) 126 cmd := NewCmdUpgrade(rc) 127 assert.NotNil(t, cmd) 128 cmd.PersistentFlags().Set(constants.TimeoutFlag, "2ms") 129 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 130 cmd.PersistentFlags().Set(constants.AutoBugReportFlag, "false") 131 tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig) 132 cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "") 133 cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "") 134 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 135 defer cmdHelpers.SetDefaultDeleteFunc() 136 defer os.RemoveAll(tempKubeConfigPath.Name()) 137 138 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 139 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 140 141 // Run upgrade command 142 err := cmd.Execute() 143 assert.Error(t, err) 144 assert.Equal(t, "Error: Timeout 2ms exceeded waiting for upgrade to complete\n", errBuf.String()) 145 assert.Contains(t, buf.String(), "Upgrading Verrazzano to version v1.4.0") 146 // Bug report must not exist 147 if helpers.CheckAndRemoveBugReportExistsInDir("") { 148 t.Fatal("found bug report file in current directory") 149 } 150 } 151 152 // TestUpgradeCmdDefaultNoVPO 153 // GIVEN a CLI upgrade command with all defaults and no VPO found 154 // 155 // WHEN I call cmd.Execute for upgrade 156 // THEN the CLI upgrade command fails 157 func TestUpgradeCmdDefaultNoVPO(t *testing.T) { 158 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateVerrazzanoObjectWithVersion()).Build() 159 160 // Send stdout stderr to a byte buffer 161 buf := new(bytes.Buffer) 162 errBuf := new(bytes.Buffer) 163 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 164 rc.SetClient(c) 165 rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme())) 166 cmd := NewCmdUpgrade(rc) 167 assert.NotNil(t, cmd) 168 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 169 tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig) 170 cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "") 171 cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "") 172 173 // Run upgrade command 174 cmd.PersistentFlags().Set(constants.VPOTimeoutFlag, "1s") 175 err := cmd.Execute() 176 assert.Error(t, err) 177 assert.ErrorContains(t, err, "Waiting for verrazzano-platform-operator pod in namespace verrazzano-install") 178 assert.Contains(t, errBuf.String(), "Error: Waiting for verrazzano-platform-operator pod in namespace verrazzano-install") 179 if !helpers.CheckAndRemoveBugReportExistsInDir("") { 180 t.Fatal("found bug report file in current directory") 181 } 182 } 183 184 // TestUpgradeCmdDefaultMultipleVPO 185 // GIVEN a CLI upgrade command with all defaults and multiple VPOs found 186 // 187 // WHEN I call cmd.Execute for upgrade 188 // THEN the CLI upgrade command fails 189 func TestUpgradeCmdDefaultMultipleVPO(t *testing.T) { 190 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 191 vpo2 := testhelpers.CreateVPOPod(constants.VerrazzanoPlatformOperator + "-2") 192 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz, vpo2)...).Build() 193 // Send stdout stderr to a byte buffer 194 buf := new(bytes.Buffer) 195 errBuf := new(bytes.Buffer) 196 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 197 rc.SetClient(c) 198 rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme())) 199 cmd := NewCmdUpgrade(rc) 200 assert.NotNil(t, cmd) 201 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 202 tempKubeConfigPath, _ := os.CreateTemp(os.TempDir(), testKubeConfig) 203 cmd.Flags().String(constants.GlobalFlagKubeConfig, tempKubeConfigPath.Name(), "") 204 cmd.Flags().String(constants.GlobalFlagContext, testK8sContext, "") 205 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 206 defer cmdHelpers.SetDefaultDeleteFunc() 207 208 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 209 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 210 211 // Run upgrade command 212 cmd.PersistentFlags().Set(constants.VPOTimeoutFlag, "1s") 213 err := cmd.Execute() 214 assert.Error(t, err) 215 assert.ErrorContains(t, err, "Waiting for verrazzano-platform-operator, more than one verrazzano-platform-operator pod was found in namespace verrazzano-install") 216 assert.Contains(t, errBuf.String(), "Error: Waiting for verrazzano-platform-operator, more than one verrazzano-platform-operator pod was found in namespace verrazzano-install") 217 if !helpers.CheckAndRemoveBugReportExistsInDir("") { 218 t.Fatal("found bug report file in current directory") 219 } 220 } 221 222 // TestUpgradeCmdJsonLogFormat 223 // GIVEN a CLI upgrade command with defaults and --log-format=json and --wait==false 224 // 225 // WHEN I call cmd.Execute for upgrade 226 // THEN the CLI upgrade command is successful 227 func TestUpgradeCmdJsonLogFormat(t *testing.T) { 228 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 229 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 230 231 // Send stdout stderr to a byte buffer 232 buf := new(bytes.Buffer) 233 errBuf := new(bytes.Buffer) 234 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 235 rc.SetClient(c) 236 cmd := NewCmdUpgrade(rc) 237 assert.NotNil(t, cmd) 238 cmd.PersistentFlags().Set(constants.LogFormatFlag, "json") 239 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 240 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 241 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 242 defer cmdHelpers.SetDefaultDeleteFunc() 243 244 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 245 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 246 247 // Run upgrade command 248 err := cmd.Execute() 249 assert.NoError(t, err) 250 assert.Equal(t, "", errBuf.String()) 251 } 252 253 // TestUpgradeCmdOperatorFile 254 // GIVEN a CLI upgrade command with defaults and --wait=false and --operator-file specified 255 // 256 // WHEN I call cmd.Execute for upgrade 257 // THEN the CLI upgrade command is successful 258 func TestUpgradeCmdOperatorFile(t *testing.T) { 259 tests := []struct { 260 testName string 261 manifestsFlagName string 262 }{ 263 {"Use manifests flag", constants.ManifestsFlag}, 264 {"Use deprecated operator-file flag", constants.OperatorFileFlag}, 265 } 266 for _, tt := range tests { 267 t.Run(tt.testName, func(t *testing.T) { 268 vz := testhelpers.CreateVerrazzanoObjectWithVersion().(*v1beta1.Verrazzano) 269 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 270 271 // Send stdout stderr to a byte buffer 272 buf := new(bytes.Buffer) 273 errBuf := new(bytes.Buffer) 274 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 275 rc.SetClient(c) 276 cmd := NewCmdUpgrade(rc) 277 assert.NotNil(t, cmd) 278 cmd.PersistentFlags().Set(tt.manifestsFlagName, "../../test/testdata/operator-file-fake.yaml") 279 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 280 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 281 defer cmdHelpers.SetDefaultDeleteFunc() 282 283 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 284 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 285 286 // Run upgrade command 287 err := cmd.Execute() 288 assert.NoError(t, err) 289 assert.Equal(t, "", errBuf.String()) 290 assert.Contains(t, buf.String(), "Applying the file ../../test/testdata/operator-file-fake.yaml") 291 assert.Contains(t, buf.String(), "namespace/verrazzano-install created") 292 assert.Contains(t, buf.String(), "serviceaccount/verrazzano-platform-operator created") 293 assert.Contains(t, buf.String(), "service/verrazzano-platform-operator created") 294 295 // Verify the objects in the manifests got added 296 sa := corev1.ServiceAccount{} 297 err = c.Get(context.TODO(), types.NamespacedName{Namespace: vpoconst.VerrazzanoInstallNamespace, Name: constants.VerrazzanoPlatformOperator}, &sa) 298 assert.NoError(t, err) 299 expectedLastAppliedConfigAnnotation := "{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"annotations\":{},\"name\":\"verrazzano-platform-operator\",\"namespace\":\"verrazzano-install\"}}\n" 300 testhelpers.VerifyLastAppliedConfigAnnotation(t, sa.ObjectMeta, expectedLastAppliedConfigAnnotation) 301 302 ns := corev1.Namespace{} 303 err = c.Get(context.TODO(), types.NamespacedName{Name: "verrazzano-install"}, &ns) 304 assert.NoError(t, err) 305 expectedLastAppliedConfigAnnotation = "{\"apiVersion\":\"v1\",\"kind\":\"Namespace\",\"metadata\":{\"annotations\":{},\"labels\":{\"verrazzano.io/namespace\":\"verrazzano-install\"},\"name\":\"verrazzano-install\"}}\n" 306 testhelpers.VerifyLastAppliedConfigAnnotation(t, ns.ObjectMeta, expectedLastAppliedConfigAnnotation) 307 308 svc := corev1.Service{} 309 err = c.Get(context.TODO(), types.NamespacedName{Namespace: vpoconst.VerrazzanoInstallNamespace, Name: constants.VerrazzanoPlatformOperator}, &svc) 310 assert.NoError(t, err) 311 expectedLastAppliedConfigAnnotation = "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"verrazzano-platform-operator\"},\"name\":\"verrazzano-platform-operator\",\"namespace\":\"verrazzano-install\"},\"spec\":{\"ports\":[{\"name\":\"http-metric\",\"port\":9100,\"protocol\":\"TCP\",\"targetPort\":9100}],\"selector\":{\"app\":\"verrazzano-platform-operator\"}}}\n" 312 testhelpers.VerifyLastAppliedConfigAnnotation(t, svc.ObjectMeta, expectedLastAppliedConfigAnnotation) 313 314 // Verify the version got updated 315 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, vz) 316 assert.NoError(t, err) 317 assert.Equal(t, "v1.5.2", vz.Spec.Version) 318 }) 319 } 320 } 321 322 // TestUpgradeCmdNoVerrazzano 323 // GIVEN a CLI upgrade command with no verrazzano install resource found 324 // 325 // WHEN I call cmd.Execute for upgrade 326 // THEN the CLI upgrade command fails 327 func TestUpgradeCmdNoVerrazzano(t *testing.T) { 328 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects().Build() 329 330 // Send stdout stderr to a byte buffer 331 buf := new(bytes.Buffer) 332 errBuf := new(bytes.Buffer) 333 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 334 rc.SetClient(c) 335 rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme())) 336 cmd := NewCmdUpgrade(rc) 337 assert.NotNil(t, cmd) 338 339 // Run upgrade command 340 err := cmd.Execute() 341 assert.Error(t, err) 342 assert.Equal(t, "Error: Verrazzano is not installed: Failed to find any Verrazzano resources\n", errBuf.String()) 343 } 344 345 // TestUpgradeCmdLesserStatusVersion 346 // GIVEN a CLI upgrade command specifying a version less than the status version 347 // 348 // WHEN I call cmd.Execute for upgrade 349 // THEN the CLI upgrade command fails 350 func TestUpgradeCmdLesserStatusVersion(t *testing.T) { 351 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateVerrazzanoObjectWithVersion()).Build() 352 353 // Send stdout stderr to a byte buffer 354 buf := new(bytes.Buffer) 355 errBuf := new(bytes.Buffer) 356 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 357 rc.SetClient(c) 358 rc.SetDynamicClient(dynfake.NewSimpleDynamicClient(helpers.GetScheme())) 359 cmd := NewCmdUpgrade(rc) 360 assert.NotNil(t, cmd) 361 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.3.3") 362 363 // Run upgrade command 364 err := cmd.Execute() 365 assert.Error(t, err) 366 assert.Equal(t, "Error: Upgrade to a lesser version of Verrazzano is not allowed. Upgrade version specified was v1.3.3 and current Verrazzano version is v1.3.4\n", errBuf.String()) 367 } 368 369 // TestUpgradeCmdEqualStatusVersion 370 // GIVEN a CLI upgrade command specifying a version equal to the status version and the spec version is empty 371 // 372 // WHEN I call cmd.Execute for upgrade 373 // THEN the CLI upgrade command is successful with an informational message 374 func TestUpgradeCmdEqualStatusVersion(t *testing.T) { 375 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateVerrazzanoObjectWithVersion()).Build() 376 377 // Send stdout stderr to a byte buffer 378 buf := new(bytes.Buffer) 379 errBuf := new(bytes.Buffer) 380 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 381 rc.SetClient(c) 382 cmd := NewCmdUpgrade(rc) 383 assert.NotNil(t, cmd) 384 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.3.4") 385 386 // Run upgrade command 387 err := cmd.Execute() 388 assert.NoError(t, err) 389 assert.Equal(t, "Verrazzano is already at the specified upgrade version of v1.3.4\n", buf.String()) 390 } 391 392 // TestUpgradeCmdLesserSpecVersion 393 // GIVEN a CLI upgrade command specifying a version less than the spec version 394 // 395 // WHEN I call cmd.Execute for upgrade 396 // THEN the CLI upgrade command fails 397 func TestUpgradeCmdLesserSpecVersion(t *testing.T) { 398 vz := &v1beta1.Verrazzano{ 399 TypeMeta: metav1.TypeMeta{}, 400 ObjectMeta: metav1.ObjectMeta{ 401 Namespace: "default", 402 Name: "verrazzano", 403 }, 404 Spec: v1beta1.VerrazzanoSpec{ 405 Version: "v1.3.4", 406 }, 407 Status: v1beta1.VerrazzanoStatus{ 408 Version: "v1.3.3", 409 }, 410 } 411 412 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(vz).Build() 413 414 // Send stdout stderr to a byte buffer 415 buf := new(bytes.Buffer) 416 errBuf := new(bytes.Buffer) 417 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 418 rc.SetClient(c) 419 cmd := NewCmdUpgrade(rc) 420 assert.NotNil(t, cmd) 421 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.3.3") 422 423 // Run upgrade command 424 err := cmd.Execute() 425 assert.Error(t, err) 426 assert.Equal(t, "Error: Upgrade to a lesser version of Verrazzano is not allowed. Upgrade version specified was v1.3.3 and the upgrade in progress is v1.3.4\n", errBuf.String()) 427 } 428 429 // TestUpgradeCmdInProgress 430 // GIVEN a CLI upgrade command an upgrade was in progress 431 // 432 // WHEN I call cmd.Execute for upgrade 433 // THEN the CLI upgrade command is successful 434 func TestUpgradeCmdInProgress(t *testing.T) { 435 vz := &v1beta1.Verrazzano{ 436 TypeMeta: metav1.TypeMeta{}, 437 ObjectMeta: metav1.ObjectMeta{ 438 Namespace: "default", 439 Name: "verrazzano", 440 }, 441 Spec: v1beta1.VerrazzanoSpec{ 442 Version: "v1.3.4", 443 }, 444 Status: v1beta1.VerrazzanoStatus{ 445 Version: "v1.3.3", 446 }, 447 } 448 449 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 450 451 // Send stdout stderr to a byte buffer 452 buf := new(bytes.Buffer) 453 errBuf := new(bytes.Buffer) 454 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 455 rc.SetClient(c) 456 cmd := NewCmdUpgrade(rc) 457 assert.NotNil(t, cmd) 458 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 459 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.3.4") 460 461 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 462 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 463 464 // Run upgrade command 465 err := cmd.Execute() 466 assert.NoError(t, err) 467 assert.Equal(t, "", errBuf.String()) 468 } 469 470 // TestUpgradeFromPrivateRegistry tests upgrading from a private registry. 471 // 472 // GIVEN Verrazzano is installed from a private registry 473 // 474 // WHEN I call cmd.Execute for upgrade with the same private registry settings 475 // THEN the CLI upgrade command is successful and the VPO and VPO webhook deployments have the expected private registry configuration 476 func TestUpgradeFromPrivateRegistry(t *testing.T) { 477 // First install using a private registry 478 479 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build() 480 errBuf := new(bytes.Buffer) 481 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: new(bytes.Buffer), ErrOut: errBuf}) 482 rc.SetClient(c) 483 cmd := install.NewCmdInstall(rc) 484 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 485 cmd.PersistentFlags().Set(constants.VersionFlag, testVZMajorRelease) 486 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, testImageRegistry) 487 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, testImagePrefix) 488 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 489 defer cmdHelpers.SetDefaultDeleteFunc() 490 491 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 492 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 493 494 install.SetValidateCRFunc(install.FakeValidateCRFunc) 495 defer install.SetDefaultValidateCRFunc() 496 497 // Run install command 498 err := cmd.Execute() 499 assert.NoError(t, err) 500 assert.Equal(t, "", errBuf.String()) 501 502 // Need to update the VZ status version otherwise upgrade fails 503 vz := &v1beta1.Verrazzano{} 504 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, vz) 505 assert.NoError(t, err) 506 507 vz.Status.Version = testVZMajorRelease 508 err = c.Status().Update(context.TODO(), vz) 509 assert.NoError(t, err) 510 511 // Now do the upgrade using the same private registry settings 512 cmd = NewCmdUpgrade(rc) 513 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 514 cmd.PersistentFlags().Set(constants.VersionFlag, testVZPatchRelease) 515 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, testImageRegistry) 516 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, testImagePrefix) 517 518 // Run upgrade command 519 err = cmd.Execute() 520 assert.NoError(t, err) 521 assert.Equal(t, "", errBuf.String()) 522 523 // Verify that the VPO deployment has the expected environment variables to enable pulling images from a private registry 524 deployment, err := cmdHelpers.GetExistingVPODeployment(c) 525 assert.NoError(t, err) 526 assert.NotNil(t, deployment) 527 testhelpers.AssertPrivateRegistryEnvVars(t, c, deployment, testImageRegistry, testImagePrefix) 528 529 // Verify that the VPO image has been updated 530 testhelpers.AssertPrivateRegistryImage(t, c, deployment, testImageRegistry, testImagePrefix) 531 532 // Verify that the VPO webhook image has been updated 533 deployment, err = cmdHelpers.GetExistingVPOWebhookDeployment(c) 534 assert.NoError(t, err) 535 assert.NotNil(t, deployment) 536 537 testhelpers.AssertPrivateRegistryImage(t, c, deployment, testImageRegistry, testImagePrefix) 538 } 539 540 // TestUpgradeFromDifferentPrivateRegistry tests upgrading from a different private registry 541 func TestUpgradeFromDifferentPrivateRegistry(t *testing.T) { 542 // First install using a private registry 543 const proceedQuestionText = "Proceed to upgrade with new settings? [y/N]" 544 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build() 545 errBuf := new(bytes.Buffer) 546 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: new(bytes.Buffer), ErrOut: errBuf}) 547 rc.SetClient(c) 548 549 content := []byte("y") 550 tempfile, err := os.CreateTemp("", "test-input.txt") 551 if err != nil { 552 assert.Error(t, err) 553 } 554 // clean up tempfile 555 defer os.Remove(tempfile.Name()) 556 if _, err := tempfile.Write(content); err != nil { 557 assert.Error(t, err) 558 } 559 if _, err := tempfile.Seek(0, 0); err != nil { 560 assert.Error(t, err) 561 } 562 oldStdin := os.Stdin 563 // Restore original Stdin 564 defer func() { os.Stdin = oldStdin }() 565 os.Stdin = tempfile 566 567 cmd := install.NewCmdInstall(rc) 568 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 569 cmd.PersistentFlags().Set(constants.VersionFlag, testVZMajorRelease) 570 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, testImageRegistry) 571 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, testImagePrefix) 572 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 573 defer cmdHelpers.SetDefaultDeleteFunc() 574 575 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 576 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 577 578 install.SetValidateCRFunc(install.FakeValidateCRFunc) 579 defer install.SetDefaultValidateCRFunc() 580 581 // Run install command 582 err = cmd.Execute() 583 assert.NoError(t, err) 584 assert.Equal(t, "", errBuf.String()) 585 586 // Need to update the VZ status version otherwise upgrade fails 587 vz := &v1beta1.Verrazzano{} 588 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, vz) 589 assert.NoError(t, err) 590 591 vz.Status.Version = testVZMajorRelease 592 err = c.Status().Update(context.TODO(), vz) 593 assert.NoError(t, err) 594 595 // GIVEN Verrazzano is installed from a private registry 596 // 597 // WHEN I call cmd.Execute for upgrade with different private registry settings and answer "n" when asked to proceed 598 // THEN the upgrade is cancelled 599 const imageRegistryForUpgrade = "newreg.io" 600 const imagePrefixForUpgrade = "newrepo" 601 602 // Create a buffer for Stdin that simulates the user typing an "n" in response to the question on whether the CLI 603 // should continue with the upgrade because the registry settings are different from the settings used during install 604 inBuf := new(bytes.Buffer) 605 inBuf.WriteString("n") 606 607 outBuf := new(bytes.Buffer) 608 errBuf = new(bytes.Buffer) 609 rc = testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: inBuf, Out: outBuf, ErrOut: errBuf}) 610 rc.SetClient(c) 611 612 cmd = NewCmdUpgrade(rc) 613 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 614 cmd.PersistentFlags().Set(constants.VersionFlag, testVZPatchRelease) 615 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, imageRegistryForUpgrade) 616 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, imagePrefixForUpgrade) 617 618 // Run upgrade command - expect that the CLI asks us if we want to continue with the existing registry settings 619 // and we reply with "n" 620 err = cmd.Execute() 621 assert.NoError(t, err) 622 assert.Contains(t, outBuf.String(), proceedQuestionText) 623 assert.Contains(t, outBuf.String(), "Upgrade canceled") 624 assert.Equal(t, "", errBuf.String()) 625 626 // Verify that the VPO deployment has the expected environment variables to enable pulling images from a private registry 627 // and that they are the settings from the install, not the upgrade 628 deployment, err := cmdHelpers.GetExistingVPODeployment(c) 629 assert.NoError(t, err) 630 assert.NotNil(t, deployment) 631 testhelpers.AssertPrivateRegistryEnvVars(t, c, deployment, testImageRegistry, testImagePrefix) 632 633 // Verify that the VPO image is using the install private registry settings 634 testhelpers.AssertPrivateRegistryImage(t, c, deployment, testImageRegistry, testImagePrefix) 635 636 // Verify that the VPO webhook image is using the install private registry settings 637 deployment, err = cmdHelpers.GetExistingVPOWebhookDeployment(c) 638 assert.NoError(t, err) 639 assert.NotNil(t, deployment) 640 641 testhelpers.AssertPrivateRegistryImage(t, c, deployment, testImageRegistry, testImagePrefix) 642 643 // GIVEN Verrazzano is installed from a private registry 644 // 645 // WHEN I call cmd.Execute for upgrade with different private registry settings and answer "y" when asked to proceed 646 // THEN the upgrade succeeds and the new registry settings are configured on the VPO 647 inBuf = new(bytes.Buffer) 648 inBuf.WriteString("y") 649 650 outBuf = new(bytes.Buffer) 651 errBuf = new(bytes.Buffer) 652 rc = testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: inBuf, Out: outBuf, ErrOut: errBuf}) 653 rc.SetClient(c) 654 655 cmd = NewCmdUpgrade(rc) 656 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 657 cmd.PersistentFlags().Set(constants.VersionFlag, testVZPatchRelease) 658 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, imageRegistryForUpgrade) 659 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, imagePrefixForUpgrade) 660 661 // Run upgrade command - expect that the CLI asks us if we want to continue with the existing registry settings 662 // and we reply with "y" 663 err = cmd.Execute() 664 assert.NoError(t, err) 665 assert.Contains(t, outBuf.String(), proceedQuestionText) 666 assert.Contains(t, outBuf.String(), "Upgrading Verrazzano") 667 assert.Equal(t, "", errBuf.String()) 668 669 // Verify that the VPO deployment has the expected environment variables to enable pulling images from a private registry 670 // and that they are the new settings from the upgrade 671 deployment, err = cmdHelpers.GetExistingVPODeployment(c) 672 assert.NoError(t, err) 673 assert.NotNil(t, deployment) 674 testhelpers.AssertPrivateRegistryEnvVars(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 675 676 // Verify that the VPO image is using the upgrade private registry settings 677 testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 678 679 // Verify that the VPO webhook image is using the upgrade private registry settings 680 deployment, err = cmdHelpers.GetExistingVPOWebhookDeployment(c) 681 assert.NoError(t, err) 682 assert.NotNil(t, deployment) 683 684 testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 685 } 686 687 // TestUpgradeFromPrivateRegistryWithForce tests upgrading from a private registry to a different private registry using the skip confirmation flag 688 // 689 // GIVEN Verrazzano is installed from a private registry 690 // 691 // WHEN I call cmd.Execute for upgrade with different private registry settings and I set the skip confirmation flag 692 // THEN the CLI upgrade command is successful and the VPO and VPO webhook deployments have the expected private registry configuration 693 func TestUpgradeFromPrivateRegistryWithSkipConfirmation(t *testing.T) { 694 // First install using a private registry 695 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(testhelpers.CreateTestVPOObjects()...).Build() 696 errBuf := new(bytes.Buffer) 697 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: new(bytes.Buffer), ErrOut: errBuf}) 698 rc.SetClient(c) 699 cmd := install.NewCmdInstall(rc) 700 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 701 cmd.PersistentFlags().Set(constants.VersionFlag, testVZMajorRelease) 702 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, testImageRegistry) 703 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, testImagePrefix) 704 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 705 defer cmdHelpers.SetDefaultDeleteFunc() 706 707 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 708 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 709 710 install.SetValidateCRFunc(install.FakeValidateCRFunc) 711 defer install.SetDefaultValidateCRFunc() 712 713 // Run install command 714 err := cmd.Execute() 715 assert.NoError(t, err) 716 assert.Equal(t, "", errBuf.String()) 717 718 // Need to update the VZ status version otherwise upgrade fails 719 vz := &v1beta1.Verrazzano{} 720 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, vz) 721 assert.NoError(t, err) 722 723 vz.Status.Version = testVZMajorRelease 724 err = c.Status().Update(context.TODO(), vz) 725 assert.NoError(t, err) 726 727 // Now do the upgrade using different private registry settings 728 const imageRegistryForUpgrade = "newreg.io" 729 const imagePrefixForUpgrade = "newrepo" 730 731 outBuf := new(bytes.Buffer) 732 errBuf = new(bytes.Buffer) 733 rc = testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: outBuf, ErrOut: errBuf}) 734 rc.SetClient(c) 735 736 cmd = NewCmdUpgrade(rc) 737 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 738 cmd.PersistentFlags().Set(constants.VersionFlag, testVZPatchRelease) 739 cmd.PersistentFlags().Set(constants.ImageRegistryFlag, imageRegistryForUpgrade) 740 cmd.PersistentFlags().Set(constants.ImagePrefixFlag, imagePrefixForUpgrade) 741 742 // Set the "skip confirmation" flag so we do not get asked to continue with the upgrade 743 cmd.PersistentFlags().Set(constants.SkipConfirmationFlag, "true") 744 745 // Run upgrade command 746 err = cmd.Execute() 747 assert.NoError(t, err) 748 assert.Contains(t, outBuf.String(), "Upgrading Verrazzano") 749 assert.Equal(t, "", errBuf.String()) 750 751 // Verify that the VPO deployment environment variables for private registry have been updated 752 deployment, err := cmdHelpers.GetExistingVPODeployment(c) 753 assert.NoError(t, err) 754 assert.NotNil(t, deployment) 755 testhelpers.AssertPrivateRegistryEnvVars(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 756 757 // Verify that the VPO image has been updated 758 testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 759 760 // Verify that the VPO webhook image has been updated 761 deployment, err = cmdHelpers.GetExistingVPOWebhookDeployment(c) 762 assert.NoError(t, err) 763 assert.NotNil(t, deployment) 764 765 testhelpers.AssertPrivateRegistryImage(t, c, deployment, imageRegistryForUpgrade, imagePrefixForUpgrade) 766 } 767 768 // TestUpgradeCmdWithSetFlagsNoWait 769 // GIVEN a CLI upgrade command with all defaults and --wait==false 770 // 771 // WHEN I call cmd.Execute for upgrade 772 // THEN the CLI upgrade command is successful 773 func TestUpgradeCmdWithSetFlagsNoWait(t *testing.T) { 774 tests := []struct { 775 name string 776 isValidSetArgs bool 777 setArgs []string 778 }{ 779 {name: "Upgrade with valid --set args", isValidSetArgs: true, setArgs: []string{"spec.components.jaegerOperator.enabled=true"}}, 780 {name: "Upgrade with invalid --set args", isValidSetArgs: false, setArgs: []string{"s"}}, 781 } 782 for _, tt := range tests { 783 t.Run(tt.name, func(t *testing.T) { 784 vz := testhelpers.CreateVerrazzanoObjectWithVersion() 785 c := fake.NewClientBuilder().WithScheme(helpers.NewScheme()).WithObjects(append(testhelpers.CreateTestVPOObjects(), vz)...).Build() 786 787 // Send stdout stderr to a byte buffer 788 buf := new(bytes.Buffer) 789 errBuf := new(bytes.Buffer) 790 rc := testhelpers.NewFakeRootCmdContext(genericclioptions.IOStreams{In: os.Stdin, Out: buf, ErrOut: errBuf}) 791 rc.SetClient(c) 792 cmd := NewCmdUpgrade(rc) 793 assert.NotNil(t, cmd) 794 cmd.PersistentFlags().Set(constants.WaitFlag, "false") 795 cmd.PersistentFlags().Set(constants.VersionFlag, "v1.4.0") 796 for _, arg := range tt.setArgs { 797 cmd.PersistentFlags().Set(constants.SetFlag, arg) 798 } 799 cmdHelpers.SetDeleteFunc(cmdHelpers.FakeDeleteFunc) 800 defer cmdHelpers.SetDefaultDeleteFunc() 801 802 cmdHelpers.SetVPOIsReadyFunc(func(_ client.Client) (bool, error) { return true, nil }) 803 defer cmdHelpers.SetDefaultVPOIsReadyFunc() 804 805 // Run upgrade command 806 err := cmd.Execute() 807 808 if tt.isValidSetArgs { 809 // Verify the vz resource is as expected 810 vzResource := v1beta1.Verrazzano{} 811 err = c.Get(context.TODO(), types.NamespacedName{Namespace: "default", Name: "verrazzano"}, &vzResource) 812 assert.NoError(t, err) 813 isJaegerOperatorEnabled := vzResource.Spec.Components.JaegerOperator.Enabled 814 assert.NotNil(t, isJaegerOperatorEnabled) 815 assert.Equal(t, true, *isJaegerOperatorEnabled) 816 } else { 817 assert.Error(t, err) 818 } 819 820 }) 821 } 822 823 }