github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/tests/integration-service/integration.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "github.com/devfile/library/pkg/util" 9 "github.com/redhat-appstudio/e2e-tests/pkg/framework" 10 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 11 "github.com/redhat-appstudio/e2e-tests/pkg/utils/tekton" 12 "knative.dev/pkg/apis" 13 14 appstudioApi "github.com/redhat-appstudio/application-api/api/v1alpha1" 15 integrationv1alpha1 "github.com/redhat-appstudio/integration-service/api/v1alpha1" 16 17 . "github.com/onsi/ginkgo/v2" 18 . "github.com/onsi/gomega" 19 ) 20 21 const ( 22 containerImageSource = "quay.io/redhat-appstudio-qe/busybox-loop:latest" 23 gitSourceRepoName = "devfile-sample-python-basic" 24 gitSourceURL = "https://github.com/redhat-appstudio-qe/" + gitSourceRepoName 25 BundleURL = "quay.io/redhat-appstudio/example-tekton-bundle:integration-pipeline-pass" 26 BundleURLFail = "quay.io/redhat-appstudio/example-tekton-bundle:integration-pipeline-fail" 27 InPipelineName = "integration-pipeline-pass" 28 InPipelineNameFail = "integration-pipeline-fail" 29 EnvironmentName = "development" 30 IntegrationServiceUser = "integration-e2e" 31 gitURL = "https://github.com/redhat-appstudio/integration-examples.git" 32 revision = "main" 33 pathInRepo = "pipelines/integration_resolver_pipeline_pass.yaml" 34 ) 35 36 var _ = framework.IntegrationServiceSuiteDescribe("Integration Service E2E tests", Label("integration-service", "HACBS"), func() { 37 defer GinkgoRecover() 38 39 var f *framework.Framework 40 var err error 41 42 var applicationName, componentName, appStudioE2EApplicationsNamespace string 43 var timeout, interval time.Duration 44 var originalComponent *appstudioApi.Component 45 var snapshot *appstudioApi.Snapshot 46 var snapshot_push *appstudioApi.Snapshot 47 var env *appstudioApi.Environment 48 49 Describe("the component with git source (GitHub) is created", Ordered, func() { 50 51 createApp := func() { 52 applicationName = fmt.Sprintf("integ-app-%s", util.GenerateRandomString(4)) 53 appStudioE2EApplicationsNamespace = f.UserNamespace 54 55 _, err := f.AsKubeAdmin.CommonController.CreateTestNamespace(appStudioE2EApplicationsNamespace) 56 Expect(err).NotTo(HaveOccurred(), "Error when creating/updating '%s' namespace: %v", appStudioE2EApplicationsNamespace, err) 57 58 app, err := f.AsKubeAdmin.HasController.CreateHasApplication(applicationName, appStudioE2EApplicationsNamespace) 59 Expect(err).NotTo(HaveOccurred()) 60 Expect(utils.WaitUntil(f.AsKubeAdmin.HasController.ApplicationGitopsRepoExists(app.Status.Devfile), 30*time.Second)).To( 61 Succeed(), fmt.Sprintf("timed out waiting for gitops content to be created for app %s in namespace %s: %+v", app.Name, app.Namespace, err), 62 ) 63 } 64 65 createComponent := func() { 66 componentName = fmt.Sprintf("integration-suite-test-component-git-source-%s", util.GenerateRandomString(4)) 67 timeout = time.Minute * 4 68 interval = time.Second * 1 69 // Create a component with Git Source URL being defined 70 // using cdq since git ref is not known 71 cdq, err := f.AsKubeAdmin.HasController.CreateComponentDetectionQuery(componentName, appStudioE2EApplicationsNamespace, gitSourceURL, "", "", "", false) 72 Expect(err).NotTo(HaveOccurred()) 73 Expect(len(cdq.Status.ComponentDetected)).To(Equal(1), "Expected length of the detected Components was not 1") 74 75 for _, compDetected := range cdq.Status.ComponentDetected { 76 originalComponent, err = f.AsKubeAdmin.HasController.CreateComponentFromStub(compDetected, appStudioE2EApplicationsNamespace, "", "", applicationName) 77 Expect(err).NotTo(HaveOccurred()) 78 Expect(originalComponent).NotTo(BeNil()) 79 componentName = originalComponent.Name 80 } 81 } 82 83 cleanup := func() { 84 if !CurrentSpecReport().Failed() { 85 Expect(f.AsKubeAdmin.HasController.DeleteHasApplication(applicationName, appStudioE2EApplicationsNamespace, false)).To(Succeed()) 86 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(componentName, appStudioE2EApplicationsNamespace, false)).To(Succeed()) 87 integrationTestScenarios, err := f.AsKubeAdmin.IntegrationController.GetIntegrationTestScenarios(applicationName, appStudioE2EApplicationsNamespace) 88 Expect(err).ShouldNot(HaveOccurred()) 89 90 for _, testScenario := range *integrationTestScenarios { 91 Expect(f.AsKubeAdmin.IntegrationController.DeleteIntegrationTestScenario(&testScenario, appStudioE2EApplicationsNamespace)).To(Succeed()) 92 } 93 Expect(f.SandboxController.DeleteUserSignup(f.UserName)).NotTo(BeFalse()) 94 } 95 } 96 97 assertBuildPipelineRunFinished := func() { 98 timeout = time.Minute * 10 99 interval = time.Second * 2 100 Eventually(func() bool { 101 pipelineRun, err := f.AsKubeAdmin.IntegrationController.GetBuildPipelineRun(componentName, applicationName, appStudioE2EApplicationsNamespace, false, "") 102 if err != nil { 103 GinkgoWriter.Println("PipelineRun has not been created yet") 104 return false 105 } 106 return pipelineRun.HasStarted() 107 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 108 Expect(f.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(originalComponent, "", 2)).To(Succeed()) 109 } 110 111 assertSnapshotCreated := func() { 112 Eventually(func() bool { 113 // snapshotName is sent as empty since it is unknown at this stage 114 snapshot, err = f.AsKubeAdmin.IntegrationController.GetSnapshot("", "", componentName, appStudioE2EApplicationsNamespace) 115 if err != nil { 116 GinkgoWriter.Printf("cannot get the Snapshot: %v\n", err) 117 return false 118 } 119 120 GinkgoWriter.Printf("snapshot %s is found\n", snapshot.Name) 121 return true 122 }, timeout, interval).Should(BeTrue(), "timed out when trying to check if the Snapshot exists") 123 } 124 125 assertIntegrationPipelineRunFinished := func() { 126 integrationTestScenarios, err := f.AsKubeAdmin.IntegrationController.GetIntegrationTestScenarios(applicationName, appStudioE2EApplicationsNamespace) 127 Expect(err).ShouldNot(HaveOccurred()) 128 for _, testScenario := range *integrationTestScenarios { 129 timeout = time.Minute * 5 130 interval = time.Second * 2 131 Eventually(func() bool { 132 pipelineRun, err := f.AsKubeAdmin.IntegrationController.GetIntegrationPipelineRun(testScenario.Name, snapshot.Name, appStudioE2EApplicationsNamespace) 133 if err != nil { 134 GinkgoWriter.Printf("cannot get the Integration PipelineRun: %v\n", err) 135 return false 136 } 137 return pipelineRun.HasStarted() 138 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 139 Expect(f.AsKubeAdmin.IntegrationController.WaitForIntegrationPipelineToBeFinished(&testScenario, snapshot, applicationName, appStudioE2EApplicationsNamespace)).To(Succeed(), "Error when waiting for a integration pipeline to finish") 140 } 141 } 142 143 Describe("with happy path", Ordered, func() { 144 BeforeAll(func() { 145 // Initialize the tests controllers 146 f, err = framework.NewFramework(IntegrationServiceUser) 147 Expect(err).NotTo(HaveOccurred()) 148 149 createApp() 150 createComponent() 151 _, err = f.AsKubeAdmin.IntegrationController.CreateIntegrationTestScenario(applicationName, appStudioE2EApplicationsNamespace, BundleURL, InPipelineName) 152 // create a integrationTestScenario v1beta1 version works also here 153 // ex: _, err = f.AsKubeAdmin.IntegrationController.CreateIntegrationTestScenario_beta1(applicationName, appStudioE2EApplicationsNamespace, gitURL, revision, pathInRepo) 154 Expect(err).ShouldNot(HaveOccurred()) 155 }) 156 157 AfterAll(func() { 158 if !CurrentSpecReport().Failed() { 159 cleanup() 160 161 err = f.AsKubeAdmin.IntegrationController.DeleteSnapshot(snapshot_push, appStudioE2EApplicationsNamespace) 162 Expect(err).ShouldNot(HaveOccurred()) 163 } 164 }) 165 166 It("triggers a build PipelineRun", Label("integration-service"), func() { 167 assertBuildPipelineRunFinished() 168 }) 169 170 When("the build pipelineRun run succeeded", func() { 171 It("checks if the Snapshot is created", func() { 172 assertSnapshotCreated() 173 }) 174 175 It("checks if all of the integrationPipelineRuns passed", Label("slow"), func() { 176 assertIntegrationPipelineRunFinished() 177 }) 178 }) 179 180 It("creates a ReleasePlan and an environment", func() { 181 _, err = f.AsKubeAdmin.IntegrationController.CreateReleasePlan(applicationName, appStudioE2EApplicationsNamespace) 182 Expect(err).ShouldNot(HaveOccurred()) 183 env, err = f.AsKubeAdmin.IntegrationController.CreateEnvironment(appStudioE2EApplicationsNamespace, EnvironmentName) 184 Expect(err).ShouldNot(HaveOccurred()) 185 testScenarios, err := f.AsKubeAdmin.IntegrationController.GetIntegrationTestScenarios(applicationName, appStudioE2EApplicationsNamespace) 186 Expect(err).ShouldNot(HaveOccurred()) 187 for _, testScenario := range *testScenarios { 188 GinkgoWriter.Printf("IntegrationTestScenario %s is found\n", testScenario.Name) 189 } 190 }) 191 192 It("creates an snapshot of push event", func() { 193 sampleImage := "quay.io/redhat-appstudio/sample-image@sha256:841328df1b9f8c4087adbdcfec6cc99ac8308805dea83f6d415d6fb8d40227c1" 194 snapshot_push, err = f.AsKubeAdmin.IntegrationController.CreateSnapshot(applicationName, appStudioE2EApplicationsNamespace, componentName, sampleImage) 195 Expect(err).ShouldNot(HaveOccurred()) 196 GinkgoWriter.Printf("snapshot %s is found\n", snapshot_push.Name) 197 }) 198 199 When("An snapshot of push event is created", func() { 200 It("checks if all of the integrationPipelineRuns created by push event passed", Label("slow"), func() { 201 integrationTestScenarios, err := f.AsKubeAdmin.IntegrationController.GetIntegrationTestScenarios(applicationName, appStudioE2EApplicationsNamespace) 202 Expect(err).ShouldNot(HaveOccurred()) 203 204 for _, testScenario := range *integrationTestScenarios { 205 GinkgoWriter.Printf("Integration test scenario %s is found\n", testScenario.Name) 206 timeout = time.Minute * 5 207 interval = time.Second * 2 208 Eventually(func() bool { 209 pipelineRun, err := f.AsKubeAdmin.IntegrationController.GetIntegrationPipelineRun(testScenario.Name, snapshot_push.Name, appStudioE2EApplicationsNamespace) 210 if err != nil { 211 GinkgoWriter.Printf("cannot get the Integration PipelineRun: %v\n", err) 212 return false 213 } 214 return pipelineRun.HasStarted() 215 216 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 217 timeout = time.Second * 600 218 interval = time.Second * 10 219 Eventually(func() bool { 220 pipelineRun, err := f.AsKubeAdmin.IntegrationController.GetIntegrationPipelineRun(testScenario.Name, snapshot_push.Name, appStudioE2EApplicationsNamespace) 221 Expect(err).ShouldNot(HaveOccurred()) 222 223 for _, condition := range pipelineRun.Status.Conditions { 224 GinkgoWriter.Printf("PipelineRun %s Status.Conditions.Reason: %s\n", pipelineRun.Name, condition.Reason) 225 if !pipelineRun.IsDone() { 226 return false 227 } 228 229 if !pipelineRun.GetStatusCondition().GetCondition(apis.ConditionSucceeded).IsTrue() { 230 failMessage, err := tekton.GetFailedPipelineRunLogs(f.AsKubeAdmin.CommonController.KubeRest(), f.AsKubeAdmin.CommonController.KubeInterface(), pipelineRun) 231 if err != nil { 232 GinkgoWriter.Printf("failed to get logs for pipelinerun %s: %+v\n", pipelineRun.Name, err) 233 } 234 Fail(failMessage) 235 } 236 } 237 return pipelineRun.IsDone() 238 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to finish") 239 } 240 }) 241 242 It("checks if the global candidate is updated after push event", func() { 243 timeout = time.Second * 600 244 interval = time.Second * 10 245 Eventually(func() bool { 246 if f.AsKubeAdmin.IntegrationController.HaveTestsSucceeded(snapshot_push) { 247 component, err := f.AsKubeAdmin.IntegrationController.GetComponent(applicationName, appStudioE2EApplicationsNamespace) 248 if err != nil { 249 GinkgoWriter.Println("component has not been found yet") 250 return false 251 } 252 Expect(component.Spec.ContainerImage != originalComponent.Spec.ContainerImage).To(BeTrue()) 253 GinkgoWriter.Printf("Global candidate is updated\n") 254 return true 255 } 256 snapshot_push, err = f.AsKubeAdmin.IntegrationController.GetSnapshot(snapshot_push.Name, "", "", appStudioE2EApplicationsNamespace) 257 if err != nil { 258 GinkgoWriter.Printf("snapshot %s has not been found yet\n", snapshot_push.Name) 259 } 260 return false 261 }, timeout, interval).Should(BeTrue(), "time out when waiting for updating the global candidate") 262 }) 263 264 It("checks if a Release is created successfully", func() { 265 timeout = time.Second * 800 266 interval = time.Second * 10 267 Eventually(func() bool { 268 if f.AsKubeAdmin.IntegrationController.HaveTestsSucceeded(snapshot_push) { 269 releases, err := f.AsKubeAdmin.IntegrationController.GetReleasesWithSnapshot(snapshot_push, appStudioE2EApplicationsNamespace) 270 Expect(err).ShouldNot(HaveOccurred()) 271 if len(*releases) != 0 { 272 for _, release := range *releases { 273 GinkgoWriter.Printf("Release %s is found\n", release.Name) 274 } 275 } else { 276 Fail("No Release found") 277 } 278 return true 279 } 280 snapshot_push, err = f.AsKubeAdmin.IntegrationController.GetSnapshot(snapshot_push.Name, "", "", appStudioE2EApplicationsNamespace) 281 if err != nil { 282 GinkgoWriter.Printf("snapshot %s has not been found yet\n", snapshot_push.Name) 283 } 284 return false 285 }, timeout, interval).Should(BeTrue(), "time out when waiting for release created") 286 }) 287 288 It("checks if an EnvironmentBinding is created successfully", func() { 289 timeout = time.Second * 600 290 interval = time.Second * 2 291 Eventually(func() bool { 292 if f.AsKubeAdmin.IntegrationController.HaveTestsSucceeded(snapshot_push) { 293 envbinding, err := f.AsKubeAdmin.IntegrationController.GetSnapshotEnvironmentBinding(applicationName, appStudioE2EApplicationsNamespace, env) 294 Expect(err).ShouldNot(HaveOccurred()) 295 Expect(envbinding != nil).To(BeTrue()) 296 GinkgoWriter.Printf("The EnvironmentBinding is created\n") 297 return true 298 } 299 snapshot_push, err = f.AsKubeAdmin.IntegrationController.GetSnapshot(snapshot_push.Name, "", "", appStudioE2EApplicationsNamespace) 300 if err != nil { 301 GinkgoWriter.Printf("snapshot %s has not been found yet\n", snapshot_push.Name) 302 } 303 return false 304 }, timeout, interval).Should(BeTrue(), "time out when waiting for release created") 305 }) 306 }) 307 }) 308 309 Describe("with an integration test fail", Ordered, func() { 310 BeforeAll(func() { 311 // Initialize the tests controllers 312 f, err = framework.NewFramework(IntegrationServiceUser) 313 Expect(err).NotTo(HaveOccurred()) 314 315 createApp() 316 createComponent() 317 _, err = f.AsKubeAdmin.IntegrationController.CreateIntegrationTestScenario(applicationName, appStudioE2EApplicationsNamespace, BundleURLFail, InPipelineNameFail) 318 Expect(err).ShouldNot(HaveOccurred()) 319 }) 320 321 AfterAll(func() { 322 if !CurrentSpecReport().Failed() { 323 cleanup() 324 } 325 }) 326 327 It("triggers a build PipelineRun", Label("integration-service"), func() { 328 assertBuildPipelineRunFinished() 329 }) 330 331 It("checks if the Snapshot is created", func() { 332 assertSnapshotCreated() 333 }) 334 335 It("checks if all of the integrationPipelineRuns finished", Label("slow"), func() { 336 assertIntegrationPipelineRunFinished() 337 }) 338 339 It("checks if snapshot is marked as failed", func() { 340 Eventually(func() bool { 341 snapshot, err := f.AsKubeAdmin.IntegrationController.GetSnapshot(snapshot.Name, "", "", appStudioE2EApplicationsNamespace) 342 if err != nil { 343 GinkgoWriter.Printf("cannot get the Snapshot: %v\n", err) 344 return false 345 } 346 347 GinkgoWriter.Printf("snapshot %s is found\n", snapshot.Name) 348 return !f.AsKubeAdmin.IntegrationController.HaveTestsSucceeded(snapshot) 349 }, timeout, interval).Should(BeTrue(), "time out when trying to check if either the Snapshot exists or if the Snapshot is marked as failed") 350 }) 351 352 It("checks if the global candidate is not updated", func() { 353 // give some time to do eventual updates in component 354 time.Sleep(60 * time.Second) 355 356 component, err := f.AsKubeAdmin.IntegrationController.GetComponent(applicationName, appStudioE2EApplicationsNamespace) 357 Expect(err).ShouldNot(HaveOccurred()) 358 359 // global candidate is not updated 360 Expect(component.Spec.ContainerImage == originalComponent.Spec.ContainerImage).To(BeTrue()) 361 362 }) 363 }) 364 365 Describe("valid dtcls doesn't exist", Ordered, func() { 366 var integrationTestScenario_alpha1 *integrationv1alpha1.IntegrationTestScenario 367 BeforeAll(func() { 368 // Initialize the tests controllers 369 f, err = framework.NewFramework(IntegrationServiceUser) 370 Expect(err).NotTo(HaveOccurred()) 371 372 createApp() 373 createComponent() 374 375 integrationTestScenario_alpha1, err = f.AsKubeAdmin.IntegrationController.CreateIntegrationTestScenarioWithEnvironment(applicationName, appStudioE2EApplicationsNamespace, BundleURL, InPipelineName, EnvironmentName) 376 Expect(err).ShouldNot(HaveOccurred()) 377 env, err = f.AsKubeAdmin.IntegrationController.CreateEnvironment(appStudioE2EApplicationsNamespace, EnvironmentName) 378 Expect(err).ShouldNot(HaveOccurred()) 379 }) 380 381 AfterAll(func() { 382 if !CurrentSpecReport().Failed() { 383 cleanup() 384 385 Expect(f.AsKubeAdmin.GitOpsController.DeleteAllEnvironmentsInASpecificNamespace(appStudioE2EApplicationsNamespace, 30*time.Second)).To(Succeed()) 386 Expect(f.AsKubeAdmin.IntegrationController.DeleteSnapshot(snapshot_push, appStudioE2EApplicationsNamespace)).To(BeNil()) 387 } 388 }) 389 390 It("valid deploymentTargetClass doesn't exist", func() { 391 validDTCLS, err := f.AsKubeAdmin.IntegrationController.HaveAvailableDeploymentTargetClassExist() 392 Expect(validDTCLS).To(BeNil()) 393 Expect(err).To(BeNil()) 394 }) 395 396 It("creates a snapshot of push event", func() { 397 sampleImage := "quay.io/redhat-appstudio/sample-image@sha256:841328df1b9f8c4087adbdcfec6cc99ac8308805dea83f6d415d6fb8d40227c1" 398 snapshot_push, err = f.AsKubeAdmin.IntegrationController.CreateSnapshot(applicationName, appStudioE2EApplicationsNamespace, componentName, sampleImage) 399 Expect(err).ShouldNot(HaveOccurred()) 400 GinkgoWriter.Printf("snapshot %s is found\n", snapshot_push.Name) 401 }) 402 403 When("nonexisting valid deploymentTargetClass", func() { 404 It("check no GitOpsCR is created for the dtc with nonexisting deploymentTargetClass", func() { 405 spaceRequestList, err := f.AsKubeAdmin.IntegrationController.GetSpaceRequests(appStudioE2EApplicationsNamespace) 406 Expect(err).To(BeNil()) 407 Expect(len(spaceRequestList.Items) > 0).To(BeFalse()) 408 409 deploymentTargetList, err := f.AsKubeAdmin.IntegrationController.GetDeploymentTargets(appStudioE2EApplicationsNamespace) 410 Expect(err).To(BeNil()) 411 Expect(len(deploymentTargetList.Items) > 0).To(BeFalse()) 412 413 deploymentTargetClaimList, err := f.AsKubeAdmin.IntegrationController.GetDeploymentTargetClaims(appStudioE2EApplicationsNamespace) 414 Expect(err).To(BeNil()) 415 Expect(len(deploymentTargetClaimList.Items) > 0).To(BeFalse()) 416 417 environmentList, err := f.AsKubeAdmin.IntegrationController.GetEnvironments(appStudioE2EApplicationsNamespace) 418 Expect(err).To(BeNil()) 419 Expect(len(environmentList.Items) > 1).To(BeFalse()) 420 421 pipelineRun, err := f.AsKubeAdmin.IntegrationController.GetIntegrationPipelineRun(integrationTestScenario_alpha1.Name, snapshot_push.Name, appStudioE2EApplicationsNamespace) 422 Expect(pipelineRun.Name == "" && strings.Contains(err.Error(), "no pipelinerun found")).To(BeTrue()) 423 }) 424 It("checks if snapshot is not marked as passed", func() { 425 snapshot, err := f.AsKubeAdmin.IntegrationController.GetSnapshot(snapshot_push.Name, "", "", appStudioE2EApplicationsNamespace) 426 Expect(err).ShouldNot(HaveOccurred()) 427 Expect(f.AsKubeAdmin.IntegrationController.HaveTestsSucceeded(snapshot)).To(BeFalse()) 428 }) 429 }) 430 }) 431 }) 432 })