github.com/SAP/cloud-mta-build-tool@v1.2.27/internal/buildops/build_params_test.go (about) 1 package buildops 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 8 . "github.com/onsi/ginkgo" 9 . "github.com/onsi/ginkgo/extensions/table" 10 . "github.com/onsi/gomega" 11 12 "github.com/SAP/cloud-mta-build-tool/internal/archive" 13 "github.com/SAP/cloud-mta-build-tool/internal/commands" 14 "github.com/SAP/cloud-mta/mta" 15 ) 16 17 var _ = Describe("BuildParams", func() { 18 19 var _ = DescribeTable("valid cases", func(module *mta.Module, expected string) { 20 loc := &dir.Loc{SourcePath: getTestPath("mtahtml5")} 21 path, err := GetModuleSourceArtifactPath(loc, false, module, "", true) 22 Ω(err).Should(Succeed()) 23 Ω(path).Should(Equal(expected)) 24 }, 25 Entry("Implicit Build Results Path", &mta.Module{Path: "testapp"}, getTestPath("mtahtml5", "testapp")), 26 Entry("Explicit Build Results Path", 27 &mta.Module{ 28 Path: "testapp", 29 BuildParams: map[string]interface{}{buildResultParam: filepath.Join("webapp", "controller")}, 30 }, getTestPath("mtahtml5", "testapp", "webapp", "controller"))) 31 32 var _ = Describe("GetBuildResultsPath", func() { 33 It("empty path, no build results", func() { 34 module := &mta.Module{} 35 buildResult, _ := GetModuleSourceArtifactPath( 36 &dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "", true) 37 Ω(buildResult).Should(Equal("")) 38 }) 39 40 It("build results - pattern", func() { 41 module := &mta.Module{ 42 Path: "inui2", 43 BuildParams: map[string]interface{}{buildResultParam: "*.txt"}, 44 } 45 buildResult, _ := GetModuleSourceArtifactPath( 46 &dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "", true) 47 Ω(buildResult).Should(HaveSuffix("anotherfile.txt")) 48 }) 49 50 It("default build results", func() { 51 module := &mta.Module{ 52 Path: "inui2", 53 } 54 buildResult, _ := GetModuleSourceArtifactPath( 55 &dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "*.txt", true) 56 Ω(buildResult).Should(HaveSuffix("anotherfile.txt")) 57 }) 58 It("default build results - no file answers pattern", func() { 59 module := &mta.Module{ 60 Path: "inui2", 61 } 62 _, err := GetModuleSourceArtifactPath( 63 &dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, false, module, "b*.txt", true) 64 Ω(err).Should(HaveOccurred()) 65 }) 66 }) 67 68 var _ = DescribeTable("getRequiredTargetPath", func(requires BuildRequires, module mta.Module, expected string) { 69 Ω(getRequiredTargetPath(&dir.Loc{}, &module, &requires)).Should(HaveSuffix(expected)) 70 }, 71 Entry("Implicit Target Path", BuildRequires{}, mta.Module{Path: "mPath"}, "mPath"), 72 Entry("Explicit Target Path", BuildRequires{TargetPath: "artifacts"}, mta.Module{Path: "mPath"}, filepath.Join("mPath", "artifacts"))) 73 74 var _ = Describe("ProcessRequirements", func() { 75 wd, _ := os.Getwd() 76 ep := dir.Loc{SourcePath: filepath.Join(wd, "testdata", "testproject"), TargetPath: filepath.Join(wd, "testdata", "result")} 77 require := BuildRequires{ 78 Name: "A", 79 TargetPath: "./b_copied_artifacts", 80 } 81 require1 := BuildRequires{ 82 Name: "C", 83 TargetPath: "./b_copied_artifacts", 84 } 85 reqs := []BuildRequires{require} 86 reqs1 := []BuildRequires{require1} 87 mtaObj := mta.MTA{ 88 Modules: []*mta.Module{ 89 { 90 Name: "A", 91 Path: "ui5app", 92 }, 93 { 94 Name: "B", 95 Path: "moduleB", 96 BuildParams: map[string]interface{}{ 97 requiresParam: reqs, 98 }, 99 }, 100 { 101 Name: "C", 102 Path: "ui5app", 103 BuildParams: map[string]interface{}{ 104 buildResultParam: "xxx.xxx", 105 }, 106 }, 107 { 108 Name: "D", 109 Path: "ui5app", 110 BuildParams: map[string]interface{}{ 111 requiresParam: reqs1, 112 }, 113 }, 114 }, 115 } 116 117 It("wrong builders configuration", func() { 118 conf := commands.BuilderTypeConfig 119 commands.BuilderTypeConfig = []byte("bad bad bad") 120 Ω(ProcessRequirements(&ep, &mtaObj, &require, "B")).Should(HaveOccurred()) 121 commands.BuilderTypeConfig = conf 122 }) 123 124 It("default build results - no file answers pattern", func() { 125 err := ProcessRequirements(&dir.Loc{SourcePath: getTestPath("testbuildparams", "ui2", "deep", "folder")}, 126 &mtaObj, &require1, "D") 127 Ω(err).Should(HaveOccurred()) 128 }) 129 130 AfterEach(func() { 131 os.RemoveAll(filepath.Join(wd, "testdata", "testproject", "moduleB")) 132 }) 133 134 var _ = DescribeTable("Valid cases", func(artifacts []string, expectedPath string) { 135 require.Artifacts = artifacts 136 Ω(ProcessRequirements(&ep, &mtaObj, &require, "B")).Should(Succeed()) 137 Ω(filepath.Join(wd, expectedPath)).Should(BeADirectory()) 138 Ω(filepath.Join(wd, expectedPath, "webapp", "Component.js")).Should(BeAnExistingFile()) 139 }, 140 Entry("Require All - list", []string{"*"}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts")), 141 Entry("Require All - single value", []string{"*"}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts")), 142 Entry("Require All From Parent", []string{"."}, filepath.Join("testdata", "testproject", "moduleB", "b_copied_artifacts", "ui5app"))) 143 144 var _ = DescribeTable("Invalid cases", func(lp *dir.Loc, require BuildRequires, mtaObj mta.MTA, moduleName, buildResult string) { 145 Ω(ProcessRequirements(lp, &mtaObj, &require, moduleName)).Should(HaveOccurred()) 146 }, 147 Entry("Module not defined", 148 &dir.Loc{}, 149 BuildRequires{Name: "A", Artifacts: []string{"*"}, TargetPath: "b_copied_artifacts"}, 150 mta.MTA{Modules: []*mta.Module{{Name: "A", Path: "ui5app"}, {Name: "B", Path: "moduleB"}}}, 151 "C", ""), 152 Entry("Required Module not defined", 153 &dir.Loc{}, 154 BuildRequires{Name: "C", Artifacts: []string{"*"}, TargetPath: "b_copied_artifacts"}, 155 mta.MTA{Modules: []*mta.Module{{Name: "A", Path: "ui5app"}, {Name: "B", Path: "moduleB"}}}, 156 "B", ""), 157 Entry("Target path - file", 158 &dir.Loc{SourcePath: getTestPath("testbuildparams")}, 159 BuildRequires{Name: "ui1", Artifacts: []string{"*"}, TargetPath: "file.txt"}, 160 mta.MTA{Modules: []*mta.Module{{Name: "ui1", Path: "ui1"}, {Name: "node", Path: "node"}}}, 161 "node", "")) 162 163 }) 164 }) 165 166 var _ = Describe("GetModuleTargetArtifactPath", func() { 167 It("path is empty", func() { 168 loc := dir.Loc{} 169 path, _, err := GetModuleTargetArtifactPath(&loc, false, &mta.Module{}, "", true) 170 Ω(err).Should(Succeed()) 171 Ω(path).Should(BeEmpty()) 172 }) 173 It("fails when path doesn't exist", func() { 174 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 175 _, _, err := GetModuleTargetArtifactPath(&loc, false, &mta.Module{Path: "abc"}, "", true) 176 Ω(err).Should(HaveOccurred()) 177 }) 178 It("deployment descriptor", func() { 179 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 180 path, _, err := GetModuleTargetArtifactPath(&loc, true, &mta.Module{Path: "abc"}, "", true) 181 Ω(err).Should(Succeed()) 182 Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "abc"))) 183 }) 184 It("fails on wrong definition of build result", func() { 185 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 186 module := &mta.Module{ 187 Name: "web", 188 Path: "webapp", 189 BuildParams: map[string]interface{}{ 190 buildResultParam: 1, 191 }, 192 } 193 _, _, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 194 Ω(err).Should(HaveOccurred()) 195 Ω(err.Error()).Should(ContainSubstring(fmt.Sprintf(WrongBuildResultMsg, 1, "web"))) 196 }) 197 It("fails on wrong definition of build artifact name", func() { 198 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 199 module := &mta.Module{ 200 Name: "web", 201 Path: filepath.Join("testapp", "webapp"), 202 BuildParams: map[string]interface{}{ 203 buildArtifactNameParam: 1, 204 }, 205 } 206 _, _, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 207 Ω(err).Should(HaveOccurred()) 208 Ω(err.Error()).Should(ContainSubstring(fmt.Sprintf(WrongBuildArtifactNameMsg, 1, "web"))) 209 }) 210 It("artifact is a folder", func() { 211 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 212 module := &mta.Module{ 213 Name: "web", 214 Path: filepath.Join("testapp", "webapp"), 215 BuildParams: map[string]interface{}{ 216 buildArtifactNameParam: "test", 217 }, 218 } 219 path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 220 Ω(err).Should(Succeed()) 221 Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.zip"))) 222 Ω(toArchive).Should(BeTrue()) 223 }) 224 It("artifact is a file", func() { 225 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 226 module := &mta.Module{ 227 Name: "web", 228 Path: filepath.Join("testapp", "webapp", "Component.js"), 229 BuildParams: map[string]interface{}{ 230 buildArtifactNameParam: "test", 231 }, 232 } 233 path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 234 Ω(err).Should(Succeed()) 235 Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.zip"))) 236 Ω(toArchive).Should(BeTrue()) 237 }) 238 It("artifact is a file defined by build result", func() { 239 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 240 module := &mta.Module{ 241 Name: "web", 242 Path: "testapp", 243 BuildParams: map[string]interface{}{ 244 buildResultParam: filepath.Join("webapp", "controller", "View1.controller.js"), 245 buildArtifactNameParam: "ctrl", 246 }, 247 } 248 path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 249 Ω(err).Should(Succeed()) 250 Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "webapp", "controller", "ctrl.zip"))) 251 Ω(toArchive).Should(BeTrue()) 252 }) 253 It("artifact is an archive", func() { 254 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 255 module := &mta.Module{ 256 Name: "web", 257 Path: filepath.Join("testapp", "webapp", "Component.jar"), 258 BuildParams: map[string]interface{}{ 259 buildArtifactNameParam: "test", 260 }, 261 } 262 path, toArchive, err := GetModuleTargetArtifactPath(&loc, false, module, "", true) 263 Ω(err).Should(Succeed()) 264 Ω(path).Should(Equal(getTestPath("result", ".mtahtml5_mta_build_tmp", "web", "test.jar"))) 265 Ω(toArchive).Should(BeFalse()) 266 }) 267 It("no build result resolving, path provided as pattern", func() { 268 loc := dir.Loc{SourcePath: getTestPath("mtahtml5"), TargetPath: getTestPath("result")} 269 moduleLoc := dir.ModuleLocation(&loc, false) 270 module := &mta.Module{ 271 Name: "web", 272 Path: filepath.Join("testapp", "webapp", "*.jar"), 273 } 274 path, toArchive, err := GetModuleTargetArtifactPath(moduleLoc, false, module, "", false) 275 Ω(err).Should(Succeed()) 276 Ω(path).Should(Equal(getTestPath("result", "*.jar"))) 277 Ω(toArchive).Should(BeFalse()) 278 }) 279 }) 280 281 var _ = Describe("Process complex list of requirements", func() { 282 AfterEach(func() { 283 os.RemoveAll(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder")) 284 os.RemoveAll(getTestPath("testbuildparams", "node", "newfolder")) 285 }) 286 287 It("", func() { 288 lp := dir.Loc{ 289 SourcePath: getTestPath("testbuildparams"), 290 TargetPath: getTestPath("result"), 291 } 292 mtaObj, _ := lp.ParseFile() 293 for _, m := range mtaObj.Modules { 294 if m.Name == "node" { 295 for _, r := range GetBuildRequires(m) { 296 Ω(ProcessRequirements(&lp, mtaObj, &r, "node")).Should(Succeed()) 297 } 298 } 299 } 300 // ["*"] => "newfolder" 301 Ω(getTestPath("testbuildparams", "node", "newfolder", "webapp")).Should(BeADirectory()) 302 // ["deep/folder/inui2/anotherfile.txt"] => "existingfolder/deepfolder" 303 Ω(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder", "anotherfile.txt")).Should(BeAnExistingFile()) 304 // ["./deep/*/inui2/another*"] => "./existingfolder/deepfolder" 305 Ω(getTestPath("testbuildparams", "node", "existingfolder", "deepfolder", "anotherfile2.txt")).Should(BeAnExistingFile()) 306 // ["deep/folder/inui2/somefile.txt", "*/folder/"] => "newfolder/newdeepfolder" 307 Ω(getTestPath("testbuildparams", "node", "newfolder", "newdeepfolder", "folder")).Should(BeADirectory()) 308 }) 309 310 }) 311 312 var _ = Describe("PlatformDefined", func() { 313 It("No platforms", func() { 314 m := mta.Module{ 315 Name: "x", 316 BuildParams: map[string]interface{}{ 317 SupportedPlatformsParam: []string{}, 318 }, 319 } 320 Ω(PlatformDefined(&m, "cf")).Should(Equal(false)) 321 }) 322 It("All platforms", func() { 323 m := mta.Module{ 324 Name: "x", 325 BuildParams: map[string]interface{}{}, 326 } 327 Ω(PlatformDefined(&m, "cf")).Should(Equal(true)) 328 }) 329 It("Matching platform", func() { 330 m := mta.Module{ 331 Name: "x", 332 BuildParams: map[string]interface{}{ 333 SupportedPlatformsParam: []string{"CF"}, 334 }, 335 } 336 Ω(PlatformDefined(&m, "cf")).Should(Equal(true)) 337 }) 338 It("Not Matching platform", func() { 339 m := mta.Module{ 340 Name: "x", 341 BuildParams: map[string]interface{}{ 342 SupportedPlatformsParam: []string{"neo"}, 343 }, 344 } 345 Ω(PlatformDefined(&m, "cf")).Should(Equal(false)) 346 }) 347 It("Matching platform - interface", func() { 348 m := mta.Module{ 349 Name: "x", 350 BuildParams: map[string]interface{}{ 351 SupportedPlatformsParam: []interface{}{"cf"}, 352 }, 353 } 354 Ω(PlatformDefined(&m, "cf")).Should(Equal(true)) 355 }) 356 It("Not Matching platform - interface", func() { 357 m := mta.Module{ 358 Name: "x", 359 BuildParams: map[string]interface{}{ 360 SupportedPlatformsParam: []interface{}{"neo"}, 361 }, 362 } 363 Ω(PlatformDefined(&m, "cf")).Should(Equal(false)) 364 }) 365 }) 366 367 var _ = Describe("GetBuilder", func() { 368 It("Builder defined by type", func() { 369 m := mta.Module{ 370 Name: "x", 371 Type: "node-js", 372 BuildParams: map[string]interface{}{ 373 SupportedPlatformsParam: []string{}, 374 }, 375 } 376 builder, custom, _, cmds, err := commands.GetBuilder(&m) 377 Ω(builder).Should(Equal("node-js")) 378 Ω(custom).Should(BeFalse()) 379 Ω(cmds).Should(BeNil()) 380 Ω(err).Should(Succeed()) 381 }) 382 It("Builder defined by build params", func() { 383 m := mta.Module{ 384 Name: "x", 385 Type: "node-js", 386 BuildParams: map[string]interface{}{ 387 builderParam: "npm", 388 "npm-opts": map[string]interface{}{ 389 "no-optional": nil, 390 }, 391 }, 392 } 393 builder, custom, _, cmds, err := commands.GetBuilder(&m) 394 Ω(builder).Should(Equal("npm")) 395 Ω(custom).Should(Equal(true)) 396 Ω(len(cmds)).Should(Equal(0)) 397 Ω(err).Should(Succeed()) 398 }) 399 It("Builder defined by build params", func() { 400 m := mta.Module{ 401 Name: "x", 402 Type: "node-js", 403 BuildParams: map[string]interface{}{ 404 builderParam: "custom", 405 "commands": []string{"command1"}, 406 }, 407 } 408 builder, custom, _, cmds, err := commands.GetBuilder(&m) 409 Ω(builder).Should(Equal("custom")) 410 Ω(custom).Should(Equal(true)) 411 Ω(cmds[0]).Should(Equal("command1")) 412 Ω(err).Should(Succeed()) 413 }) 414 It("fetcher builder defined by build params", func() { 415 m := mta.Module{ 416 Name: "x", 417 Type: "node-js", 418 BuildParams: map[string]interface{}{ 419 builderParam: "fetcher", 420 "fetcher-opts": map[interface{}]interface{}{ 421 "repo-type": "maven", 422 "repo-coordinates": "com.sap.xs.java:xs-audit-log-api:1.2.3", 423 }, 424 }, 425 } 426 builder, custom, options, cmds, err := commands.GetBuilder(&m) 427 Ω(options).Should(Equal(map[string]string{ 428 "repo-type": "maven", 429 "repo-coordinates": "com.sap.xs.java:xs-audit-log-api:1.2.3"})) 430 Ω(builder).Should(Equal("fetcher")) 431 Ω(custom).Should(BeTrue()) 432 Ω(cmds).Should(BeNil()) 433 Ω(err).Should(Succeed()) 434 }) 435 It("fetcher builder defined by build params from mta.yaml", func() { 436 currDir, err := os.Getwd() 437 Ω(err).Should(Succeed()) 438 loc, err := dir.Location(filepath.Join(currDir, "testdata"), "", "dev", nil, os.Getwd) 439 Ω(err).Should(Succeed()) 440 loc.MtaFilename = "mtaWithFetcher.yaml" 441 m, err := loc.ParseFile() 442 Ω(err).Should(Succeed()) 443 444 builder, custom, options, cmds, err := commands.GetBuilder(m.Modules[0]) 445 Ω(options).Should(Equal(map[string]string{ 446 "repo-type": "maven", 447 "repo-coordinates": "mygroup:myart:1.0.0"})) 448 Ω(builder).Should(Equal("fetcher")) 449 Ω(custom).Should(BeTrue()) 450 Ω(cmds).Should(BeNil()) 451 Ω(err).Should(Succeed()) 452 }) 453 }) 454 455 var _ = Describe("IfNoSource", func() { 456 It("no source module", func() { 457 buildParams := make(map[string]interface{}) 458 buildParams[noSourceParam] = true 459 module := mta.Module{BuildParams: buildParams} 460 Ω(IfNoSource(&module)).Should(BeTrue()) 461 }) 462 It("no source module", func() { 463 buildParams := make(map[string]interface{}) 464 buildParams[noSourceParam] = false 465 module := mta.Module{BuildParams: buildParams} 466 Ω(IfNoSource(&module)).Should(BeFalse()) 467 }) 468 It("not no source module", func() { 469 buildParams := make(map[string]interface{}) 470 module := mta.Module{BuildParams: buildParams} 471 Ω(IfNoSource(&module)).Should(BeFalse()) 472 }) 473 }) 474 475 func getTestPath(relPath ...string) string { 476 wd, _ := os.Getwd() 477 return filepath.Join(wd, "testdata", filepath.Join(relPath...)) 478 }