github.com/SAP/cloud-mta-build-tool@v1.2.27/integration/cloud_mta_build_tool_test.go (about) 1 // +build integration 2 3 package integration_test 4 5 import ( 6 "archive/zip" 7 "bufio" 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "log" 12 13 "os" 14 "os/exec" 15 "path/filepath" 16 "runtime" 17 "strings" 18 "time" 19 20 . "github.com/onsi/ginkgo" 21 . "github.com/onsi/ginkgo/extensions/table" 22 . "github.com/onsi/gomega" 23 "github.com/pkg/errors" 24 25 dir "github.com/SAP/cloud-mta-build-tool/internal/archive" 26 "github.com/SAP/cloud-mta/mta" 27 ) 28 29 const ( 30 demoArchiveName = "mta_demo_0.0.1.mtar" 31 //javaArchiveName = "com.fetcher.project_0.0.1.mtar" 32 binPath = "mbt" 33 ) 34 35 var mbtName = "" 36 var mbtTargetPath = "" 37 38 var _ = Describe("Integration - CloudMtaBuildTool", func() { 39 40 BeforeSuite(func() { 41 By("Building and smoke testing mbt") 42 mbtName = "mbt" 43 buildAndInstallMBT() 44 smokeTestMBT() 45 }) 46 47 AfterSuite(func() { 48 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/" + mbtName))).Should(Succeed()) 49 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/Makefile.mta"))).Should(Succeed()) 50 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/mtad.yaml"))).Should(Succeed()) 51 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/abc.mtar"))).Should(Succeed()) 52 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/mta_archives"))).Should(Succeed()) 53 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_java/myModule/target"))).Should(Succeed()) 54 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_java/Makefile.mta"))).Should(Succeed()) 55 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_java/mtad.yaml"))).Should(Succeed()) 56 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_java/mta_archives"))).Should(Succeed()) 57 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_demo/node/package-lock.json"))).Should(Succeed()) 58 }) 59 60 var _ = Describe("Command to provide the list of modules", func() { 61 62 It("Getting module", func() { 63 dir, _ := os.Getwd() 64 path := dir + filepath.FromSlash("/testdata/mta_demo") 65 bin := filepath.FromSlash(binPath) 66 cmdOut, cmdErr, err := execute(bin, "provide modules", path) 67 Ω(err).Should(Succeed(), cmdErr) 68 Ω(cmdOut).ShouldNot(BeNil()) 69 Ω(cmdOut).Should(ContainSubstring("[node node-js]" + "\n")) 70 }) 71 72 It("Command name error", func() { 73 dir, _ := os.Getwd() 74 path := dir + filepath.FromSlash("/testdata/") 75 bin := filepath.FromSlash(binPath) 76 _, _, err := execute(bin, "provide modules 2", path) 77 Ω(err).Should(HaveOccurred()) 78 }) 79 }) 80 var _ = Describe("Generate the Makefile according to the mta.yaml file", func() { 81 82 It("Generate Makefile for mta_demo", func() { 83 dir, _ := os.Getwd() 84 path := filepath.Join(dir, "testdata", "mta_demo") 85 bin := filepath.FromSlash(binPath) 86 _, errOut, err := execute(bin, "init", path) 87 Ω(err).Should(Succeed(), errOut) 88 89 // Check the MakeFile was generated 90 Ω(filepath.Join(dir, "testdata", "mta_demo", "Makefile.mta")).Should(BeAnExistingFile()) 91 }) 92 93 It("Generate Makefile for mta_java", func() { 94 dir, _ := os.Getwd() 95 path := filepath.Join(dir, "testdata", "mta_java") 96 bin := filepath.FromSlash(binPath) 97 _, errOut, err := execute(bin, "init", path) 98 Ω(err).Should(Succeed(), errOut) 99 100 // Check the MakeFile was generated 101 Ω(filepath.Join(dir, "testdata", "mta_java", "Makefile.mta")).Should(BeAnExistingFile()) 102 }) 103 104 It("Command name error", func() { 105 dir, _ := os.Getwd() 106 path := dir + filepath.FromSlash("/testdata/mta_demo") 107 bin := filepath.FromSlash(binPath) 108 _, _, err := execute(bin, "init 2", path) 109 Ω(err).Should(HaveOccurred()) 110 111 }) 112 }) 113 114 var _ = Describe("Generate MTAR", func() { 115 It("Generate MTAR with provided target and mtar name", func() { 116 dir, _ := os.Getwd() 117 Ω(os.RemoveAll(filepath.Join(dir, "testdata", "mta_demo", demoArchiveName))).Should(Succeed()) 118 path := dir + filepath.FromSlash("/testdata/mta_demo") 119 bin := filepath.FromSlash("make") 120 cmdOut, errOut, err := execute(bin, "-f Makefile.mta p=cf mtar=abc t="+path, path) 121 Ω(err).Should(Succeed(), errOut) 122 Ω(cmdOut).ShouldNot(BeEmpty()) 123 // Check the archive was generated 124 Ω(filepath.Join(dir, "testdata", "mta_demo", "abc.mtar")).Should(BeAnExistingFile()) 125 }) 126 127 It("Generate MTAR - wrong platform", func() { 128 129 dir, _ := os.Getwd() 130 path := dir + filepath.FromSlash("/testdata/mta_demo") 131 bin := filepath.FromSlash("make") 132 out, errOut, err := execute(bin, "-f Makefile.mta p=xxx mtar=xyz1", path) 133 Ω(err).Should(HaveOccurred()) 134 Ω(out + errOut).Should(ContainSubstring(`ERROR invalid target platform "xxx"; supported platforms are: "cf", "neo", "xsa"`)) 135 Ω(filepath.Join(dir, "testdata", "mta_demo", "mta_archives", "xyz1.mtar")).ShouldNot(BeAnExistingFile()) 136 }) 137 138 var _ = Describe("MBT build - generates Makefile and executes it", func() { 139 140 It("MBT build for mta_demo", func() { 141 dir, _ := os.Getwd() 142 path := filepath.Join(dir, "testdata", "mta_demo") 143 bin := filepath.FromSlash(binPath) 144 _, errOut, err := execute(bin, "build -p=cf", path) 145 Ω(err).Should(Succeed(), errOut) 146 147 // Check the MTAR was generated 148 validateMtaArchiveContents([]string{"node/", "node/data.zip", "node-js/", "node-js/data.zip"}, filepath.Join(path, "mta_archives", "mta_demo_0.0.1.mtar")) 149 }) 150 151 It("MBT build - wrong platform", func() { 152 dir, _ := os.Getwd() 153 path := filepath.Join(dir, "testdata", "mta_demo") 154 bin := filepath.FromSlash(binPath) 155 _, _, err := execute(bin, "build -p=xxx", path) 156 Ω(err).Should(HaveOccurred()) 157 }) 158 159 It("MBT build with timeout", func() { 160 dir, _ := os.Getwd() 161 path := filepath.Join(dir, "testdata", "moduletimeout") 162 bin := filepath.FromSlash(binPath) 163 164 start := time.Now() 165 out, errOut, err := execute(bin, "build", path) 166 elapsed := time.Since(start) 167 Ω(err).Should(HaveOccurred()) 168 Ω(out + errOut).Should(ContainSubstring("timed out")) 169 170 // Check elapsed time 171 Ω(elapsed).Should(BeNumerically(">=", time.Duration(5)*time.Second)) 172 Ω(elapsed).Should(BeNumerically("<=", time.Duration(10)*time.Second)) 173 }) 174 }) 175 176 It("Generate MTAR - unsupported platform, module removed from mtad", func() { 177 178 dir, _ := os.Getwd() 179 path := dir + filepath.FromSlash("/testdata/mta_demo") 180 bin := filepath.FromSlash("make") 181 _, errOut, err := execute(bin, "-f Makefile.mta p=neo mtar=xyz", path) 182 Ω(err).Should(Succeed(), errOut) 183 mtarFilename := filepath.Join(dir, "testdata", "mta_demo", "mta_archives", "xyz.mtar") 184 Ω(mtarFilename).Should(BeAnExistingFile()) 185 // check that module with unsupported platform 'neo' is not presented in mtad.yaml 186 mtadContent, e := getFileContentFromZip(mtarFilename, "mtad.yaml") 187 Ω(e).Should(Succeed()) 188 actual, e := mta.Unmarshal(mtadContent) 189 Ω(e).Should(Succeed()) 190 expected, e := mta.Unmarshal([]byte(` 191 _schema-version: "3.1" 192 ID: mta_demo 193 version: 0.0.1 194 modules: 195 - name: node-js 196 type: nodejs 197 path: node-js 198 provides: 199 - name: node-js_api 200 properties: 201 url: ${default-url} 202 parameters: 203 name: nodejs 204 parameters: 205 hcp-deployer-version: 1.1.0 206 `)) 207 Ω(e).Should(Succeed()) 208 Ω(actual).Should(Equal(expected)) 209 }) 210 211 It("Generate MTAR for mta_demo", func() { 212 213 dir, _ := os.Getwd() 214 path := dir + filepath.FromSlash("/testdata/mta_demo") 215 bin := filepath.FromSlash("make") 216 _, errOut, err := execute(bin, "-f Makefile.mta p=cf", path) 217 Ω(err).Should(Succeed(), errOut) 218 // Check the archive was generated 219 mtarFilename := filepath.Join(dir, "testdata", "mta_demo", "mta_archives", demoArchiveName) 220 Ω(filepath.Join(dir, "testdata", "mta_demo", "mta_archives", demoArchiveName)).Should(BeAnExistingFile()) 221 // check that module with unsupported platform 'cf' is presented in mtad.yaml 222 mtadContent, e := getFileContentFromZip(mtarFilename, "mtad.yaml") 223 Ω(e).Should(Succeed()) 224 actual, e := mta.Unmarshal(mtadContent) 225 Ω(e).Should(Succeed()) 226 expected, e := mta.Unmarshal([]byte(` 227 _schema-version: "3.1" 228 ID: mta_demo 229 version: 0.0.1 230 modules: 231 - name: node 232 type: javascript.nodejs 233 path: node 234 provides: 235 - name: node_api 236 properties: 237 url: ${default-url} 238 - name: node-js 239 type: javascript.nodejs 240 path: node-js 241 provides: 242 - name: node-js_api 243 properties: 244 url: ${default-url} 245 `)) 246 Ω(e).Should(Succeed()) 247 Ω(actual).Should(Equal(expected)) 248 validateMtaArchiveContents([]string{"node/", "node/data.zip", "node-js/", "node-js/data.zip"}, filepath.Join(path, "mta_archives", "mta_demo_0.0.1.mtar")) 249 }) 250 //It("Generate MTAR for mta_java", func() { 251 // 252 // dir, _ := os.Getwd() 253 // path := dir + filepath.FromSlash("/testdata/mta_java") 254 // bin := filepath.FromSlash("make") 255 // _, errOut, err, _ := execute(bin, "-f Makefile.mta p=cf", path) 256 // Ω(err).Should(Succeed(), errOut) 257 // // Check the archive was generated 258 // mtarFilename := filepath.Join(dir, "testdata", "mta_java", "mta_archives", javaArchiveName) 259 // Ω(filepath.Join(dir, "testdata", "mta_java", "mta_archives", javaArchiveName)).Should(BeAnExistingFile()) 260 // // check that module with unsupported platform 'cf' is presented in mtad.yaml 261 // mtadContent, e := getFileContentFromZip(mtarFilename, "mtad.yaml") 262 // Ω(e).Should(Succeed()) 263 // actual, e := mta.Unmarshal(mtadContent) 264 // Ω(e).Should(Succeed()) 265 // expected, e := mta.Unmarshal([]byte(` 266 // _schema-version: 2.0.0 267 // ID: com.fetcher.project 268 // version: 0.0.1 269 // modules: 270 // - name: myModule 271 // type: java.tomcat 272 // path: myModule 273 // requires: 274 // - name: otracker-uaa 275 // - name: otracker-managed-hdi 276 // parameters: 277 // buildpack: sap_java_buildpack 278 // stack: cflinuxfs3 279 // resources: 280 // - name: otracker-uaa 281 // type: com.sap.xs.uaa-space 282 // parameters: 283 // config-path: xs-security.json 284 // - name: otracker-managed-hdi 285 // type: com.sap.xs.managed-hdi-container 286 // `)) 287 // Ω(e).Should(Succeed()) 288 // Ω(actual).Should(Equal(expected)) 289 // validateMtaArchiveContents([]string{"myModule/", "myModule/java-xsahaa-1.1.2.war"}, filepath.Join(path, "mta_archives", "com.fetcher.project_0.0.1.mtar")) 290 //}) 291 292 When("Running MBT commands with MTA extension descriptors", func() { 293 var path string 294 var mtarFilename string 295 var makefileName string 296 BeforeEach(func() { 297 dir, err := os.Getwd() 298 Ω(err).Should(Succeed()) 299 path = filepath.Join(dir, "testdata", "mta_demo") 300 mtarFilename = filepath.Join(path, "mta_archives", demoArchiveName) 301 makefileName = filepath.Join(path, "Makefile.mta") 302 }) 303 AfterEach(func() { 304 Ω(os.RemoveAll(makefileName)).Should(Succeed()) 305 Ω(os.RemoveAll(mtarFilename)).Should(Succeed()) 306 }) 307 308 var validateMtar = func() { 309 // Check the MTAR was generated without the node-js module (since the extension file overrides its supported-platforms) 310 Ω(mtarFilename).Should(BeAnExistingFile()) 311 validateMtaArchiveContents([]string{"node/", "node/data.zip"}, mtarFilename) 312 313 // Check the mtad.yaml has the parts from the extension file 314 // check that module with unsupported platform 'neo' is not present in the mtad.yaml 315 mtadContent, e := getFileContentFromZip(mtarFilename, "mtad.yaml") 316 Ω(e).Should(Succeed()) 317 actual, e := mta.Unmarshal(mtadContent) 318 Ω(e).Should(Succeed()) 319 expected, e := mta.Unmarshal([]byte(` 320 _schema-version: "3.1" 321 ID: mta_demo 322 version: 0.0.1 323 modules: 324 - name: node 325 type: javascript.nodejs 326 path: node 327 provides: 328 - name: node_api 329 properties: 330 url: ${default-url} 331 `)) 332 Ω(e).Should(Succeed()) 333 Ω(actual).Should(Equal(expected)) 334 } 335 336 It("MBT build for mta_demo with extension", func() { 337 bin := filepath.FromSlash(binPath) 338 _, errOut, err := execute(bin, "build -e=ext.mtaext -p=cf", path) 339 Ω(err).Should(Succeed(), errOut) 340 validateMtar() 341 }) 342 343 It("MBT init and run make for mta_demo with extension - non-verbose", func() { 344 bin := filepath.FromSlash(binPath) 345 cmdOut, errOut, err := execute(bin, "init -e=ext.mtaext", path) 346 Ω(err).Should(Succeed(), errOut) 347 Ω(cmdOut).ShouldNot(BeNil()) 348 // Read the MakeFile was generated 349 Ω(makefileName).Should(BeAnExistingFile()) 350 // generate mtar 351 _, errOut, err = execute("make", "-f Makefile.mta p=cf", path) 352 Ω(err).Should(Succeed(), errOut) 353 validateMtar() 354 }) 355 356 It("MBT init and run make for mta_demo with extension - verbose", func() { 357 bin := filepath.FromSlash(binPath) 358 cmdOut, errOut, err := execute(bin, "init -m=verbose -e=ext.mtaext", path) 359 Ω(err).Should(Succeed(), errOut) 360 Ω(cmdOut).ShouldNot(BeNil()) 361 // Read the MakeFile was generated 362 Ω(makefileName).Should(BeAnExistingFile()) 363 // generate mtar 364 _, errOut, err = execute("make", "-f Makefile.mta p=cf", path) 365 Ω(err).Should(Succeed(), errOut) 366 validateMtar() 367 }) 368 }) 369 }) 370 371 var _ = Describe("Generate the Verbose Makefile and use it for mtar generation", func() { 372 373 It("Generate Verbose Makefile", func() { 374 dir, _ := os.Getwd() 375 Ω(os.RemoveAll(filepath.Join(dir, "testdata", "mta_demo", "Makefile.mta"))).Should(Succeed()) 376 Ω(os.RemoveAll(filepath.Join(dir, "testdata", "mta_demo", "mta_archives", demoArchiveName))).Should(Succeed()) 377 path := filepath.Join(dir, "testdata", "mta_demo") 378 bin := filepath.FromSlash(binPath) 379 cmdOut, errOut, err := execute(bin, "init -m=verbose", path) 380 Ω(err).Should(Succeed(), errOut) 381 Ω(cmdOut).ShouldNot(BeNil()) 382 // Read the MakeFile was generated 383 Ω(filepath.Join(dir, "testdata", "mta_demo", "Makefile.mta")).Should(BeAnExistingFile()) 384 // generate mtar 385 bin = filepath.FromSlash("make") 386 _, errOut, err = execute(bin, "-f Makefile.mta p=cf", path) 387 Ω(err).Should(Succeed(), errOut) 388 // Check the archive was generated 389 Ω(filepath.Join(dir, "testdata", "mta_demo", "mta_archives", demoArchiveName)).Should(BeAnExistingFile()) 390 }) 391 392 Describe("module with dependencies", func() { 393 dir, _ := os.Getwd() 394 path := filepath.Join(dir, "testdata", "moduledep") 395 archivePath := filepath.Join(path, "mta_archives", "f1_0.0.1.mtar") 396 tempZipPath := filepath.Join(path, "mta_archives", "data.zip") 397 398 AfterEach(func() { 399 Ω(os.RemoveAll(filepath.Join(path, "Makefile.mta"))).Should(Succeed()) 400 Ω(os.RemoveAll(filepath.Join(path, "mta_archives"))).Should(Succeed()) 401 Ω(os.RemoveAll(filepath.Join(path, "public", "client"))).Should(Succeed()) 402 Ω(os.RemoveAll(filepath.Join(path, "public", "client2"))).Should(Succeed()) 403 }) 404 405 It("Generate Verbose Makefile with module dependencies", func() { 406 bin := filepath.FromSlash(binPath) 407 cmdOut, errOut, err := execute(bin, "init -m=verbose", path) 408 Ω(err).Should(Succeed(), errOut) 409 Ω(cmdOut).ShouldNot(BeNil()) 410 // Check the MakeFile was generated 411 Ω(filepath.Join(path, "Makefile.mta")).Should(BeAnExistingFile()) 412 413 // Generate mtar 414 bin = filepath.FromSlash("make") 415 _, errOut, err = execute(bin, "-f Makefile.mta p=cf", path) 416 Ω(err).Should(Succeed(), errOut) 417 // Check the archive was generated 418 Ω(archivePath).Should(BeAnExistingFile()) 419 validateMtaArchiveContents([]string{"module_with_dep/", "module_with_dep/data.zip"}, archivePath) 420 421 // Extract data.zip and check its content 422 err = extractFileFromZip(archivePath, "module_with_dep/data.zip", tempZipPath) 423 Ω(err).Should(Succeed()) 424 validateArchiveContents([]string{"package.json", "client/", "client/client_package.json", "client2/", "client2/client_package.json"}, tempZipPath) 425 }) 426 }) 427 }) 428 429 Describe("module with dependencies", func() { 430 dir, _ := os.Getwd() 431 path := filepath.Join(dir, "testdata", "moduledep") 432 archivePath := filepath.Join(path, "mta_archives", "f1_0.0.1.mtar") 433 tempZipPath := filepath.Join(path, "mta_archives", "data.zip") 434 435 AfterEach(func() { 436 Ω(os.RemoveAll(filepath.Join(path, "mta_archives"))).Should(Succeed()) 437 Ω(os.RemoveAll(filepath.Join(path, "public", "client"))).Should(Succeed()) 438 Ω(os.RemoveAll(filepath.Join(path, "public", "client2"))).Should(Succeed()) 439 }) 440 441 DescribeTable("Build MTA with module dependencies", func(additionalBuildOpts []string) { 442 bin := filepath.FromSlash(binPath) 443 cmdOut, _, err := executeWithArgs(bin, path, append([]string{"build"}, additionalBuildOpts...)...) 444 Ω(err).Should(Succeed()) 445 Ω(cmdOut).ShouldNot(BeNil()) 446 447 // Check the archive was generated 448 Ω(archivePath).Should(BeAnExistingFile()) 449 validateMtaArchiveContents([]string{"module_with_dep/", "module_with_dep/data.zip"}, archivePath) 450 451 // Extract data.zip and check its content 452 err = extractFileFromZip(archivePath, "module_with_dep/data.zip", tempZipPath) 453 Ω(err).Should(Succeed()) 454 validateArchiveContents([]string{"package.json", "client/", "client/client_package.json", "client2/", "client2/client_package.json"}, tempZipPath) 455 }, 456 Entry("Non-verbose build", []string{}), 457 Entry("Parallel verbose build", []string{"--mode=verbose"}), 458 Entry("Serial verbose build", []string{"--mode=verbose", "--jobs=1"}), 459 ) 460 }) 461 462 var _ = Describe("MBT gen commands", func() { 463 It("Generate mtad", func() { 464 dir, _ := os.Getwd() 465 path := filepath.Join(dir, "testdata", "mta_demo") 466 Ω(os.MkdirAll(filepath.Join(path, ".mta_demo_mta_build_tmp", "node"), os.ModePerm)).Should(Succeed()) 467 Ω(os.MkdirAll(filepath.Join(path, ".mta_demo_mta_build_tmp", "node-js"), os.ModePerm)).Should(Succeed()) 468 bin := filepath.FromSlash(binPath) 469 _, errOut, err := execute(bin, "mtad-gen", path) 470 Ω(err).Should(Succeed(), errOut) 471 mtadPath := filepath.Join(path, "mtad.yaml") 472 Ω(mtadPath).Should(BeAnExistingFile()) 473 content, _ := ioutil.ReadFile(mtadPath) 474 mtadObj, _ := mta.Unmarshal(content) 475 Ω(len(mtadObj.Modules)).Should(Equal(2)) 476 Ω(mtadObj.Modules[0].Type).Should(Equal("javascript.nodejs")) 477 Ω(mtadObj.Modules[1].Type).Should(Equal("javascript.nodejs")) 478 }) 479 480 It("Generate mtad with mta extension", func() { 481 dir, _ := os.Getwd() 482 path := filepath.Join(dir, "testdata", "mta_demo") 483 Ω(os.MkdirAll(filepath.Join(path, ".mta_demo_mta_build_tmp", "node"), os.ModePerm)).Should(Succeed()) 484 Ω(os.MkdirAll(filepath.Join(path, ".mta_demo_mta_build_tmp", "node-js"), os.ModePerm)).Should(Succeed()) 485 bin := filepath.FromSlash(binPath) 486 _, errOut, err := execute(bin, `mtad-gen -e="ext.mtaext"`, path) 487 Ω(err).Should(Succeed(), errOut) 488 mtadPath := filepath.Join(path, "mtad.yaml") 489 Ω(mtadPath).Should(BeAnExistingFile()) 490 content, _ := ioutil.ReadFile(mtadPath) 491 mtadObj, _ := mta.Unmarshal(content) 492 Ω(len(mtadObj.Modules)).Should(Equal(1)) 493 Ω(mtadObj.Modules[0].Name).Should(Equal("node")) 494 Ω(mtadObj.Modules[0].Type).Should(Equal("javascript.nodejs")) 495 }) 496 }) 497 498 var _ = Describe("Deploy basic mta archive", func() { 499 AfterEach(func() { 500 resourceCleanup("node") 501 resourceCleanup("node-js") 502 }) 503 It("Deploy MTAR", func() { 504 dir, _ := os.Getwd() 505 path := dir + filepath.FromSlash("/testdata/mta_demo/mta_archives") 506 bin := filepath.FromSlash("cf") 507 // Execute deployment process with output to make the deployment success/failure more clear 508 err := executeWithOutput(bin, "deploy "+demoArchiveName+" -f", path) 509 Ω(err).Should(Succeed()) 510 // Check if the deploy succeeded by using curl command response. 511 // Receiving the output status code 200 represents successful deployment 512 args := "-s -o /dev/null -w '%{http_code}' " + os.Getenv("NODE_APP_ROUTE") 513 path = dir + filepath.FromSlash("/testdata/mta_demo") 514 bin = filepath.FromSlash("curl") 515 cmdOut, errOut, err := executeEverySecond(bin, args, path) 516 if len(errOut) > 0 { 517 log.Println(errOut) 518 } 519 Ω(err).Should(Succeed()) 520 Ω(cmdOut).Should(Equal("'200'")) 521 }) 522 }) 523 524 var _ = Describe("Generate merged mta.yaml", func() { 525 AfterEach(func() { 526 dir, _ := os.Getwd() 527 Ω(os.RemoveAll(filepath.Join(dir, "testdata", "mta_demo", "result.yaml"))).Should(Succeed()) 528 }) 529 It("merges with one extension", func() { 530 dir, _ := os.Getwd() 531 path := filepath.Join(dir, "testdata", "mta_demo") 532 bin := filepath.FromSlash(binPath) 533 _, errOut, err := execute(bin, `merge -e=ext.mtaext -n=result.yaml`, path) 534 Ω(err).Should(Succeed(), errOut) 535 mtadPath := filepath.Join(path, "result.yaml") 536 Ω(mtadPath).Should(BeAnExistingFile()) 537 content, _ := ioutil.ReadFile(mtadPath) 538 mtaObj, _ := mta.Unmarshal(content) 539 expected, e := mta.Unmarshal([]byte(` 540 ID: mta_demo 541 _schema-version: '2.1' 542 version: 0.0.1 543 544 modules: 545 - name: node 546 type: nodejs 547 path: node 548 provides: 549 - name: node_api 550 properties: 551 url: ${default-url} 552 build-parameters: 553 supported-platforms: [cf] 554 - name: node-js 555 type: nodejs 556 path: node-js 557 provides: 558 - name: node-js_api 559 properties: 560 url: ${default-url} 561 build-parameters: 562 builder: zip 563 supported-platforms: [neo] 564 `)) 565 Ω(e).Should(Succeed()) 566 Ω(mtaObj).Should(Equal(expected)) 567 }) 568 }) 569 570 var _ = Describe("Assemble MTAR", func() { 571 var currentWorkingDirectory string 572 var mtaAssemblePath string 573 var resultMtarPath string 574 575 BeforeEach(func() { 576 currentWorkingDirectory, _ = os.Getwd() 577 mtaAssemblePath = currentWorkingDirectory + filepath.FromSlash("/testdata/mta_assemble") 578 resultMtarPath = filepath.Join(mtaAssemblePath, "mta_archives", "mta.assembly.example_1.3.3.mtar") 579 }) 580 581 AfterEach(func() { 582 Ω(os.RemoveAll(filepath.Join(mtaAssemblePath, "mta.assembly.example.mtar"))).Should(Succeed()) 583 Ω(os.Chdir(currentWorkingDirectory)).Should(Succeed()) 584 Ω(os.RemoveAll(filepath.FromSlash("./testdata/mta_assemble/mta_archives"))).Should(Succeed()) 585 }) 586 587 It("Assemble MTAR", func() { 588 bin := filepath.FromSlash(binPath) 589 cmdOut, errOut, err := execute(bin, "assemble", mtaAssemblePath) 590 Ω(err).Should(Succeed(), errOut) 591 Ω(cmdOut).ShouldNot(BeNil()) 592 Ω(cmdOut).Should(ContainSubstring("assembling the MTA project..." + "\n")) 593 Ω(cmdOut).Should(ContainSubstring("copying the MTA content..." + "\n")) 594 Ω(cmdOut).Should(ContainSubstring("generating the metadata..." + "\n")) 595 Ω(cmdOut).Should(ContainSubstring("generating the MTA archive..." + "\n")) 596 Ω(cmdOut).Should(ContainSubstring("the MTA archive generated at: " + resultMtarPath + "\n")) 597 Ω(cmdOut).Should(ContainSubstring("cleaning temporary files..." + "\n")) 598 Ω(resultMtarPath).Should(BeAnExistingFile()) 599 validateMtaArchiveContents([]string{ 600 "node.zip", "xs-security.json", 601 "node/", "node/.eslintrc", "node/.eslintrc.ext", "node/.gitignore", "node/.npmrc", "node/jest.json", "node/package.json", "node/runTest.js", "node/server.js", 602 "node/.che/", "node/.che/project.json", 603 "node/tests/", "node/tests/sample-spec.js", 604 }, resultMtarPath) 605 }) 606 607 It("Assemble MTAR with MTA extension", func() { 608 bin := filepath.FromSlash(binPath) 609 cmdOut, errOut, err := execute(bin, fmt.Sprintf(`assemble -e="my.mtaext"`), mtaAssemblePath) 610 Ω(err).Should(Succeed(), errOut) 611 Ω(cmdOut).ShouldNot(Equal("")) 612 Ω(resultMtarPath).Should(BeAnExistingFile()) 613 // TODO the assemble command copies the contents of excluded modules to the archive (unrelated to the extension files) even though 614 // the modules are removed from the mtad.yaml and manifest.mf 615 validateMtaArchiveContents([]string{ 616 "node.zip", "xs-security.json", 617 "node/", "node/.eslintrc", "node/.eslintrc.ext", "node/.gitignore", "node/.npmrc", "node/jest.json", "node/package.json", "node/runTest.js", "node/server.js", 618 "node/.che/", "node/.che/project.json", 619 "node/tests/", "node/tests/sample-spec.js", 620 }, resultMtarPath) 621 mtadContent, e := getFileContentFromZip(resultMtarPath, "mtad.yaml") 622 Ω(e).Should(Succeed()) 623 actual, e := mta.Unmarshal(mtadContent) 624 Ω(e).Should(Succeed()) 625 expected, e := mta.Unmarshal([]byte(` 626 _schema-version: "3" 627 ID: mta.assembly.example 628 version: 1.3.3 629 modules: 630 - name: example2 631 type: javascript.nodejs 632 path: node.zip 633 provides: 634 - name: backend 635 properties: 636 url: "${default-url}" 637 requires: 638 - name: assembly-uaa 639 resources: 640 - name: mta-assembly-uaa 641 type: org.cloudfoundry.managed-service 642 parameters: 643 service: xsuaa 644 service-plan: space 645 path: xs-security.json 646 647 `)) 648 Ω(e).Should(Succeed()) 649 Ω(actual).Should(Equal(expected)) 650 }) 651 }) 652 }) 653 654 func buildAndInstallMBT() error { 655 if runtime.GOOS == "linux" || runtime.GOOS == "darwin" { 656 mbtName = mbtName 657 } else { 658 mbtName = mbtName + ".exe" 659 } 660 mbtTargetPath = filepath.Join(os.Getenv("GOPATH"), "/bin/"+mbtName) 661 662 cmd := exec.Command("go", "build", "-o", mbtTargetPath, ".") 663 cmd.Dir = filepath.FromSlash("../") 664 err := cmd.Run() 665 if err != nil { 666 fmt.Println("mbt build and install failed: ", err) 667 return err 668 } 669 670 return nil 671 } 672 673 func smokeTestMBT() error { 674 var stdout bytes.Buffer 675 cmd := exec.Command(mbtName, "-h") 676 cmd.Stdout = &stdout 677 err := cmd.Run() 678 if err != nil { 679 fmt.Println("exec mbt -h error: ", err) 680 return err 681 } 682 fmt.Println("exec mbt -h success: ", stdout.String()) 683 return nil 684 } 685 686 func getFileContentFromZip(path string, filename string) ([]byte, error) { 687 zipFile, err := zip.OpenReader(path) 688 if err != nil { 689 return nil, err 690 } 691 defer zipFile.Close() 692 for _, file := range zipFile.File { 693 if strings.Contains(file.Name, filename) { 694 fc, err := file.Open() 695 if err != nil { 696 return nil, err 697 } 698 defer fc.Close() // If we got here there won't be another loop iteration 699 return ioutil.ReadAll(fc) 700 } 701 } 702 return nil, fmt.Errorf(`file "%s" not found`, filename) 703 } 704 705 func extractFileFromZip(archivePath string, filename string, dst string) error { 706 zipFile, err := zip.OpenReader(archivePath) 707 if err != nil { 708 return err 709 } 710 defer func() { 711 _ = zipFile.Close() 712 }() 713 var fileToExtract *zip.File = nil 714 for _, file := range zipFile.File { 715 if strings.Contains(file.Name, filename) { 716 fileToExtract = file 717 } 718 } 719 if fileToExtract == nil { 720 return fmt.Errorf(`file "%s" not found`, filename) 721 } 722 723 in, err := fileToExtract.Open() 724 if err != nil { 725 return err 726 } 727 defer func() { 728 _ = in.Close() 729 }() 730 err = dir.WriteFile(in, dst) 731 return err 732 } 733 734 func validateMtaArchiveContents(expectedAdditionalFilesInArchive []string, archiveLocation string) { 735 expectedFilesInArchive := append(expectedAdditionalFilesInArchive, "META-INF/", "META-INF/MANIFEST.MF", "META-INF/mtad.yaml") 736 validateArchiveContents(expectedFilesInArchive, archiveLocation) 737 } 738 739 func validateArchiveContents(expectedFilesInArchive []string, archiveLocation string) { 740 archive, err := zip.OpenReader(archiveLocation) 741 Ω(err).Should(Succeed()) 742 defer func() { 743 _ = archive.Close() 744 }() 745 var filesInArchive []string 746 for _, file := range archive.File { 747 filesInArchive = append(filesInArchive, file.Name) 748 } 749 for _, expectedFile := range expectedFilesInArchive { 750 Ω(contains(expectedFile, filesInArchive)).Should(BeTrue(), fmt.Sprintf("expected %s to be in the archive; archive contains %v", expectedFile, filesInArchive)) 751 } 752 for _, existingFile := range filesInArchive { 753 Ω(contains(existingFile, expectedFilesInArchive)).Should(BeTrue(), fmt.Sprintf("did not expect %s to be in the archive; archive contains %v", existingFile, filesInArchive)) 754 } 755 } 756 757 func contains(element string, elements []string) bool { 758 for _, el := range elements { 759 if el == element { 760 return true 761 } 762 } 763 return false 764 } 765 766 // execute with live output 767 func executeWithOutput(bin string, args string, path string) error { 768 cmd := exec.Command(bin, strings.Split(args, " ")...) 769 cmd.Dir = path 770 cmdReader, err := cmd.StdoutPipe() 771 if err != nil { 772 return errors.Wrapf(err, "Error creating StdoutPipe for Cmd") 773 } 774 cmdErrReader, err := cmd.StderrPipe() 775 if err != nil { 776 return errors.Wrapf(err, "Error creating StderrPipe for Cmd") 777 } 778 779 scanner := bufio.NewScanner(cmdReader) 780 scannerErr := bufio.NewScanner(cmdErrReader) 781 782 go func() { 783 for scanner.Scan() { 784 fmt.Printf("process output | %s\n", scanner.Text()) 785 } 786 }() 787 go func() { 788 for scannerErr.Scan() { 789 fmt.Printf("process error output | %s\n", scannerErr.Text()) 790 } 791 }() 792 793 err = cmd.Start() 794 if err != nil { 795 return errors.Wrapf(err, "Error starting Cmd") 796 } 797 err = cmd.Wait() 798 if err != nil { 799 return errors.Wrapf(err, "Error waiting for Cmd") 800 } 801 return nil 802 } 803 804 // Delete deployed app 805 func resourceCleanup(appName string) { 806 wd, _ := os.Getwd() 807 path := wd + filepath.FromSlash("/testdata/mta_demo") 808 bin := filepath.FromSlash("cf") 809 cmdOut, cmdErr, err := execute(bin, "delete "+appName+" -r -f", path) 810 Ω(err).Should(Succeed(), cmdErr) 811 Ω(cmdOut).ShouldNot(BeEmpty()) 812 } 813 814 // Execute command every second for 40 times 815 func executeEverySecond(bin string, args string, path string) (string, errorOut string, err error) { 816 n := 0 817 cmdOut, errOut, err := execute(bin, args, path) 818 for range time.Tick(time.Second) { 819 if n == 40 || strings.Compare(cmdOut, "'200'") == 0 { 820 break 821 } 822 cmdOut, errOut, err = execute(bin, args, path) 823 n++ 824 } 825 return cmdOut, errOut, err 826 } 827 828 // Execute commands and get outputs 829 func execute(bin string, args string, path string) (output string, errorOutput string, err error) { 830 return executeWithArgs(bin, path, strings.Split(args, " ")...) 831 } 832 833 func executeWithArgs(bin string, path string, args ...string) (output string, errorOutput string, err error) { 834 // Provide list of commands 835 cmd := exec.Command(bin, args...) 836 // bin path 837 cmd.Dir = path 838 // std out 839 stdoutBuf := &bytes.Buffer{} 840 cmd.Stdout = stdoutBuf 841 // std error 842 stdErrBuf := &bytes.Buffer{} 843 cmd.Stderr = stdErrBuf 844 // Start command 845 if err = cmd.Start(); err != nil { 846 return "", "", err 847 } 848 // wait to the command to finish 849 err = cmd.Wait() 850 return stdoutBuf.String(), stdErrBuf.String(), err 851 }