github.com/jenkins-x/jx/v2@v2.1.155/pkg/tekton/metapipeline/metapipeline_test.go (about)

     1  // +build unit
     2  
     3  package metapipeline
     4  
     5  import (
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	jenkinsv1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1"
    10  	"github.com/jenkins-x/jx-api/pkg/client/clientset/versioned"
    11  	"github.com/jenkins-x/jx-logging/pkg/log"
    12  	"github.com/jenkins-x/jx/v2/pkg/apps"
    13  	"github.com/jenkins-x/jx/v2/pkg/gits"
    14  	"github.com/jenkins-x/jx/v2/pkg/tekton"
    15  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  
    20  	"github.com/jenkins-x/jx-api/pkg/client/clientset/versioned/fake"
    21  	corev1 "k8s.io/api/core/v1"
    22  )
    23  
    24  func TestMetaPipeline(t *testing.T) {
    25  	RegisterFailHandler(Fail)
    26  	RunSpecs(t, "Meta pipeline Suite")
    27  }
    28  
    29  var _ = Describe("Meta pipeline", func() {
    30  
    31  	Describe("#createMetaPipelineCRDs", func() {
    32  		var (
    33  			testParams   CRDCreationParameters
    34  			actualCRDs   *tekton.CRDWrapper
    35  			actualError  error
    36  			actualStdout string
    37  		)
    38  
    39  		BeforeEach(func() {
    40  			gitInfo, _ := gits.NewGitFake().Info("/acme")
    41  			pullRef := NewPullRefWithPullRequest("https://github.com/jenkins-x/jx", "master", "0967f9ecd7dd2d0acf883c7656c9dc2ad2bf9815", PullRequestRef{ID: "42", MergeSHA: "db8e2d275df53477b1c6871f7d7f4281dacf3169"})
    42  
    43  			testParams = CRDCreationParameters{
    44  				PipelineName:     "test-pipeline",
    45  				PipelineKind:     PullRequestPipeline,
    46  				BranchIdentifier: "master",
    47  				PullRef:          pullRef,
    48  				GitInfo:          *gitInfo,
    49  				Labels:           map[string]string{"someLabel": "someValue"},
    50  				EnvVars:          map[string]string{"SOME_VAR": "SOME_VAL", "OTHER_VAR": "OTHER_VAL"},
    51  				BuildNumber:      "1",
    52  				SourceDir:        "source",
    53  				ServiceAccount:   tekton.DefaultPipelineSA,
    54  				VersionsDir:      filepath.Join("test_data", "stable_versions"),
    55  			}
    56  		})
    57  
    58  		JustBeforeEach(func() {
    59  			actualCRDs, actualStdout, actualError = createMetaPipeline(testParams)
    60  		})
    61  
    62  		Context("with no extending Apps", func() {
    63  			It("should not error", func() {
    64  				Expect(actualError).Should(BeNil())
    65  			})
    66  
    67  			It("should not write to stdout", func() {
    68  				Expect(actualStdout).Should(BeEmpty())
    69  			})
    70  
    71  			It("contain a single task", func() {
    72  				tasks := actualCRDs.Tasks()
    73  				Expect(tasks).Should(HaveLen(1))
    74  			})
    75  
    76  			It("contain five task steps", func() {
    77  				steps := actualCRDs.Tasks()[0].Spec.Steps
    78  				Expect(steps).Should(HaveLen(5))
    79  				Expect(steps[0].Name).Should(Equal("setup-builder-home"))
    80  				Expect(steps[1].Name).Should(Equal("git-merge"))
    81  				Expect(steps[2].Name).Should(Equal(mergePullRefsStepName))
    82  				Expect(steps[3].Name).Should(Equal(createEffectivePipelineStepName))
    83  				Expect(steps[4].Name).Should(Equal(createTektonCRDsStepName))
    84  			})
    85  
    86  			It("merge pull refs step passes correct pull ref", func() {
    87  				steps := actualCRDs.Tasks()[0].Spec.Steps
    88  				mergePullRefStep := steps[2]
    89  				Expect(mergePullRefStep.Args).Should(Equal([]string{"jx step git merge --verbose --baseBranch master --baseSHA 0967f9ecd7dd2d0acf883c7656c9dc2ad2bf9815 --sha db8e2d275df53477b1c6871f7d7f4281dacf3169"}))
    90  			})
    91  
    92  			It("should pass custom env variables to step syntax effective to be applied to effective project config", func() {
    93  				step := actualCRDs.Tasks()[0].Spec.Steps[3]
    94  				Expect(step.Args[0]).Should(ContainSubstring("--env SOME_VAR=SOME_VAL"))
    95  				Expect(step.Args[0]).Should(ContainSubstring("--env OTHER_VAR=OTHER_VAL"))
    96  			})
    97  
    98  			It("should have correct step create task args", func() {
    99  				step := actualCRDs.Tasks()[0].Spec.Steps[4]
   100  				Expect(step.Args).Should(Equal([]string{"jx step create task --clone-dir /workspace/source --kind pullrequest --pr-number 42 --service-account tekton-bot --source source --branch master --build-number 1 --label someLabel=someValue"}))
   101  			})
   102  
   103  			It("should pass labels to step create task to be applied to generated CRDs", func() {
   104  				step := actualCRDs.Tasks()[0].Spec.Steps[4]
   105  				Expect(step.Args[0]).Should(ContainSubstring("--label someLabel=someValue"))
   106  			})
   107  		})
   108  
   109  		Context("with extending App missing required metadata", func() {
   110  			JustBeforeEach(func() {
   111  				testApp := jenkinsv1.App{
   112  					ObjectMeta: metav1.ObjectMeta{
   113  						Name:   "acme-app",
   114  						Labels: map[string]string{apps.AppTypeLabel: apps.PipelineExtension.String()},
   115  					},
   116  
   117  					Spec: jenkinsv1.AppSpec{},
   118  				}
   119  				testParams.Apps = []jenkinsv1.App{testApp}
   120  				actualCRDs, actualStdout, actualError = createMetaPipeline(testParams)
   121  			})
   122  
   123  			It("should not error", func() {
   124  				Expect(actualError).Should(BeNil())
   125  			})
   126  
   127  			It("should write warning to stdout", func() {
   128  				Expect(actualStdout).Should(ContainSubstring("WARNING: Skipping app acme-app in meta pipeline"))
   129  			})
   130  
   131  			It("contain a single task", func() {
   132  				tasks := actualCRDs.Tasks()
   133  				Expect(tasks).Should(HaveLen(1))
   134  			})
   135  
   136  			It("contain five task steps", func() {
   137  				steps := actualCRDs.Tasks()[0].Spec.Steps
   138  				Expect(steps).Should(HaveLen(5))
   139  				Expect(steps[0].Name).Should(Equal("setup-builder-home"))
   140  				Expect(steps[1].Name).Should(Equal("git-merge"))
   141  				Expect(steps[2].Name).Should(Equal(mergePullRefsStepName))
   142  				Expect(steps[3].Name).Should(Equal(createEffectivePipelineStepName))
   143  				Expect(steps[4].Name).Should(Equal(createTektonCRDsStepName))
   144  			})
   145  		})
   146  
   147  		Context("with extending App", func() {
   148  			JustBeforeEach(func() {
   149  				testApp := jenkinsv1.App{
   150  					ObjectMeta: metav1.ObjectMeta{
   151  						Name:   "acme-app",
   152  						Labels: map[string]string{apps.AppTypeLabel: apps.PipelineExtension.String()},
   153  					},
   154  
   155  					Spec: jenkinsv1.AppSpec{
   156  						PipelineExtension: &jenkinsv1.PipelineExtension{
   157  							Name:    "acme-ext",
   158  							Image:   "acme:1.0.0",
   159  							Command: "run",
   160  							Args:    []string{},
   161  						},
   162  					},
   163  				}
   164  				testParams.Apps = []jenkinsv1.App{testApp}
   165  				actualCRDs, actualStdout, actualError = createMetaPipeline(testParams)
   166  			})
   167  
   168  			It("should not error", func() {
   169  				Expect(actualError).Should(BeNil())
   170  			})
   171  
   172  			It("should not write to stdout", func() {
   173  				Expect(actualStdout).Should(BeEmpty())
   174  			})
   175  
   176  			It("contain a single task", func() {
   177  				tasks := actualCRDs.Tasks()
   178  				Expect(tasks).Should(HaveLen(1))
   179  			})
   180  
   181  			It("contain six task steps", func() {
   182  				steps := actualCRDs.Tasks()[0].Spec.Steps
   183  				Expect(steps).Should(HaveLen(6))
   184  				Expect(steps[0].Name).Should(Equal("setup-builder-home"))
   185  				Expect(steps[1].Name).Should(Equal("git-merge"))
   186  				Expect(steps[2].Name).Should(Equal(mergePullRefsStepName))
   187  				Expect(steps[3].Name).Should(Equal(createEffectivePipelineStepName))
   188  				Expect(steps[3].Image).Should(Equal("gcr.io/jenkinsxio/builder-maven:0.1.527"))
   189  				Expect(steps[4].Name).Should(Equal("acme-ext"))
   190  				Expect(steps[5].Name).Should(Equal(createTektonCRDsStepName))
   191  			})
   192  			It("uses version stream for default image", func() {
   193  				steps := actualCRDs.Tasks()[0].Spec.Steps
   194  				Expect(steps[3].Image).Should(Equal("gcr.io/jenkinsxio/builder-maven:0.1.527"))
   195  			})
   196  		})
   197  
   198  		Context("with no SHAs to merge (only baseBranch)", func() {
   199  			JustBeforeEach(func() {
   200  				pullRef := NewPullRef("https://github.com/jenkins-x/jx", "master", "0967f9ecd7dd2d0acf883c7656c9dc2ad2bf9815")
   201  				testParams.PullRef = pullRef
   202  				actualCRDs, actualStdout, actualError = createMetaPipeline(testParams)
   203  			})
   204  
   205  			It("merge pull refs step passes correct pull ref", func() {
   206  				steps := actualCRDs.Tasks()[0].Spec.Steps
   207  				mergePullRefStep := steps[2]
   208  				Expect(mergePullRefStep.Args[0]).Should(ContainSubstring("SKIP merge-pull-refs: Nothing to merge"))
   209  			})
   210  		})
   211  
   212  		Context("with no SHAs to merge (baseBranch & baseSHA)", func() {
   213  			JustBeforeEach(func() {
   214  				pullRef := NewPullRef("https://github.com/jenkins-x/jx", "master", "")
   215  
   216  				testParams.PullRef = pullRef
   217  				actualCRDs, actualStdout, actualError = createMetaPipeline(testParams)
   218  			})
   219  
   220  			It("merge pull refs step passes correct pull ref", func() {
   221  				steps := actualCRDs.Tasks()[0].Spec.Steps
   222  				mergePullRefStep := steps[2]
   223  				Expect(mergePullRefStep.Args[0]).Should(ContainSubstring("SKIP merge-pull-refs: Nothing to merge"))
   224  			})
   225  		})
   226  	})
   227  
   228  	Describe("#getExtendingApps", func() {
   229  		var (
   230  			jxClient versioned.Interface
   231  		)
   232  
   233  		BeforeEach(func() {
   234  			jxClient = fake.NewSimpleClientset()
   235  		})
   236  
   237  		Context("with no extending App", func() {
   238  			It("should return empty app list", func() {
   239  				apps, err := getExtendingApps(jxClient, "jx")
   240  				Expect(err).Should(BeNil())
   241  				Expect(apps).Should(HaveLen(0))
   242  			})
   243  		})
   244  
   245  		Context("with extending App", func() {
   246  			BeforeEach(func() {
   247  				testApp := jenkinsv1.App{
   248  					ObjectMeta: metav1.ObjectMeta{
   249  						Name:   "acme-app",
   250  						Labels: map[string]string{apps.AppTypeLabel: apps.PipelineExtension.String()},
   251  					},
   252  
   253  					Spec: jenkinsv1.AppSpec{
   254  						PipelineExtension: &jenkinsv1.PipelineExtension{
   255  							Name:    "acme-ext",
   256  							Image:   "acme:1.0.0",
   257  							Command: "run",
   258  							Args:    []string{},
   259  						},
   260  					},
   261  				}
   262  				_, err := jxClient.JenkinsV1().Apps("jx").Create(&testApp)
   263  				Expect(err).Should(BeNil())
   264  			})
   265  
   266  			It("should return the registered App", func() {
   267  				apps, err := getExtendingApps(jxClient, "jx")
   268  				Expect(err).Should(BeNil())
   269  				Expect(apps).Should(HaveLen(1))
   270  				Expect(apps[0].Name).Should(Equal("acme-app"))
   271  			})
   272  		})
   273  	})
   274  
   275  	Describe("#buildEnvParams", func() {
   276  		var (
   277  			testParams CRDCreationParameters
   278  		)
   279  
   280  		BeforeEach(func() {
   281  			gitInfo, _ := gits.ParseGitURL("https://github.com/jenkins-x/jx")
   282  			pullRef := NewPullRefWithPullRequest("https://github.com/jenkins-x/jx", "master", "0967f9ecd7dd2d0acf883c7656c9dc2ad2bf9815", PullRequestRef{ID: "42", MergeSHA: "db8e2d275df53477b1c6871f7d7f4281dacf3169"})
   283  			testParams = CRDCreationParameters{
   284  				PipelineName:     "test-pipeline",
   285  				PipelineKind:     PullRequestPipeline,
   286  				BranchIdentifier: "master",
   287  				PullRef:          pullRef,
   288  				GitInfo:          *gitInfo,
   289  				Labels:           map[string]string{"someLabel": "someValue"},
   290  				EnvVars:          map[string]string{"SOME_VAR": "OTHER_VALUE", "SOURCE_URL": "http://foo.git"},
   291  				BuildNumber:      "1",
   292  				SourceDir:        "source",
   293  				ServiceAccount:   tekton.DefaultPipelineSA,
   294  				VersionsDir:      filepath.Join("test_data", "stable_versions"),
   295  			}
   296  		})
   297  
   298  		It("env vars don't contain duplicates", func() {
   299  			vars := buildEnvParams(testParams)
   300  			var seen []string
   301  
   302  			for _, envVar := range vars {
   303  				Expect(seen).ShouldNot(ContainElement(envVar.Name))
   304  				seen = append(seen, envVar.Name)
   305  			}
   306  
   307  			Expect(len(seen)).Should(Equal(len(vars)))
   308  		})
   309  
   310  		It("explicitly set env variables win over custom env variables", func() {
   311  			vars := buildEnvParams(testParams)
   312  			expected := corev1.EnvVar{
   313  				Name:  "SOURCE_URL",
   314  				Value: "https://github.com/jenkins-x/jx",
   315  			}
   316  			Expect(vars).Should(ContainElement(expected))
   317  		})
   318  	})
   319  })
   320  
   321  func createMetaPipeline(params CRDCreationParameters) (*tekton.CRDWrapper, string, error) {
   322  	var crds *tekton.CRDWrapper
   323  	var err error
   324  	out := log.CaptureOutput(func() {
   325  		crds, err = createMetaPipelineCRDs(params)
   326  	})
   327  	return crds, out, err
   328  }