github.com/redhat-appstudio/e2e-tests@v0.0.0-20230619105049-9a422b2094d7/tests/build/build.go (about) 1 package build 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 "time" 8 9 "k8s.io/utils/pointer" 10 11 "github.com/google/go-github/v44/github" 12 appservice "github.com/redhat-appstudio/application-api/api/v1alpha1" 13 "github.com/redhat-appstudio/e2e-tests/pkg/utils/build" 14 "github.com/redhat-appstudio/e2e-tests/pkg/utils/tekton" 15 16 "github.com/devfile/library/pkg/util" 17 "github.com/redhat-appstudio/e2e-tests/pkg/constants" 18 "github.com/redhat-appstudio/e2e-tests/pkg/utils" 19 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" 20 k8sErrors "k8s.io/apimachinery/pkg/api/errors" 21 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 23 . "github.com/onsi/ginkgo/v2" 24 . "github.com/onsi/gomega" 25 routev1 "github.com/openshift/api/route/v1" 26 buildservice "github.com/redhat-appstudio/build-service/api/v1alpha1" 27 "github.com/redhat-appstudio/e2e-tests/pkg/framework" 28 v1 "k8s.io/api/core/v1" 29 ) 30 31 var _ = framework.BuildSuiteDescribe("Build service E2E tests", Label("build", "HACBS"), func() { 32 var f *framework.Framework 33 var pacControllerRoute *routev1.Route 34 35 var err error 36 defer GinkgoRecover() 37 38 Describe("test PaC component build", Ordered, Label("github-webhook", "pac-build", "pipeline", "image-controller"), func() { 39 var applicationName, componentName, componentBaseBranchName, pacBranchName, testNamespace, pacControllerHost, defaultBranchTestComponentName, imageRepoName, robotAccountName string 40 var component *appservice.Component 41 42 var timeout, interval time.Duration 43 44 var prNumber int 45 var prCreationTime time.Time 46 47 BeforeAll(func() { 48 49 f, err = framework.NewFramework(utils.GetGeneratedNamespace("build-e2e")) 50 Expect(err).NotTo(HaveOccurred()) 51 testNamespace = f.UserNamespace 52 53 consoleRoute, err := f.AsKubeAdmin.CommonController.GetOpenshiftRoute("console", "openshift-console") 54 Expect(err).ShouldNot(HaveOccurred()) 55 56 if utils.IsPrivateHostname(consoleRoute.Spec.Host) { 57 Skip("Using private cluster (not reachable from Github), skipping...") 58 } 59 60 // Used for identifying related webhook on GitHub - in order to delete it 61 // TODO: Remove when https://github.com/redhat-appstudio/infra-deployments/pull/1725 it is merged 62 pacControllerRoute, err = f.AsKubeAdmin.CommonController.GetOpenshiftRoute("pipelines-as-code-controller", "pipelines-as-code") 63 if err != nil { 64 if k8sErrors.IsNotFound(err) { 65 pacControllerRoute, err = f.AsKubeAdmin.CommonController.GetOpenshiftRoute("pipelines-as-code-controller", "openshift-pipelines") 66 } 67 } 68 Expect(err).ShouldNot(HaveOccurred()) 69 pacControllerHost = pacControllerRoute.Spec.Host 70 71 applicationName = fmt.Sprintf("build-suite-test-application-%s", util.GenerateRandomString(4)) 72 app, err := f.AsKubeAdmin.HasController.CreateHasApplication(applicationName, testNamespace) 73 Expect(err).NotTo(HaveOccurred()) 74 Expect(utils.WaitUntil(f.AsKubeAdmin.HasController.ApplicationGitopsRepoExists(app.Status.Devfile), 30*time.Second)).To( 75 Succeed(), fmt.Sprintf("timed out waiting for gitops content to be created for app %s in namespace %s: %+v", app.Name, app.Namespace, err), 76 ) 77 78 componentName = fmt.Sprintf("%s-%s", "test-component-pac", util.GenerateRandomString(4)) 79 pacBranchName = constants.PaCPullRequestBranchPrefix + componentName 80 componentBaseBranchName = fmt.Sprintf("base-%s", util.GenerateRandomString(4)) 81 82 err = f.AsKubeAdmin.CommonController.Github.CreateRef(helloWorldComponentGitSourceRepoName, helloWorldComponentDefaultBranch, componentBaseBranchName) 83 Expect(err).ShouldNot(HaveOccurred()) 84 85 defaultBranchTestComponentName = fmt.Sprintf("test-custom-default-branch-%s", util.GenerateRandomString(4)) 86 }) 87 88 AfterAll(func() { 89 if !CurrentSpecReport().Failed() { 90 Expect(f.AsKubeAdmin.HasController.DeleteHasApplication(applicationName, testNamespace, false)).To(Succeed()) 91 Expect(f.SandboxController.DeleteUserSignup(f.UserName)).NotTo(BeFalse()) 92 } 93 94 // Delete new branches created by PaC and a testing branch used as a component's base branch 95 err = f.AsKubeAdmin.CommonController.Github.DeleteRef(helloWorldComponentGitSourceRepoName, pacBranchName) 96 if err != nil { 97 Expect(err.Error()).To(ContainSubstring("Reference does not exist")) 98 } 99 err = f.AsKubeAdmin.CommonController.Github.DeleteRef(helloWorldComponentGitSourceRepoName, componentBaseBranchName) 100 if err != nil { 101 Expect(err.Error()).To(ContainSubstring("Reference does not exist")) 102 } 103 err = f.AsKubeAdmin.CommonController.Github.DeleteRef(helloWorldComponentGitSourceRepoName, constants.PaCPullRequestBranchPrefix+defaultBranchTestComponentName) 104 if err != nil { 105 Expect(err.Error()).To(ContainSubstring("Reference does not exist")) 106 } 107 108 // Delete created webhook from GitHub 109 hooks, err := f.AsKubeAdmin.CommonController.Github.ListRepoWebhooks(helloWorldComponentGitSourceRepoName) 110 Expect(err).NotTo(HaveOccurred()) 111 112 for _, h := range hooks { 113 hookUrl := h.Config["url"].(string) 114 if strings.Contains(hookUrl, pacControllerHost) { 115 Expect(f.AsKubeAdmin.CommonController.Github.DeleteWebhook(helloWorldComponentGitSourceRepoName, h.GetID())).To(Succeed()) 116 break 117 } 118 } 119 120 //Delete the quay image repo since we are setting delete-repo=false 121 _, err = build.DeleteImageRepo(imageRepoName) 122 Expect(err).NotTo(HaveOccurred(), "Failed to delete image repo with error: %+v", err) 123 124 }) 125 126 When("a new component without specified branch is created", Label("pac-custom-default-branch"), func() { 127 BeforeAll(func() { 128 deleteRepo := false 129 _, err = f.AsKubeDeveloper.HasController.CreateComponentWithPaCEnabled(applicationName, defaultBranchTestComponentName, testNamespace, helloWorldComponentGitSourceURL, "", deleteRepo) 130 Expect(err).ShouldNot(HaveOccurred()) 131 }) 132 133 It("correctly targets the default branch (that is not named 'main') with PaC", func() { 134 timeout = time.Second * 300 135 interval = time.Second * 1 136 Eventually(func() bool { 137 prs, err := f.AsKubeAdmin.CommonController.Github.ListPullRequests(helloWorldComponentGitSourceRepoName) 138 Expect(err).ShouldNot(HaveOccurred()) 139 140 for _, pr := range prs { 141 if pr.Head.GetRef() == constants.PaCPullRequestBranchPrefix+defaultBranchTestComponentName { 142 Expect(pr.GetBase().GetRef()).To(Equal(helloWorldComponentDefaultBranch)) 143 return true 144 } 145 } 146 return false 147 }, timeout, interval).Should(BeTrue(), "timed out when waiting for init PaC PR to be created") 148 }) 149 It("triggers a PipelineRun", func() { 150 timeout = time.Second * 600 151 interval = time.Second * 1 152 Eventually(func() bool { 153 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(defaultBranchTestComponentName, applicationName, testNamespace, "") 154 if err != nil { 155 GinkgoWriter.Println("PipelineRun has not been created yet") 156 return false 157 } 158 return pipelineRun.HasStarted() 159 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 160 }) 161 It("image repo and robot account created successfully", func() { 162 component, err := f.AsKubeAdmin.HasController.GetHasComponent(defaultBranchTestComponentName, testNamespace) 163 Expect(err).ShouldNot(HaveOccurred(), "could not get component %s in the %s namespace", defaultBranchTestComponentName, testNamespace) 164 165 annotations := component.GetAnnotations() 166 imageRepoName, err = build.GetQuayImageName(annotations) 167 Expect(err).ShouldNot(HaveOccurred(), "failed to read image repo name from %+v", annotations) 168 169 imageExist, err := build.DoesImageRepoExistInQuay(imageRepoName) 170 Expect(err).ShouldNot(HaveOccurred(), "failed while checking if image repo exists in quay with error: %+v", err) 171 Expect(imageExist).To(BeTrue(), "quay image does not exists") 172 173 robotAccountName = build.GetRobotAccountName(imageRepoName) 174 robotAccountExist, err := build.DoesRobotAccountExistInQuay(robotAccountName) 175 Expect(err).ShouldNot(HaveOccurred(), "failed while checking if robot account exists in quay with error: %+v", err) 176 Expect(robotAccountExist).To(BeTrue(), "quay robot account does not exists") 177 178 }) 179 It("a related PipelineRun and Github webhook should be deleted after deleting the component", func() { 180 timeout = time.Second * 60 181 interval = time.Second * 1 182 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(defaultBranchTestComponentName, testNamespace, true)).To(Succeed()) 183 // Test removal of PipelineRun 184 Eventually(func() bool { 185 _, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(defaultBranchTestComponentName, applicationName, testNamespace, "") 186 return err != nil && strings.Contains(err.Error(), "no pipelinerun found") 187 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 188 // Test removal of related webhook in GitHub repo 189 Eventually(func() bool { 190 hooks, err := f.AsKubeAdmin.CommonController.Github.ListRepoWebhooks(helloWorldComponentGitSourceRepoName) 191 Expect(err).NotTo(HaveOccurred()) 192 193 for _, h := range hooks { 194 hookUrl := h.Config["url"].(string) 195 if strings.Contains(hookUrl, pacControllerHost) { 196 return false 197 } 198 } 199 return true 200 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 201 }) 202 It("PR branch should not exists in the repo", func() { 203 timeout = time.Second * 60 204 interval = time.Second * 1 205 Eventually(func() bool { 206 exists, err := f.AsKubeAdmin.CommonController.Github.ExistsRef(helloWorldComponentGitSourceRepoName, constants.PaCPullRequestBranchPrefix+defaultBranchTestComponentName) 207 Expect(err).ShouldNot(HaveOccurred()) 208 return exists 209 }, timeout, interval).Should(BeFalse(), "timed out when waiting for the branch to be deleted") 210 }) 211 It("related image repo should not be deleted but the robot account should be deleted after deleting the component", func() { 212 timeout = time.Second * 60 213 interval = time.Second * 1 214 // Check image repo should not be deleted 215 Eventually(func() (bool, error) { 216 return build.DoesImageRepoExistInQuay(imageRepoName) 217 }, timeout, interval).Should(BeTrue(), "timed out when checking if image repo got deleted") 218 // Check robot account should be deleted 219 Eventually(func() (bool, error) { 220 return build.DoesRobotAccountExistInQuay(robotAccountName) 221 }, timeout, interval).Should(BeFalse(), "timed out when checking if robot account got deleted") 222 223 }) 224 }) 225 226 When("a new Component with specified custom branch is created", Label("custom-branch"), func() { 227 BeforeAll(func() { 228 // Create a component with Git Source URL, a specified git branch and marking delete-repo=true 229 deleteRepo := true 230 component, err = f.AsKubeAdmin.HasController.CreateComponentWithPaCEnabled(applicationName, componentName, testNamespace, helloWorldComponentGitSourceURL, componentBaseBranchName, deleteRepo) 231 Expect(err).ShouldNot(HaveOccurred()) 232 }) 233 It("triggers a PipelineRun", func() { 234 timeout = time.Second * 600 235 interval = time.Second * 1 236 Eventually(func() bool { 237 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 238 if err != nil { 239 GinkgoWriter.Println("PipelineRun has not been created yet") 240 return false 241 } 242 return pipelineRun.HasStarted() 243 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 244 }) 245 It("should lead to a PaC init PR creation", func() { 246 timeout = time.Second * 300 247 interval = time.Second * 1 248 249 Eventually(func() bool { 250 prs, err := f.AsKubeAdmin.CommonController.Github.ListPullRequests(helloWorldComponentGitSourceRepoName) 251 Expect(err).ShouldNot(HaveOccurred()) 252 253 for _, pr := range prs { 254 if pr.Head.GetRef() == pacBranchName { 255 prNumber = pr.GetNumber() 256 prCreationTime = pr.GetCreatedAt() 257 return true 258 } 259 } 260 return false 261 }, timeout, interval).Should(BeTrue(), "timed out when waiting for init PaC PR to be created") 262 }) 263 It("the PipelineRun should eventually finish successfully", func() { 264 Expect(f.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(component, "", 2)).To(Succeed()) 265 }) 266 It("image repo and robot account created successfully", func() { 267 268 component, err := f.AsKubeAdmin.HasController.GetHasComponent(componentName, testNamespace) 269 Expect(err).ShouldNot(HaveOccurred(), "could not get component %s in the %s namespace", componentName, testNamespace) 270 271 annotations := component.GetAnnotations() 272 imageRepoName, err = build.GetQuayImageName(annotations) 273 Expect(err).ShouldNot(HaveOccurred(), "failed to read image repo name from %+v", annotations) 274 275 imageExist, err := build.DoesImageRepoExistInQuay(imageRepoName) 276 Expect(err).ShouldNot(HaveOccurred(), "failed while checking if image repo exists in quay with error: %+v", err) 277 Expect(imageExist).To(BeTrue(), "quay image does not exists") 278 279 robotAccountName = build.GetRobotAccountName(imageRepoName) 280 robotAccountExist, err := build.DoesRobotAccountExistInQuay(robotAccountName) 281 Expect(err).ShouldNot(HaveOccurred(), "failed while checking if robot account exists in quay with error: %+v") 282 Expect(robotAccountExist).To(BeTrue(), "quay robot account does not exists") 283 284 }) 285 }) 286 287 When("image tag is updated successfully", func() { 288 //TODO: check if image tag present once below issue is resolved 289 // https://issues.redhat.com/browse/SRVKP-3064 290 // https://github.com/openshift-pipelines/pipeline-service/pull/632 291 292 It("should ensure pruning labels are set", func() { 293 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 294 Expect(err).ShouldNot(HaveOccurred()) 295 296 image, err := build.ImageFromPipelineRun(pipelineRun) 297 Expect(err).ShouldNot(HaveOccurred()) 298 299 labels := image.Config.Config.Labels 300 Expect(labels).ToNot(BeEmpty()) 301 302 expiration, ok := labels["quay.expires-after"] 303 Expect(ok).To(BeTrue()) 304 Expect(expiration).To(Equal(utils.GetEnv(constants.IMAGE_TAG_EXPIRATION_ENV, constants.DefaultImageTagExpiration))) 305 }) 306 It("eventually leads to a creation of a PR comment with the PipelineRun status report", func() { 307 var comments []*github.IssueComment 308 timeout = time.Minute * 15 309 interval = time.Second * 10 310 311 Eventually(func() bool { 312 comments, err = f.AsKubeAdmin.CommonController.Github.ListPullRequestCommentsSince(helloWorldComponentGitSourceRepoName, prNumber, prCreationTime) 313 Expect(err).ShouldNot(HaveOccurred()) 314 315 return len(comments) != 0 316 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PaC PR comment about the pipelinerun status to appear in the component repo") 317 318 // TODO uncomment once https://issues.redhat.com/browse/SRVKP-2471 is sorted 319 //Expect(comments).To(HaveLen(1), fmt.Sprintf("the initial PR has more than 1 comment after a single pipelinerun. repo: %s, pr number: %d, comments content: %v", helloWorldComponentGitSourceURL, prNumber, comments)) 320 Expect(comments[len(comments)-1]).To(ContainSubstring("success"), "the initial PR doesn't contain the info about successful pipelinerun") 321 }) 322 }) 323 324 When("the PaC init branch is updated", func() { 325 var branchUpdateTimestamp time.Time 326 var createdFileSHA string 327 328 BeforeAll(func() { 329 fileToCreatePath := fmt.Sprintf(".tekton/%s-readme.md", componentName) 330 branchUpdateTimestamp = time.Now() 331 createdFile, err := f.AsKubeAdmin.CommonController.Github.CreateFile(helloWorldComponentGitSourceRepoName, fileToCreatePath, fmt.Sprintf("test PaC branch %s update", pacBranchName), pacBranchName) 332 Expect(err).NotTo(HaveOccurred()) 333 334 createdFileSHA = createdFile.GetSHA() 335 GinkgoWriter.Println("created file sha:", createdFileSHA) 336 }) 337 338 It("eventually leads to triggering another PipelineRun", func() { 339 timeout = time.Minute * 7 340 interval = time.Second * 1 341 342 Eventually(func() bool { 343 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, createdFileSHA) 344 if err != nil { 345 GinkgoWriter.Println("PipelineRun has not been created yet") 346 return false 347 } 348 return pipelineRun.HasStarted() 349 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 350 }) 351 It("PipelineRun should eventually finish", func() { 352 Expect(f.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(component, createdFileSHA, 2)).To(Succeed()) 353 }) 354 It("eventually leads to another update of a PR with a comment about the PipelineRun status report", func() { 355 var comments []*github.IssueComment 356 357 timeout = time.Minute * 20 358 interval = time.Second * 5 359 360 Eventually(func() bool { 361 comments, err = f.AsKubeAdmin.CommonController.Github.ListPullRequestCommentsSince(helloWorldComponentGitSourceRepoName, prNumber, branchUpdateTimestamp) 362 Expect(err).ShouldNot(HaveOccurred()) 363 364 return len(comments) != 0 365 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PaC PR comment about the pipelinerun status to appear in the component repo") 366 367 // TODO uncomment once https://issues.redhat.com/browse/SRVKP-2471 is sorted 368 //Expect(comments).To(HaveLen(1), fmt.Sprintf("the updated PaC PR has more than 1 comment after a single branch update. repo: %s, pr number: %d, comments content: %v", helloWorldComponentGitSourceURL, prNumber, comments)) 369 Expect(comments[len(comments)-1]).To(ContainSubstring("success"), "the updated PR doesn't contain the info about successful pipelinerun") 370 }) 371 }) 372 373 When("the PaC init branch is merged", func() { 374 var mergeResult *github.PullRequestMergeResult 375 var mergeResultSha string 376 var pipelineRun *v1beta1.PipelineRun 377 378 BeforeAll(func() { 379 Eventually(func() error { 380 mergeResult, err = f.AsKubeAdmin.CommonController.Github.MergePullRequest(helloWorldComponentGitSourceRepoName, prNumber) 381 return err 382 }, time.Minute).Should(BeNil(), fmt.Sprintf("error when merging PaC pull request: %+v", err)) 383 384 mergeResultSha = mergeResult.GetSHA() 385 GinkgoWriter.Println("merged result sha:", mergeResultSha) 386 }) 387 388 It("eventually leads to triggering another PipelineRun", func() { 389 timeout = time.Minute * 10 390 interval = time.Second * 1 391 392 Eventually(func() bool { 393 pipelineRun, err = f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, mergeResultSha) 394 if err != nil { 395 GinkgoWriter.Println("PipelineRun has not been created yet") 396 return false 397 } 398 return pipelineRun.HasStarted() 399 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 400 }) 401 402 It("pipelineRun should eventually finish", func() { 403 Expect(f.AsKubeAdmin.HasController.WaitForComponentPipelineToBeFinished(component, mergeResultSha, 2)).To(Succeed()) 404 }) 405 406 It("does not have expiration set", func() { 407 image, err := build.ImageFromPipelineRun(pipelineRun) 408 Expect(err).ShouldNot(HaveOccurred()) 409 410 labels := image.Config.Config.Labels 411 Expect(labels).ToNot(BeEmpty()) 412 413 expiration, ok := labels["quay.expires-after"] 414 Expect(ok).To(BeFalse()) 415 Expect(expiration).To(BeEmpty()) 416 }) 417 }) 418 419 When("the component is removed and recreated (with the same name in the same namespace)", func() { 420 BeforeAll(func() { 421 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(componentName, testNamespace, true)).To(Succeed()) 422 423 timeout := 1 * time.Minute 424 interval := 1 * time.Second 425 Eventually(func() bool { 426 _, err := f.AsKubeAdmin.HasController.GetHasComponent(componentName, testNamespace) 427 return k8sErrors.IsNotFound(err) 428 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the app %s to be deleted in %s namespace", applicationName, testNamespace) 429 // Check removal of image repo 430 Eventually(func() (bool, error) { 431 return build.DoesImageRepoExistInQuay(imageRepoName) 432 }, timeout, interval).Should(BeFalse(), "timed out when waiting for image repo to be deleted") 433 // Check removal of robot account 434 Eventually(func() (bool, error) { 435 return build.DoesRobotAccountExistInQuay(robotAccountName) 436 }, timeout, interval).Should(BeFalse(), "timed out when waiting for robot account to be deleted") 437 438 deleteRepo := true 439 _, err = f.AsKubeAdmin.HasController.CreateComponentWithPaCEnabled(applicationName, componentName, testNamespace, helloWorldComponentGitSourceURL, componentBaseBranchName, deleteRepo) 440 }) 441 442 It("should no longer lead to a creation of a PaC PR", func() { 443 timeout = time.Second * 40 444 interval = time.Second * 2 445 Consistently(func() bool { 446 prs, err := f.AsKubeAdmin.CommonController.Github.ListPullRequests(helloWorldComponentGitSourceRepoName) 447 Expect(err).ShouldNot(HaveOccurred()) 448 449 for _, pr := range prs { 450 if pr.Head.GetRef() == pacBranchName { 451 return true 452 } 453 } 454 return false 455 }, timeout, interval).Should(BeFalse(), "did not expect a new PR created after initial PaC configuration was already merged for the same component name and a namespace") 456 }) 457 }) 458 }) 459 460 Describe("Creating component with container image source", Ordered, func() { 461 462 var applicationName, componentName, testNamespace string 463 var timeout, interval time.Duration 464 465 BeforeAll(func() { 466 applicationName = fmt.Sprintf("test-app-%s", util.GenerateRandomString(4)) 467 f, err = framework.NewFramework(utils.GetGeneratedNamespace("build-e2e")) 468 Expect(err).NotTo(HaveOccurred()) 469 testNamespace = f.UserNamespace 470 471 app, err := f.AsKubeAdmin.HasController.CreateHasApplication(applicationName, testNamespace) 472 Expect(err).NotTo(HaveOccurred()) 473 Expect(utils.WaitUntil(f.AsKubeAdmin.HasController.ApplicationGitopsRepoExists(app.Status.Devfile), 30*time.Second)).To( 474 Succeed(), fmt.Sprintf("timed out waiting for gitops content to be created for app %s in namespace %s: %+v", app.Name, app.Namespace, err), 475 ) 476 477 componentName = fmt.Sprintf("build-suite-test-component-image-source-%s", util.GenerateRandomString(4)) 478 outputContainerImage := "" 479 timeout = time.Second * 500 480 interval = time.Second * 1 481 // Create a component with containerImageSource being defined 482 _, err = f.AsKubeAdmin.HasController.CreateComponent(applicationName, componentName, testNamespace, "", "", containerImageSource, outputContainerImage, "", true) 483 Expect(err).ShouldNot(HaveOccurred()) 484 }) 485 486 AfterAll(func() { 487 if !CurrentSpecReport().Failed() { 488 Expect(f.AsKubeAdmin.HasController.DeleteHasApplication(applicationName, testNamespace, false)).To(Succeed()) 489 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(componentName, testNamespace, false)).To(Succeed()) 490 Expect(f.AsKubeAdmin.TektonController.DeleteAllPipelineRunsInASpecificNamespace(testNamespace)).To(Succeed()) 491 Expect(f.SandboxController.DeleteUserSignup(f.UserName)).NotTo(BeFalse()) 492 } 493 }) 494 495 It("should not trigger a PipelineRun", func() { 496 Consistently(func() bool { 497 _, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 498 Expect(err).NotTo(BeNil()) 499 return strings.Contains(err.Error(), "no pipelinerun found") 500 }, timeout, interval).Should(BeTrue(), fmt.Sprintf("expected no PipelineRun to be triggered for the component %s in %s namespace", componentName, testNamespace)) 501 }) 502 }) 503 504 Describe("PLNSRVCE-799 - test pipeline selector", Label("pipeline-selector"), Ordered, func() { 505 var timeout, interval time.Duration 506 var componentName, applicationName, testNamespace string 507 var expectedAdditionalPipelineParam buildservice.PipelineParam 508 509 BeforeAll(func() { 510 f, err = framework.NewFramework(utils.GetGeneratedNamespace("build-e2e")) 511 Expect(err).NotTo(HaveOccurred()) 512 testNamespace = f.UserNamespace 513 applicationName = fmt.Sprintf("test-app-%s", util.GenerateRandomString(4)) 514 515 app, err := f.AsKubeAdmin.HasController.CreateHasApplication(applicationName, testNamespace) 516 Expect(err).NotTo(HaveOccurred()) 517 Expect(utils.WaitUntil(f.AsKubeAdmin.HasController.ApplicationGitopsRepoExists(app.Status.Devfile), 30*time.Second)).To( 518 Succeed(), fmt.Sprintf("timed out waiting for gitops content to be created for app %s in namespace %s: %+v", app.Name, app.Namespace, err), 519 ) 520 521 componentName = "build-suite-test-bundle-overriding" 522 523 expectedAdditionalPipelineParam = buildservice.PipelineParam{ 524 Name: "test-custom-param-name", 525 Value: "test-custom-param-value", 526 } 527 528 timeout = time.Second * 600 529 interval = time.Second * 1 530 }) 531 532 AfterAll(func() { 533 if !CurrentSpecReport().Failed() { 534 Expect(f.AsKubeAdmin.HasController.DeleteHasApplication(applicationName, testNamespace, false)).To(Succeed()) 535 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(componentName, testNamespace, false)).To(Succeed()) 536 Expect(f.AsKubeAdmin.TektonController.DeleteAllPipelineRunsInASpecificNamespace(testNamespace)).To(Succeed()) 537 Expect(f.SandboxController.DeleteUserSignup(f.UserName)).NotTo(BeFalse()) 538 } 539 }) 540 541 It("a specific Pipeline bundle should be used and additional pipeline params should be added to the PipelineRun if all WhenConditions match", func() { 542 // using cdq since git ref is not known 543 cdq, err := f.AsKubeAdmin.HasController.CreateComponentDetectionQuery(componentName, testNamespace, helloWorldComponentGitSourceURL, "", "", "", false) 544 Expect(err).NotTo(HaveOccurred()) 545 Expect(len(cdq.Status.ComponentDetected)).To(Equal(1), "Expected length of the detected Components was not 1") 546 547 for _, compDetected := range cdq.Status.ComponentDetected { 548 // Since we only know the component name after cdq creation, 549 // BuildPipelineSelector should be created before component creation and after cdq creation 550 ps := &buildservice.BuildPipelineSelector{ 551 ObjectMeta: metav1.ObjectMeta{ 552 Name: "build-pipeline-selector", 553 Namespace: testNamespace, 554 }, 555 Spec: buildservice.BuildPipelineSelectorSpec{Selectors: []buildservice.PipelineSelector{ 556 { 557 Name: "user-custom-selector", 558 PipelineRef: v1beta1.PipelineRef{ 559 Name: "docker-build", 560 Bundle: dummyPipelineBundleRef, 561 }, 562 PipelineParams: []buildservice.PipelineParam{expectedAdditionalPipelineParam}, 563 WhenConditions: buildservice.WhenCondition{ 564 ProjectType: "hello-world", 565 DockerfileRequired: pointer.Bool(true), 566 ComponentName: compDetected.ComponentStub.ComponentName, 567 Annotations: map[string]string{"skip-initial-checks": "true"}, 568 Labels: constants.ComponentDefaultLabel, 569 }, 570 }, 571 }}, 572 } 573 574 Expect(f.AsKubeAdmin.CommonController.KubeRest().Create(context.TODO(), ps)).To(Succeed()) 575 576 c, err := f.AsKubeAdmin.HasController.CreateComponentFromStub(compDetected, testNamespace, "", "", applicationName) 577 Expect(err).NotTo(HaveOccurred()) 578 componentName = c.Name 579 } 580 581 Eventually(func() bool { 582 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 583 if err != nil { 584 GinkgoWriter.Println("PipelineRun has not been created yet") 585 return false 586 } 587 return pipelineRun.HasStarted() 588 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 589 590 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 591 Expect(err).ShouldNot(HaveOccurred()) 592 Expect(pipelineRun.Spec.PipelineRef.Bundle).To(Equal(dummyPipelineBundleRef)) 593 Expect(pipelineRun.Spec.Params).To(ContainElement(v1beta1.Param{ 594 Name: expectedAdditionalPipelineParam.Name, 595 Value: v1beta1.ParamValue{StringVal: expectedAdditionalPipelineParam.Value, Type: "string"}}, 596 )) 597 }) 598 599 It("default Pipeline bundle should be used and no additional Pipeline params should be added to the PipelineRun if one of the WhenConditions does not match", func() { 600 notMatchingComponentName := componentName + util.GenerateRandomString(4) 601 // using cdq since git ref is not known 602 cdq, err := f.AsKubeAdmin.HasController.CreateComponentDetectionQuery(notMatchingComponentName, testNamespace, helloWorldComponentGitSourceURL, "", "", "", false) 603 Expect(err).NotTo(HaveOccurred()) 604 Expect(len(cdq.Status.ComponentDetected)).To(Equal(1), "Expected length of the detected Components was not 1") 605 606 for _, compDetected := range cdq.Status.ComponentDetected { 607 c, err := f.AsKubeAdmin.HasController.CreateComponentFromStub(compDetected, testNamespace, "", "", applicationName) 608 Expect(err).NotTo(HaveOccurred()) 609 notMatchingComponentName = c.Name 610 } 611 612 Eventually(func() bool { 613 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(notMatchingComponentName, applicationName, testNamespace, "") 614 if err != nil { 615 GinkgoWriter.Println("PipelineRun has not been created yet") 616 return false 617 } 618 return pipelineRun.HasStarted() 619 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 620 621 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(notMatchingComponentName, applicationName, testNamespace, "") 622 Expect(err).ShouldNot(HaveOccurred()) 623 Expect(pipelineRun.Spec.PipelineRef.Bundle).ToNot(Equal(dummyPipelineBundleRef)) 624 Expect(pipelineRun.Spec.Params).ToNot(ContainElement(v1beta1.Param{ 625 Name: expectedAdditionalPipelineParam.Name, 626 Value: v1beta1.ParamValue{StringVal: expectedAdditionalPipelineParam.Value, Type: "string"}}, 627 )) 628 }) 629 }) 630 631 Describe("A secret with dummy quay.io credentials is created in the testing namespace", Ordered, func() { 632 633 var applicationName, componentName, testNamespace string 634 var timeout, interval time.Duration 635 var err error 636 var kc tekton.KubeController 637 var pipelineRun *v1beta1.PipelineRun 638 639 BeforeAll(func() { 640 641 f, err = framework.NewFramework(utils.GetGeneratedNamespace("build-e2e")) 642 Expect(err).NotTo(HaveOccurred()) 643 testNamespace = f.UserNamespace 644 645 kc = tekton.KubeController{ 646 Commonctrl: *f.AsKubeAdmin.CommonController, 647 Tektonctrl: *f.AsKubeAdmin.TektonController, 648 Namespace: testNamespace, 649 } 650 651 if err = f.AsKubeAdmin.CommonController.UnlinkSecretFromServiceAccount(testNamespace, constants.RegistryAuthSecretName, constants.DefaultPipelineServiceAccount, true); err != nil { 652 GinkgoWriter.Println(fmt.Sprintf("Failed to unlink registry auth secret from service account: %v\n", err)) 653 } 654 655 if err = f.AsKubeAdmin.CommonController.DeleteSecret(testNamespace, constants.RegistryAuthSecretName); err != nil { 656 GinkgoWriter.Println(fmt.Sprintf("Failed to delete regitry auth secret from namespace: %s\n", err)) 657 } 658 659 _, err := f.AsKubeAdmin.CommonController.GetSecret(testNamespace, constants.RegistryAuthSecretName) 660 if err != nil { 661 // If we have an error when getting RegistryAuthSecretName, it should be IsNotFound err 662 Expect(k8sErrors.IsNotFound(err)).To(BeTrue()) 663 } else { 664 Skip("a registry auth secret is already created in testing namespace - skipping....") 665 } 666 667 applicationName = fmt.Sprintf("test-app-%s", util.GenerateRandomString(4)) 668 669 app, err := f.AsKubeAdmin.HasController.CreateHasApplication(applicationName, testNamespace) 670 Expect(err).NotTo(HaveOccurred()) 671 Expect(utils.WaitUntil(f.AsKubeAdmin.HasController.ApplicationGitopsRepoExists(app.Status.Devfile), 30*time.Second)).To( 672 Succeed(), fmt.Sprintf("timed out waiting for gitops content to be created for app %s in namespace %s: %+v", app.Name, app.Namespace, err), 673 ) 674 timeout = time.Minute * 20 675 interval = time.Second * 1 676 677 dummySecret := &v1.Secret{ 678 ObjectMeta: metav1.ObjectMeta{Name: constants.RegistryAuthSecretName}, 679 Type: v1.SecretTypeDockerConfigJson, 680 Data: map[string][]byte{".dockerconfigjson": []byte("{\"auths\":{\"quay.io\":{\"username\":\"test\",\"password\":\"test\",\"auth\":\"dGVzdDp0ZXN0\",\"email\":\"\"}}}")}, 681 } 682 683 _, err = f.AsKubeAdmin.CommonController.CreateSecret(testNamespace, dummySecret) 684 Expect(err).ToNot(HaveOccurred()) 685 err = f.AsKubeAdmin.CommonController.LinkSecretToServiceAccount(testNamespace, dummySecret.Name, constants.DefaultPipelineServiceAccount, false) 686 Expect(err).ToNot(HaveOccurred()) 687 688 componentName = "build-suite-test-secret-overriding" 689 // using cdq since git ref is not known 690 cdq, err := f.AsKubeAdmin.HasController.CreateComponentDetectionQuery(componentName, testNamespace, helloWorldComponentGitSourceURL, "", "", "", false) 691 Expect(err).NotTo(HaveOccurred()) 692 Expect(len(cdq.Status.ComponentDetected)).To(Equal(1), "Expected length of the detected Components was not 1") 693 694 for _, compDetected := range cdq.Status.ComponentDetected { 695 c, err := f.AsKubeAdmin.HasController.CreateComponentFromStub(compDetected, testNamespace, "", "", applicationName) 696 Expect(err).NotTo(HaveOccurred()) 697 componentName = c.Name 698 } 699 }) 700 701 AfterAll(func() { 702 if !CurrentSpecReport().Failed() { 703 Expect(f.AsKubeAdmin.HasController.DeleteHasApplication(applicationName, testNamespace, false)).To(Succeed()) 704 Expect(f.AsKubeAdmin.HasController.DeleteHasComponent(componentName, testNamespace, false)).To(Succeed()) 705 Expect(f.AsKubeAdmin.TektonController.DeleteAllPipelineRunsInASpecificNamespace(testNamespace)).To(Succeed()) 706 Expect(f.SandboxController.DeleteUserSignup(f.UserName)).NotTo(BeFalse()) 707 } 708 }) 709 710 It("should override the shared secret", func() { 711 Eventually(func() bool { 712 pipelineRun, err := f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 713 if err != nil { 714 GinkgoWriter.Println("PipelineRun has not been created yet") 715 return false 716 } 717 return pipelineRun.HasStarted() 718 }, timeout, interval).Should(BeTrue(), "timed out when waiting for the PipelineRun to start") 719 720 pipelineRun, err = f.AsKubeAdmin.HasController.GetComponentPipelineRun(componentName, applicationName, testNamespace, "") 721 Expect(err).ShouldNot(HaveOccurred()) 722 Expect(pipelineRun.Spec.Workspaces).To(HaveLen(1)) 723 }) 724 725 It("should not be possible to push to quay.io repo (PipelineRun should fail)", func() { 726 pipelineRunTimeout := int(time.Duration(20) * time.Minute) 727 728 Expect(kc.WatchPipelineRun(pipelineRun.Name, pipelineRunTimeout)).To(Succeed()) 729 pipelineRun, err = kc.Tektonctrl.GetPipelineRun(pipelineRun.Name, pipelineRun.Namespace) 730 Expect(err).NotTo(HaveOccurred()) 731 tr, err := kc.GetTaskRunStatus(f.AsKubeAdmin.CommonController.KubeRest(), pipelineRun, constants.BuildTaskRunName) 732 Expect(err).NotTo(HaveOccurred()) 733 Expect(tekton.DidTaskSucceed(tr)).To(BeFalse()) 734 }) 735 }) 736 })