github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v6/experimental/v3_push_command_test.go (about) 1 package experimental 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "regexp" 9 10 "code.cloudfoundry.org/cli/integration/helpers" 11 . "github.com/onsi/ginkgo" 12 . "github.com/onsi/gomega" 13 . "github.com/onsi/gomega/gbytes" 14 . "github.com/onsi/gomega/gexec" 15 ) 16 17 var _ = Describe("v3-push command", func() { 18 var ( 19 orgName string 20 spaceName string 21 appName string 22 userName string 23 PublicDockerImage = "cloudfoundry/diego-docker-app-custom" 24 ) 25 26 BeforeEach(func() { 27 orgName = helpers.NewOrgName() 28 spaceName = helpers.NewSpaceName() 29 appName = helpers.PrefixedRandomName("app") 30 userName, _ = helpers.GetCredentials() 31 helpers.TurnOffExperimental() 32 }) 33 34 AfterEach(func() { 35 helpers.TurnOnExperimental() 36 }) 37 38 Describe("help", func() { 39 When("--help flag is set", func() { 40 It("Displays command usage to output", func() { 41 session := helpers.CF("v3-push", "--help") 42 Eventually(session).Should(Say("NAME:")) 43 Eventually(session).Should(Say("v3-push - Push a new app or sync changes to an existing app")) 44 Eventually(session).Should(Say("USAGE:")) 45 Eventually(session).Should(Say("cf v3-push APP_NAME \\[-b BUILDPACK\\]\\.\\.\\. \\[-p APP_PATH\\] \\[--no-route\\]")) 46 Eventually(session).Should(Say("cf v3-push APP_NAME --docker-image \\[REGISTRY_HOST:PORT/\\]IMAGE\\[:TAG\\] \\[--docker-username USERNAME\\] \\[--no-route\\]")) 47 Eventually(session).Should(Say("OPTIONS:")) 48 Eventually(session).Should(Say("-b\\s+Custom buildpack by name \\(e\\.g\\. my-buildpack\\) or Git URL \\(e\\.g\\. 'https://github.com/cloudfoundry/java-buildpack.git'\\) or Git URL with a branch or tag \\(e\\.g\\. 'https://github.com/cloudfoundry/java-buildpack\\.git#v3.3.0' for 'v3.3.0' tag\\)\\. To use built-in buildpacks only, specify 'default' or 'null'")) 49 Eventually(session).Should(Say("--docker-image, -o\\s+Docker image to use \\(e\\.g\\. user/docker-image-name\\)")) 50 Eventually(session).Should(Say("--docker-username\\s+Repository username; used with password from environment variable CF_DOCKER_PASSWORD")) 51 Eventually(session).Should(Say("--no-route\\s+Do not map a route to this app")) 52 Eventually(session).Should(Say("-p\\s+Path to app directory or to a zip file of the contents of the app directory")) 53 Eventually(session).Should(Say("ENVIRONMENT:")) 54 Eventually(session).Should(Say("CF_DOCKER_PASSWORD=\\s+Password used for private docker repository")) 55 Eventually(session).Should(Say("CF_STAGING_TIMEOUT=15\\s+Max wait time for buildpack staging, in minutes")) 56 Eventually(session).Should(Say("CF_STARTUP_TIMEOUT=5\\s+Max wait time for app instance startup, in minutes")) 57 58 Eventually(session).Should(Exit(0)) 59 }) 60 }) 61 }) 62 63 When("the app name is not provided", func() { 64 It("tells the user that the app name is required, prints help text, and exits 1", func() { 65 session := helpers.CF("v3-push") 66 67 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided")) 68 Eventually(session).Should(Say("NAME:")) 69 Eventually(session).Should(Exit(1)) 70 }) 71 }) 72 73 It("displays the experimental warning", func() { 74 session := helpers.CF("v3-push", appName) 75 Eventually(session.Err).Should(Say("This command is in EXPERIMENTAL stage and may change without notice")) 76 Eventually(session).Should(Exit()) 77 }) 78 79 When("the -b flag is not given an arg", func() { 80 It("tells the user that the flag requires an arg, prints help text, and exits 1", func() { 81 session := helpers.CF("v3-push", appName, "-b") 82 83 Eventually(session.Err).Should(Say("Incorrect Usage: expected argument for flag `-b'")) 84 Eventually(session).Should(Say("NAME:")) 85 Eventually(session).Should(Exit(1)) 86 }) 87 }) 88 89 When("the -p flag is not given an arg", func() { 90 It("tells the user that the flag requires an arg, prints help text, and exits 1", func() { 91 session := helpers.CF("v3-push", appName, "-p") 92 93 Eventually(session.Err).Should(Say("Incorrect Usage: expected argument for flag `-p'")) 94 Eventually(session).Should(Say("NAME:")) 95 Eventually(session).Should(Exit(1)) 96 }) 97 }) 98 99 When("the -p flag path does not exist", func() { 100 It("tells the user that the flag requires an arg, prints help text, and exits 1", func() { 101 session := helpers.CF("v3-push", appName, "-p", "path/that/does/not/exist") 102 103 Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'path/that/does/not/exist' does not exist.")) 104 Eventually(session).Should(Say("NAME:")) 105 Eventually(session).Should(Exit(1)) 106 }) 107 }) 108 109 When("the environment is not setup correctly", func() { 110 When("no API endpoint is set", func() { 111 BeforeEach(func() { 112 helpers.UnsetAPI() 113 }) 114 115 It("fails with no API endpoint set message", func() { 116 session := helpers.CF("v3-push", appName) 117 Eventually(session).Should(Say("FAILED")) 118 Eventually(session.Err).Should(Say("No API endpoint set\\. Use 'cf login' or 'cf api' to target an endpoint\\.")) 119 Eventually(session).Should(Exit(1)) 120 }) 121 }) 122 123 When("not logged in", func() { 124 BeforeEach(func() { 125 helpers.LogoutCF() 126 }) 127 128 It("fails with not logged in message", func() { 129 session := helpers.CF("v3-push", appName) 130 Eventually(session).Should(Say("FAILED")) 131 Eventually(session.Err).Should(Say("Not logged in\\. Use 'cf login' to log in\\.")) 132 Eventually(session).Should(Exit(1)) 133 }) 134 }) 135 136 When("there is no org set", func() { 137 BeforeEach(func() { 138 helpers.LogoutCF() 139 helpers.LoginCF() 140 }) 141 142 It("fails with no org targeted error message", func() { 143 session := helpers.CF("v3-push", appName) 144 Eventually(session).Should(Say("FAILED")) 145 Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org\\.")) 146 Eventually(session).Should(Exit(1)) 147 }) 148 }) 149 150 When("there is no space set", func() { 151 BeforeEach(func() { 152 helpers.LogoutCF() 153 helpers.LoginCF() 154 helpers.TargetOrg(ReadOnlyOrg) 155 }) 156 157 It("fails with no space targeted error message", func() { 158 session := helpers.CF("v3-push", appName) 159 Eventually(session).Should(Say("FAILED")) 160 Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space\\.")) 161 Eventually(session).Should(Exit(1)) 162 }) 163 }) 164 }) 165 166 When("the environment is set up correctly", func() { 167 var domainName string 168 169 BeforeEach(func() { 170 helpers.SetupCF(orgName, spaceName) 171 domainName = helpers.DefaultSharedDomain() 172 }) 173 174 AfterEach(func() { 175 helpers.QuickDeleteOrg(orgName) 176 }) 177 178 When("the app exists", func() { 179 var session *Session 180 BeforeEach(func() { 181 helpers.WithHelloWorldApp(func(appDir string) { 182 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName)).Should(Exit(0)) 183 }) 184 185 helpers.WithHelloWorldApp(func(appDir string) { 186 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "https://github.com/cloudfoundry/staticfile-buildpack") 187 Eventually(session).Should(Exit(0)) 188 }) 189 }) 190 191 It("pushes the app", func() { 192 Eventually(session).Should(Say("Updating app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 193 Eventually(session).Should(Say("OK")) 194 Eventually(session).Should(Say("")) 195 Eventually(session).Should(Say("Uploading and creating bits package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 196 Eventually(session).Should(Say("OK")) 197 Eventually(session).Should(Say("")) 198 Eventually(session).Should(Say("Stopping app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 199 Eventually(session).Should(Say("OK")) 200 Eventually(session).Should(Say("")) 201 Eventually(session).Should(Say("Staging package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 202 Eventually(session).Should(Say("OK")) 203 Eventually(session).Should(Say("Setting app %s to droplet .+ in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 204 Eventually(session).Should(Say("OK")) 205 Eventually(session).Should(Say("")) 206 Eventually(session).Should(Say("Mapping routes\\.\\.\\.")) 207 Eventually(session).Should(Say("OK")) 208 Eventually(session).Should(Say("")) 209 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 210 Eventually(session).Should(Say("OK")) 211 Eventually(session).Should(Say("")) 212 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 213 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 214 Eventually(session).Should(Say("")) 215 Eventually(session).Should(Say("name:\\s+%s", appName)) 216 Eventually(session).Should(Say("requested state:\\s+started")) 217 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 218 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 219 220 // TODO: Uncomment when capi sorts out droplet buildpack name/detectoutput 221 // Eventually(session).Should(Say("buildpacks:\\s+https://github.com/cloudfoundry/staticfile-buildpack")) 222 Eventually(session).Should(Say("")) 223 Eventually(session).Should(Say("type:\\s+web")) 224 Eventually(session).Should(Say("instances:\\s+1/1")) 225 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 226 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 227 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 228 }) 229 }) 230 231 When("the app does not already exist", func() { 232 var session *Session 233 234 BeforeEach(func() { 235 helpers.WithHelloWorldApp(func(appDir string) { 236 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName) 237 Eventually(session).Should(Exit(0)) 238 }) 239 }) 240 241 It("pushes the app", func() { 242 Eventually(session).Should(Say("Creating app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 243 Eventually(session).Should(Say("OK")) 244 Eventually(session).Should(Say("")) 245 Eventually(session).Should(Say("Uploading and creating bits package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 246 Eventually(session).Should(Say("OK")) 247 Eventually(session).Should(Say("")) 248 Consistently(session).ShouldNot(Say("Stopping app %s", appName)) 249 Eventually(session).Should(Say("Staging package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 250 Eventually(session).Should(Say("OK")) 251 Eventually(session).Should(Say("Setting app %s to droplet .+ in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 252 Eventually(session).Should(Say("OK")) 253 Eventually(session).Should(Say("")) 254 Eventually(session).Should(Say("Mapping routes\\.\\.\\.")) 255 Eventually(session).Should(Say("OK")) 256 Eventually(session).Should(Say("")) 257 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 258 Eventually(session).Should(Say("OK")) 259 Eventually(session).Should(Say("")) 260 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 261 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 262 Eventually(session).Should(Say("")) 263 Eventually(session).Should(Say("name:\\s+%s", appName)) 264 Eventually(session).Should(Say("requested state:\\s+started")) 265 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 266 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 267 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 268 Eventually(session).Should(Say("")) 269 Eventually(session).Should(Say("type:\\s+web")) 270 Eventually(session).Should(Say("instances:\\s+1/1")) 271 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 272 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 273 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 274 }) 275 }) 276 277 When("the app crashes", func() { 278 var session *Session 279 280 BeforeEach(func() { 281 helpers.WithCrashingApp(func(appDir string) { 282 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName) 283 Eventually(session).Should(Exit(0)) 284 }) 285 }) 286 287 It("pushes the app", func() { 288 Eventually(session).Should(Say("Creating app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 289 Eventually(session).Should(Say("OK")) 290 Eventually(session).Should(Say("")) 291 Eventually(session).Should(Say("Uploading and creating bits package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 292 Eventually(session).Should(Say("OK")) 293 Eventually(session).Should(Say("")) 294 Consistently(session).ShouldNot(Say("Stopping app %s", appName)) 295 Eventually(session).Should(Say("Staging package for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 296 Eventually(session).Should(Say("OK")) 297 Eventually(session).Should(Say("Setting app %s to droplet .+ in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 298 Eventually(session).Should(Say("OK")) 299 Eventually(session).Should(Say("")) 300 Eventually(session).Should(Say("Mapping routes\\.\\.\\.")) 301 Eventually(session).Should(Say("OK")) 302 Eventually(session).Should(Say("")) 303 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 304 Eventually(session).Should(Say("OK")) 305 Eventually(session).Should(Say("")) 306 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 307 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 308 Eventually(session).Should(Say("")) 309 Eventually(session).Should(Say("name:\\s+%s", appName)) 310 Eventually(session).Should(Say("requested state:\\s+started")) 311 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 312 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 313 Eventually(session).Should(Say("buildpacks:\\s+ruby")) 314 Eventually(session).Should(Say("")) 315 Eventually(session).Should(Say("type:\\s+web")) 316 Eventually(session).Should(Say("instances:\\s+0/1")) 317 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 318 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 319 Eventually(session).Should(Say("#0\\s+crashed\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 320 }) 321 }) 322 323 When("the -p flag is provided", func() { 324 When("the path is a directory", func() { 325 When("the directory contains files", func() { 326 It("pushes the app from the directory", func() { 327 helpers.WithHelloWorldApp(func(appDir string) { 328 session := helpers.CF("v3-push", appName, "-p", appDir) 329 330 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 331 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 332 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 333 Eventually(session).Should(Say("")) 334 Eventually(session).Should(Say("name:\\s+%s", appName)) 335 Eventually(session).Should(Say("requested state:\\s+started")) 336 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 337 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 338 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 339 Eventually(session).Should(Say("")) 340 Eventually(session).Should(Say("type:\\s+web")) 341 Eventually(session).Should(Say("instances:\\s+1/1")) 342 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 343 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 344 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 345 346 Eventually(session).Should(Exit(0)) 347 }) 348 }) 349 }) 350 351 When("the directory is empty", func() { 352 var emptyDir string 353 354 BeforeEach(func() { 355 var err error 356 emptyDir, err = ioutil.TempDir("", "integration-push-path-empty") 357 Expect(err).ToNot(HaveOccurred()) 358 }) 359 360 AfterEach(func() { 361 Expect(os.RemoveAll(emptyDir)).ToNot(HaveOccurred()) 362 }) 363 364 It("returns an error", func() { 365 session := helpers.CF("v3-push", appName, "-p", emptyDir) 366 Eventually(session.Err).Should(Say("No app files found in '%s'", regexp.QuoteMeta(emptyDir))) 367 Eventually(session).Should(Exit(1)) 368 }) 369 }) 370 }) 371 372 When("the path is a zip file", func() { 373 Context("pushing a zip file", func() { 374 var archive string 375 376 BeforeEach(func() { 377 helpers.WithHelloWorldApp(func(appDir string) { 378 tmpfile, err := ioutil.TempFile("", "push-archive-integration") 379 Expect(err).ToNot(HaveOccurred()) 380 archive = tmpfile.Name() 381 Expect(tmpfile.Close()) 382 383 err = helpers.Zipit(appDir, archive, "") 384 Expect(err).ToNot(HaveOccurred()) 385 }) 386 }) 387 388 AfterEach(func() { 389 Expect(os.RemoveAll(archive)).ToNot(HaveOccurred()) 390 }) 391 392 It("pushes the app from the zip file", func() { 393 session := helpers.CF("v3-push", appName, "-p", archive) 394 395 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 396 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 397 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 398 Eventually(session).Should(Say("")) 399 Eventually(session).Should(Say("name:\\s+%s", appName)) 400 Eventually(session).Should(Say("requested state:\\s+started")) 401 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 402 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 403 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 404 Eventually(session).Should(Say("")) 405 Eventually(session).Should(Say("type:\\s+web")) 406 Eventually(session).Should(Say("instances:\\s+1/1")) 407 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 408 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 409 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 410 411 Eventually(session).Should(Exit(0)) 412 }) 413 }) 414 }) 415 416 When("the path is a symlink to a directory", func() { 417 var symlinkPath string 418 419 BeforeEach(func() { 420 tempFile, err := ioutil.TempFile("", "symlink-") 421 Expect(err).ToNot(HaveOccurred()) 422 Expect(tempFile.Close()).To(Succeed()) 423 424 symlinkPath = tempFile.Name() 425 Expect(os.Remove(symlinkPath)).To(Succeed()) 426 }) 427 428 AfterEach(func() { 429 Expect(os.Remove(symlinkPath)).To(Succeed()) 430 }) 431 432 It("creates and uploads the package from the directory", func() { 433 helpers.WithHelloWorldApp(func(appDir string) { 434 Expect(os.Symlink(appDir, symlinkPath)).To(Succeed()) 435 436 session := helpers.CF("v3-push", appName, "-p", symlinkPath) 437 438 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 439 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 440 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 441 Eventually(session).Should(Say("")) 442 Eventually(session).Should(Say("name:\\s+%s", appName)) 443 Eventually(session).Should(Say("requested state:\\s+started")) 444 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 445 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 446 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 447 Eventually(session).Should(Say("")) 448 Eventually(session).Should(Say("type:\\s+web")) 449 Eventually(session).Should(Say("instances:\\s+1/1")) 450 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 451 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 452 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 453 454 Eventually(session).Should(Exit(0)) 455 }) 456 }) 457 }) 458 459 When("the path is a symlink to a zip file", func() { 460 var ( 461 archive string 462 symlinkPath string 463 ) 464 465 BeforeEach(func() { 466 helpers.WithHelloWorldApp(func(appDir string) { 467 tmpfile, err := ioutil.TempFile("", "package-archive-integration") 468 Expect(err).ToNot(HaveOccurred()) 469 archive = tmpfile.Name() 470 Expect(tmpfile.Close()) 471 472 err = helpers.Zipit(appDir, archive, "") 473 Expect(err).ToNot(HaveOccurred()) 474 }) 475 476 tempFile, err := ioutil.TempFile("", "symlink-to-archive-") 477 Expect(err).ToNot(HaveOccurred()) 478 Expect(tempFile.Close()).To(Succeed()) 479 480 symlinkPath = tempFile.Name() 481 Expect(os.Remove(symlinkPath)).To(Succeed()) 482 Expect(os.Symlink(archive, symlinkPath)).To(Succeed()) 483 }) 484 485 AfterEach(func() { 486 Expect(os.Remove(archive)).To(Succeed()) 487 Expect(os.Remove(symlinkPath)).To(Succeed()) 488 }) 489 490 It("creates and uploads the package from the zip file", func() { 491 session := helpers.CF("v3-push", appName, "-p", symlinkPath) 492 493 Eventually(session).Should(Say("Starting app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 494 Eventually(session).Should(Say("Waiting for app to start\\.\\.\\.")) 495 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 496 Eventually(session).Should(Say("")) 497 Eventually(session).Should(Say("name:\\s+%s", appName)) 498 Eventually(session).Should(Say("requested state:\\s+started")) 499 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 500 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 501 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 502 Eventually(session).Should(Say("")) 503 Eventually(session).Should(Say("type:\\s+web")) 504 Eventually(session).Should(Say("instances:\\s+1/1")) 505 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 506 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 507 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 508 509 Eventually(session).Should(Exit(0)) 510 }) 511 }) 512 }) 513 514 When("the --no-route flag is set", func() { 515 var session *Session 516 517 BeforeEach(func() { 518 helpers.WithHelloWorldApp(func(appDir string) { 519 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "--no-route") 520 Eventually(session).Should(Exit(0)) 521 }) 522 }) 523 524 It("does not map any routes to the app", func() { 525 Consistently(session).ShouldNot(Say("Mapping routes\\.\\.\\.")) 526 Eventually(session).Should(Say("name:\\s+%s", appName)) 527 Eventually(session).Should(Say("requested state:\\s+started")) 528 Eventually(session).Should(Say("routes:\\s+\n")) 529 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 530 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 531 Eventually(session).Should(Say("")) 532 Eventually(session).Should(Say("type:\\s+web")) 533 Eventually(session).Should(Say("instances:\\s+1/1")) 534 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 535 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 536 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 537 }) 538 }) 539 540 When("the -b flag is set", func() { 541 var session *Session 542 543 When("pushing a multi-buildpack app", func() { 544 BeforeEach(func() { 545 helpers.WithMultiBuildpackApp(func(appDir string) { 546 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "ruby_buildpack", "-b", "go_buildpack") 547 548 // TODO: uncomment this expectation once capi-release displays all buildpacks on droplet 549 // Story: https://www.pivotaltracker.com/story/show/150425459 550 // Eventually(session).Should(Say("buildpacks:.*ruby_buildpack, go_buildpack")) 551 552 Eventually(session).Should(Exit(0)) 553 }) 554 }) 555 556 It("successfully compiles and runs the app", func() { 557 resp, err := http.Get(fmt.Sprintf("http://%s.%s", appName, helpers.DefaultSharedDomain())) 558 Expect(err).ToNot(HaveOccurred()) 559 Expect(resp.StatusCode).To(Equal(http.StatusOK)) 560 }) 561 }) 562 563 When("resetting the buildpack to default", func() { 564 BeforeEach(func() { 565 helpers.WithHelloWorldApp(func(appDir string) { 566 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "java_buildpack")).Should(Exit(1)) 567 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "default") 568 Eventually(session).Should(Exit(0)) 569 }) 570 }) 571 572 It("successfully pushes the app", func() { 573 Eventually(session).Should(Say("name:\\s+%s", appName)) 574 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 575 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 576 }) 577 }) 578 579 When("omitting the buildpack", func() { 580 BeforeEach(func() { 581 helpers.WithHelloWorldApp(func(appDir string) { 582 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "java_buildpack")).Should(Exit(1)) 583 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName) 584 Eventually(session).Should(Exit(1)) 585 }) 586 }) 587 588 It("continues using previously set buildpack", func() { 589 Eventually(session).Should(Say("FAILED")) 590 }) 591 }) 592 593 When("the buildpack is invalid", func() { 594 BeforeEach(func() { 595 helpers.WithHelloWorldApp(func(appDir string) { 596 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "wut") 597 Eventually(session).Should(Exit(1)) 598 }) 599 }) 600 601 It("errors and does not push the app", func() { 602 Consistently(session).ShouldNot(Say("Creating app")) 603 Eventually(session).Should(Say("FAILED")) 604 Eventually(session.Err).Should(Say(`Buildpack "wut" must be an existing admin buildpack or a valid git URI`)) 605 }) 606 }) 607 608 When("the buildpack is valid", func() { 609 BeforeEach(func() { 610 helpers.WithHelloWorldApp(func(appDir string) { 611 session = helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName, "-b", "https://github.com/cloudfoundry/staticfile-buildpack") 612 Eventually(session).Should(Exit(0)) 613 }) 614 }) 615 616 It("uses the specified buildpack", func() { 617 Eventually(session).Should(Say("name:\\s+%s", appName)) 618 Eventually(session).Should(Say("requested state:\\s+started")) 619 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 620 Eventually(session).Should(Say("stack:\\s+cflinuxfs")) 621 622 // TODO: Uncomment when capi sorts out droplet buildpack name/detectoutput 623 // Eventually(session).Should(Say("buildpacks:\\s+https://github.com/cloudfoundry/staticfile-buildpack")) 624 Eventually(session).Should(Say("")) 625 Eventually(session).Should(Say("type:\\s+web")) 626 Eventually(session).Should(Say("instances:\\s+1/1")) 627 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 628 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 629 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 630 }) 631 }) 632 }) 633 634 When("the -o flag is set", func() { 635 When("the docker image is valid", func() { 636 It("uses the specified docker image", func() { 637 session := helpers.CF("v3-push", appName, "-o", PublicDockerImage) 638 639 Eventually(session).Should(Say("name:\\s+%s", appName)) 640 Eventually(session).Should(Say("requested state:\\s+started")) 641 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 642 Eventually(session).Should(Say("stack:")) 643 Eventually(session).ShouldNot(Say("buildpacks:")) 644 Eventually(session).Should(Say("docker image:\\s+%s", PublicDockerImage)) 645 Eventually(session).Should(Say("")) 646 Eventually(session).Should(Say("type:\\s+web")) 647 Eventually(session).Should(Say("instances:\\s+1/1")) 648 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 649 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 650 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 651 Eventually(session).Should(Exit(0)) 652 }) 653 }) 654 655 When("the docker image is invalid", func() { 656 It("displays an error and exits 1", func() { 657 session := helpers.CF("v3-push", appName, "-o", "some-invalid-docker-image") 658 Eventually(session).Should(Say("FAILED")) 659 Eventually(session.Err).Should(Say("StagingError - Staging error: staging failed")) 660 Eventually(session).Should(Exit(1)) 661 }) 662 }) 663 664 When("a docker username and password are provided with a private image", func() { 665 var ( 666 privateDockerImage string 667 privateDockerUsername string 668 privateDockerPassword string 669 ) 670 671 BeforeEach(func() { 672 privateDockerImage = os.Getenv("CF_INT_DOCKER_IMAGE") 673 privateDockerUsername = os.Getenv("CF_INT_DOCKER_USERNAME") 674 privateDockerPassword = os.Getenv("CF_INT_DOCKER_PASSWORD") 675 676 if privateDockerImage == "" || privateDockerUsername == "" || privateDockerPassword == "" { 677 Skip("CF_INT_DOCKER_IMAGE, CF_INT_DOCKER_USERNAME, or CF_INT_DOCKER_PASSWORD is not set") 678 } 679 }) 680 681 It("uses the specified private docker image", func() { 682 session := helpers.CustomCF( 683 helpers.CFEnv{ 684 EnvVars: map[string]string{"CF_DOCKER_PASSWORD": privateDockerPassword}, 685 }, 686 "v3-push", "--docker-username", privateDockerUsername, "--docker-image", privateDockerImage, appName, 687 ) 688 689 Eventually(session).Should(Say("name:\\s+%s", appName)) 690 Eventually(session).Should(Say("requested state:\\s+started")) 691 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 692 Eventually(session).Should(Say("stack:")) 693 Eventually(session).ShouldNot(Say("buildpacks:")) 694 Eventually(session).Should(Say("docker image:\\s+%s", privateDockerImage)) 695 Eventually(session).Should(Say("")) 696 Eventually(session).Should(Say("type:\\s+web")) 697 Eventually(session).Should(Say("instances:\\s+1/1")) 698 Eventually(session).Should(Say("memory usage:\\s+\\d+(M|G)")) 699 Eventually(session).Should(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 700 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 701 Eventually(session).Should(Exit(0)) 702 }) 703 }) 704 }) 705 706 Describe("argument combination errors", func() { 707 When("the --docker-username is provided without the -o flag", func() { 708 It("displays an error and exits 1", func() { 709 helpers.WithHelloWorldApp(func(appDir string) { 710 session := helpers.CF("v3-push", appName, "--docker-username", "some-username") 711 Eventually(session).Should(Say("FAILED")) 712 Eventually(session.Err).Should(Say("Incorrect Usage: '--docker-image, -o' and '--docker-username' must be used together.")) 713 Eventually(session).Should(Say("NAME:")) 714 Eventually(session).Should(Exit(1)) 715 }) 716 }) 717 }) 718 719 When("the --docker-username and -p flags are provided together", func() { 720 It("displays an error and exits 1", func() { 721 helpers.WithHelloWorldApp(func(appDir string) { 722 session := helpers.CF("v3-push", appName, "--docker-username", "some-username", "-p", appDir) 723 Eventually(session).Should(Say("FAILED")) 724 Eventually(session.Err).Should(Say("Incorrect Usage: '--docker-image, -o' and '--docker-username' must be used together.")) 725 Eventually(session).Should(Say("NAME:")) 726 Eventually(session).Should(Exit(1)) 727 }) 728 }) 729 }) 730 731 When("the --docker-username is provided without a password", func() { 732 var oldPassword string 733 734 BeforeEach(func() { 735 oldPassword = os.Getenv("CF_DOCKER_PASSWORD") 736 err := os.Unsetenv("CF_DOCKER_PASSWORD") 737 Expect(err).ToNot(HaveOccurred()) 738 }) 739 740 AfterEach(func() { 741 err := os.Setenv("CF_DOCKER_PASSWORD", oldPassword) 742 Expect(err).ToNot(HaveOccurred()) 743 }) 744 745 It("displays an error and exits 1", func() { 746 helpers.WithHelloWorldApp(func(appDir string) { 747 session := helpers.CF("v3-push", appName, "--docker-username", "some-username", "--docker-image", "some-image") 748 Eventually(session).Should(Say("FAILED")) 749 Eventually(session.Err).Should(Say("Environment variable CF_DOCKER_PASSWORD not set\\.")) 750 Eventually(session).Should(Exit(1)) 751 }) 752 }) 753 }) 754 755 When("the -o and -p flags are provided together", func() { 756 It("displays an error and exits 1", func() { 757 helpers.WithHelloWorldApp(func(appDir string) { 758 session := helpers.CF("v3-push", appName, "-o", PublicDockerImage, "-p", appDir) 759 Eventually(session).Should(Say("FAILED")) 760 Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: --docker-image, -o, -p")) 761 Eventually(session).Should(Say("NAME:")) 762 Eventually(session).Should(Exit(1)) 763 }) 764 }) 765 }) 766 767 When("the -o and -b flags are provided together", func() { 768 It("displays an error and exits 1", func() { 769 helpers.WithHelloWorldApp(func(appDir string) { 770 session := helpers.CF("v3-push", appName, "-o", PublicDockerImage, "-b", "some-buildpack") 771 Eventually(session).Should(Say("FAILED")) 772 Eventually(session.Err).Should(Say("Incorrect Usage: The following arguments cannot be used together: -b, --docker-image, -o")) 773 Eventually(session).Should(Say("NAME:")) 774 Eventually(session).Should(Exit(1)) 775 }) 776 }) 777 }) 778 }) 779 }) 780 })