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 }