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