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  })