github.com/randomtask1155/cli@v6.41.1-0.20181227003417-a98eed78cbde+incompatible/integration/v6/isolated/app_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
     9  	"code.cloudfoundry.org/cli/integration/helpers"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/gbytes"
    13  	. "github.com/onsi/gomega/gexec"
    14  )
    15  
    16  var _ = Describe("app command", func() {
    17  	var (
    18  		orgName   string
    19  		spaceName string
    20  		appName   string
    21  	)
    22  
    23  	BeforeEach(func() {
    24  		orgName = helpers.NewOrgName()
    25  		spaceName = helpers.NewSpaceName()
    26  		appName = helpers.PrefixedRandomName("app")
    27  	})
    28  
    29  	Describe("help", func() {
    30  		When("--help flag is set", func() {
    31  			It("Displays command usage to output", func() {
    32  				session := helpers.CF("app", "--help")
    33  				Eventually(session).Should(Say("NAME:"))
    34  				Eventually(session).Should(Say("app - Display health and status for an app"))
    35  				Eventually(session).Should(Say("USAGE:"))
    36  				Eventually(session).Should(Say("cf app APP_NAME"))
    37  				Eventually(session).Should(Say("OPTIONS:"))
    38  				Eventually(session).Should(Say("--guid      Retrieve and display the given app's guid.  All other health and status output for the app is suppressed."))
    39  				Eventually(session).Should(Say("SEE ALSO:"))
    40  				Eventually(session).Should(Say("apps, events, logs, map-route, push, unmap-route"))
    41  				Eventually(session).Should(Exit(0))
    42  			})
    43  		})
    44  	})
    45  
    46  	When("the environment is not setup correctly", func() {
    47  		It("fails with the appropriate errors", func() {
    48  			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "app", "some-app")
    49  		})
    50  
    51  		When("no API endpoint is set", func() {
    52  			BeforeEach(func() {
    53  				helpers.UnsetAPI()
    54  			})
    55  
    56  			It("fails with no API endpoint set message", func() {
    57  				session := helpers.CF("app", appName)
    58  				Eventually(session).Should(Say("FAILED"))
    59  				Eventually(session.Err).Should(Say("No API endpoint set\\. Use 'cf login' or 'cf api' to target an endpoint\\."))
    60  				Eventually(session).Should(Exit(1))
    61  			})
    62  		})
    63  		When("not logged in", func() {
    64  			BeforeEach(func() {
    65  				helpers.LogoutCF()
    66  			})
    67  
    68  			It("fails with not logged in message", func() {
    69  				session := helpers.CF("app", appName)
    70  				Eventually(session).Should(Say("FAILED"))
    71  				Eventually(session.Err).Should(Say("Not logged in\\. Use 'cf login' to log in\\."))
    72  				Eventually(session).Should(Exit(1))
    73  			})
    74  		})
    75  
    76  		When("there is no org set", func() {
    77  			BeforeEach(func() {
    78  				helpers.LogoutCF()
    79  				helpers.LoginCF()
    80  			})
    81  
    82  			It("fails with no org targeted error message", func() {
    83  				session := helpers.CF("app", appName)
    84  				Eventually(session).Should(Say("FAILED"))
    85  				Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org\\."))
    86  				Eventually(session).Should(Exit(1))
    87  			})
    88  		})
    89  
    90  		When("there is no space set", func() {
    91  			BeforeEach(func() {
    92  				helpers.LogoutCF()
    93  				helpers.LoginCF()
    94  				helpers.TargetOrg(ReadOnlyOrg)
    95  			})
    96  
    97  			It("fails with no space targeted error message", func() {
    98  				session := helpers.CF("app", appName)
    99  				Eventually(session).Should(Say("FAILED"))
   100  				Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space\\."))
   101  				Eventually(session).Should(Exit(1))
   102  			})
   103  		})
   104  	})
   105  
   106  	When("the environment is set up correctly", func() {
   107  		BeforeEach(func() {
   108  			helpers.SetupCF(orgName, spaceName)
   109  		})
   110  
   111  		AfterEach(func() {
   112  			helpers.QuickDeleteOrg(orgName)
   113  		})
   114  
   115  		Describe("version dependent display", func() {
   116  			When("CC API >= 3.27.0", func() {
   117  				BeforeEach(func() {
   118  					helpers.SkipIfVersionLessThan(ccversion.MinVersionApplicationFlowV3)
   119  				})
   120  
   121  				When("CC API >= 3.55.0", func() {
   122  					BeforeEach(func() {
   123  						helpers.SkipIfVersionLessThan("3.55.0")
   124  					})
   125  
   126  					When("all instances of the app are down", func() {
   127  						BeforeEach(func() {
   128  							infiniteMemQuota := helpers.QuotaName()
   129  							Eventually(helpers.CF("create-quota", infiniteMemQuota, "-i", "-1", "-r", "-1", "-m", "2000G")).Should(Exit(0))
   130  							Eventually(helpers.CF("set-quota", orgName, infiniteMemQuota)).Should(Exit(0))
   131  
   132  							helpers.WithHelloWorldApp(func(appDir string) {
   133  								Eventually(helpers.CF("push", appName, "-p", appDir)).Should(Exit(0))
   134  							})
   135  							Eventually(helpers.CFWithEnv(map[string]string{"CF_STAGING_TIMEOUT": "0.1", "CF_STARTUP_TIMEOUT": "0.1"}, "scale", appName, "-m", "1000G", "-f")).Should(Exit(1))
   136  						})
   137  
   138  						It("displays the down app instances", func() {
   139  							session := helpers.CF("app", appName)
   140  
   141  							userName, _ := helpers.GetCredentials()
   142  							Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   143  							Eventually(session).Should(Say("name:\\s+%s", appName))
   144  							Eventually(session).Should(Say("requested state:\\s+started"))
   145  							Eventually(session).Should(Say("type:\\s+web"))
   146  							Eventually(session).Should(Say("#0\\s+down\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z.+insufficient resources: memory"))
   147  							Eventually(session).Should(Exit(0))
   148  						})
   149  					})
   150  				})
   151  
   152  				When("the app is created but not pushed", func() {
   153  					BeforeEach(func() {
   154  						Eventually(helpers.CF("v3-create-app", appName)).Should(Exit(0))
   155  					})
   156  
   157  					It("displays blank fields for unpopulated fields", func() {
   158  						session := helpers.CF("app", appName)
   159  						Eventually(session).Should(Say("name:\\s+%s", appName))
   160  						Eventually(session).Should(Say("requested state:\\s+stopped"))
   161  						Eventually(session).Should(Say("routes:\\s+\n"))
   162  						Eventually(session).Should(Say("last uploaded:\\s+\n"))
   163  						Eventually(session).Should(Say("stack:\\s+\n"))
   164  						Eventually(session).Should(Say("buildpacks:\\s+\n"))
   165  						Eventually(session).Should(Exit(0))
   166  					})
   167  				})
   168  
   169  				When("the app is a buildpack app", func() {
   170  					var domainName string
   171  
   172  					BeforeEach(func() {
   173  						domainName = helpers.DefaultSharedDomain()
   174  					})
   175  
   176  					When("the app is started and has 2 instances", func() {
   177  						BeforeEach(func() {
   178  							helpers.WithHelloWorldApp(func(appDir string) {
   179  								manifestContents := []byte(fmt.Sprintf(`
   180  ---
   181  applications:
   182  - name: %s
   183    memory: 128M
   184    instances: 2
   185    disk_quota: 128M
   186    routes:
   187    - route: %s.%s
   188  `, appName, appName, domainName))
   189  								manifestPath := filepath.Join(appDir, "manifest.yml")
   190  								err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   191  								Expect(err).ToNot(HaveOccurred())
   192  
   193  								// Create manifest
   194  								Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   195  							})
   196  						})
   197  
   198  						// TODO: use multiprocess
   199  						It("uses the multiprocess display", func() {
   200  							userName, _ := helpers.GetCredentials()
   201  
   202  							session := helpers.CF("app", appName)
   203  
   204  							Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName))
   205  
   206  							Eventually(session).ShouldNot(Say("This command is in EXPERIMENTAL stage and may change without notice"))
   207  							Eventually(session).Should(Say("name:\\s+%s", appName))
   208  							Eventually(session).Should(Say("requested state:\\s+started"))
   209  							Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName))
   210  							Eventually(session).Should(Say("last uploaded:\\s+\\w{3} \\d{1,2} \\w{3} \\d{2}:\\d{2}:\\d{2} \\w{3} \\d{4}"))
   211  							Eventually(session).Should(Say("stack:\\s+cflinuxfs2"))
   212  							Eventually(session).Should(Say("buildpacks:\\s+staticfile"))
   213  							Eventually(session).Should(Say("type:\\s+web"))
   214  							Eventually(session).Should(Say("instances:\\s+\\d/2"))
   215  							Eventually(session).Should(Say("memory usage:\\s+128M"))
   216  							Eventually(session).Should(Say("\\s+state\\s+since\\s+cpu\\s+memory\\s+disk\\s+details"))
   217  							Eventually(session).Should(Say("#0\\s+(starting|running)\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"))
   218  
   219  							Eventually(session).Should(Exit(0))
   220  						})
   221  					})
   222  				})
   223  
   224  				When("the app is stopped", func() {
   225  					BeforeEach(func() {
   226  						helpers.WithHelloWorldApp(func(appDir string) {
   227  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   228  						})
   229  					})
   230  
   231  					It("displays that there are no running instances of the app", func() {
   232  						session := helpers.CF("app", appName)
   233  
   234  						userName, _ := helpers.GetCredentials()
   235  						Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   236  						Eventually(session).Should(Say("name:\\s+%s", appName))
   237  						Eventually(session).Should(Say("requested state:\\s+stopped"))
   238  						Eventually(session).Should(Say("type:\\s+web"))
   239  						Eventually(session).Should(Say("#0\\s+down\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"))
   240  						Eventually(session).Should(Exit(0))
   241  					})
   242  				})
   243  
   244  				When("the app has 0 instances", func() {
   245  					BeforeEach(func() {
   246  						helpers.WithHelloWorldApp(func(appDir string) {
   247  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-i", "0")).Should(Exit(0))
   248  						})
   249  					})
   250  
   251  					It("displays the app information", func() {
   252  						session := helpers.CF("app", appName)
   253  						userName, _ := helpers.GetCredentials()
   254  
   255  						Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   256  						Eventually(session).Should(Say("name:\\s+%s", appName))
   257  						Eventually(session).Should(Say("requested state:\\s+started"))
   258  						Eventually(session).Should(Say("type:\\s+web"))
   259  						Eventually(session).Should(Say("There are no running instances of this process"))
   260  						Eventually(session).Should(Exit(0))
   261  					})
   262  				})
   263  
   264  				When("the --guid flag is given", func() {
   265  					var appGUID string
   266  
   267  					BeforeEach(func() {
   268  						helpers.WithHelloWorldApp(func(appDir string) {
   269  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   270  						})
   271  
   272  						var AppInfo struct {
   273  							Resources []struct {
   274  								GUID string `json:"guid"`
   275  							} `json:"resources"`
   276  						}
   277  
   278  						helpers.Curl(&AppInfo, "/v3/apps?names=%s", appName)
   279  						appGUID = AppInfo.Resources[0].GUID
   280  					})
   281  
   282  					It("displays the app guid", func() {
   283  						session := helpers.CF("app", "--guid", appName)
   284  						Eventually(session).Should(Say(appGUID))
   285  						Eventually(session).Should(Exit(0))
   286  					})
   287  				})
   288  
   289  				When("the app uses multiple buildpacks", func() {
   290  					BeforeEach(func() {
   291  						// Until version 3.43, droplets did not list all buildpacks they were built with (#150068339).
   292  						helpers.SkipIfVersionLessThan("3.43.0")
   293  
   294  						helpers.WithMultiBuildpackApp(func(appDir string) {
   295  							Eventually(helpers.CF("v3-push", appName, "-p", appDir, "-b", "ruby_buildpack", "-b", "go_buildpack")).Should(Exit(0))
   296  						})
   297  					})
   298  
   299  					It("displays the app buildpacks", func() {
   300  						session := helpers.CF("app", appName)
   301  						Eventually(session).Should(Say("buildpacks:\\s+ruby_buildpack,\\s+go"))
   302  						Eventually(session).Should(Exit(0))
   303  					})
   304  				})
   305  			})
   306  
   307  			When("CC API < 3.27.0", func() {
   308  				BeforeEach(func() {
   309  					helpers.SkipIfVersionAtLeast(ccversion.MinVersionApplicationFlowV3)
   310  				})
   311  
   312  				When("the app is a buildpack app", func() {
   313  					var domainName string
   314  
   315  					BeforeEach(func() {
   316  						domainName = helpers.DefaultSharedDomain()
   317  					})
   318  
   319  					When("the app is started and has 2 instances", func() {
   320  						BeforeEach(func() {
   321  							helpers.WithHelloWorldApp(func(appDir string) {
   322  								manifestContents := []byte(fmt.Sprintf(`
   323  ---
   324  applications:
   325  - name: %s
   326    memory: 128M
   327    instances: 2
   328    disk_quota: 128M
   329    routes:
   330    - route: %s.%s
   331  `, appName, appName, domainName))
   332  								manifestPath := filepath.Join(appDir, "manifest.yml")
   333  								err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   334  								Expect(err).ToNot(HaveOccurred())
   335  
   336  								// Create manifest
   337  								Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   338  							})
   339  						})
   340  
   341  						It("runs the v6 command", func() {
   342  							session := helpers.CF("app", appName)
   343  							Eventually(session).Should(Say("name:\\s+%s", appName))
   344  							Eventually(session).Should(Say("requested state:\\s+started"))
   345  							Eventually(session).Should(Say("instances:\\s+2/2"))
   346  							Eventually(session).Should(Say("usage:\\s+128M x 2 instances"))
   347  							Eventually(session).Should(Say("routes:\\s+[\\w\\d-]+\\.%s", domainName))
   348  							Eventually(session).Should(Say("last uploaded:\\s+\\w{3} [0-3]\\d \\w{3} [0-2]\\d:[0-5]\\d:[0-5]\\d \\w+ \\d{4}"))
   349  							Eventually(session).Should(Say("stack:\\s+cflinuxfs2"))
   350  							Eventually(session).Should(Say("buildpack:\\s+staticfile_buildpack"))
   351  							Eventually(session).Should(Say(""))
   352  							Eventually(session).Should(Say("state\\s+since\\s+cpu\\s+memory\\s+disk\\s+details"))
   353  							Eventually(session).Should(Say("#0\\s+(running|starting)\\s+\\d{4}-[01]\\d-[0-3]\\dT[0-2][0-9]:[0-5]\\d:[0-5]\\dZ\\s+\\d+\\.\\d+%.*of 128M.*of 128M"))
   354  							Eventually(session).Should(Say("#1\\s+(running|starting)\\s+\\d{4}-[01]\\d-[0-3]\\dT[0-2][0-9]:[0-5]\\d:[0-5]\\dZ\\s+\\d+\\.\\d+%.*of 128M.*of 128M"))
   355  							Eventually(session).Should(Exit(0))
   356  						})
   357  					})
   358  				})
   359  
   360  				When("the app is stopped", func() {
   361  					BeforeEach(func() {
   362  						helpers.WithHelloWorldApp(func(appDir string) {
   363  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   364  						})
   365  					})
   366  
   367  					It("displays that there are no running instances of the app", func() {
   368  						session := helpers.CF("app", appName)
   369  
   370  						userName, _ := helpers.GetCredentials()
   371  						Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   372  						Eventually(session).Should(Say("name:\\s+%s", appName))
   373  						Eventually(session).Should(Say("requested state:\\s+stopped"))
   374  						Eventually(session).Should(Say("usage:\\s+\\d+M x 1 instances"))
   375  						Eventually(session).Should(Say("There are no running instances of this app."))
   376  						Eventually(session).Should(Exit(0))
   377  					})
   378  				})
   379  
   380  				When("the app has 0 instances", func() {
   381  					BeforeEach(func() {
   382  						helpers.SkipIfVersionLessThan(ccversion.MinVersionZeroAppInstancesV2)
   383  						helpers.WithHelloWorldApp(func(appDir string) {
   384  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-i", "0")).Should(Exit(0))
   385  						})
   386  					})
   387  
   388  					It("displays the app information", func() {
   389  						session := helpers.CF("app", appName)
   390  						userName, _ := helpers.GetCredentials()
   391  
   392  						Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   393  						Eventually(session).Should(Say("name:\\s+%s", appName))
   394  						Eventually(session).Should(Say("requested state:\\s+started"))
   395  						Eventually(session).Should(Say("usage:\\s+\\d+M x 0 instances"))
   396  						Eventually(session).Should(Say("There are no running instances of this app."))
   397  						Eventually(session).Should(Exit(0))
   398  					})
   399  				})
   400  
   401  				When("the --guid flag is given", func() {
   402  					var appGUID string
   403  
   404  					BeforeEach(func() {
   405  						helpers.WithHelloWorldApp(func(appDir string) {
   406  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   407  						})
   408  
   409  						var AppInfo struct {
   410  							Resources []struct {
   411  								Metadata struct {
   412  									GUID string `json:"guid"`
   413  								} `json:"metadata"`
   414  							} `json:"resources"`
   415  						}
   416  						helpers.Curl(&AppInfo, "/v2/apps?q=name:%s", appName)
   417  						appGUID = AppInfo.Resources[0].Metadata.GUID
   418  					})
   419  
   420  					It("displays the app guid", func() {
   421  						session := helpers.CF("app", "--guid", appName)
   422  						Eventually(session).Should(Say(appGUID))
   423  						Eventually(session).Should(Exit(0))
   424  					})
   425  				})
   426  			})
   427  		})
   428  
   429  		Describe("version independent display", func() {
   430  			When("the app name is not provided", func() {
   431  				It("tells the user that the app name is required, prints help text, and exits 1", func() {
   432  					session := helpers.CF("app")
   433  
   434  					Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
   435  					Eventually(session).Should(Say("NAME:"))
   436  					Eventually(session).Should(Exit(1))
   437  				})
   438  			})
   439  
   440  			When("the app does not exist", func() {
   441  				When("no flags are given", func() {
   442  					It("tells the user that the app is not found and exits 1", func() {
   443  						session := helpers.CF("app", appName)
   444  
   445  						Eventually(session).Should(Say("FAILED"))
   446  						Eventually(session.Err).Should(Say("App %s not found", appName))
   447  						Eventually(session).Should(Exit(1))
   448  					})
   449  				})
   450  
   451  				When("the --guid flag is given", func() {
   452  					It("tells the user that the app is not found and exits 1", func() {
   453  						session := helpers.CF("app", "--guid", appName)
   454  
   455  						Eventually(session).Should(Say("FAILED"))
   456  						Eventually(session.Err).Should(Say("App %s not found", appName))
   457  						Eventually(session).Should(Exit(1))
   458  					})
   459  				})
   460  			})
   461  
   462  			When("the app exists", func() {
   463  				When("isolation segments are available", func() {
   464  					BeforeEach(func() {
   465  						helpers.SkipIfVersionLessThan(ccversion.MinVersionIsolationSegmentV3)
   466  
   467  						Eventually(helpers.CF("create-isolation-segment", RealIsolationSegment)).Should(Exit(0))
   468  						Eventually(helpers.CF("enable-org-isolation", orgName, RealIsolationSegment)).Should(Exit(0))
   469  						Eventually(helpers.CF("set-space-isolation-segment", spaceName, RealIsolationSegment)).Should(Exit(0))
   470  
   471  						helpers.WithHelloWorldApp(func(appDir string) {
   472  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack")).Should(Exit(0))
   473  						})
   474  					})
   475  
   476  					It("displays the app isolation segment information", func() {
   477  						session := helpers.CF("app", appName)
   478  
   479  						Eventually(session).Should(Say("isolation segment:\\s+%s", RealIsolationSegment))
   480  						Eventually(session).Should(Exit(0))
   481  					})
   482  				})
   483  
   484  				When("isolation segment is not set for the application", func() {
   485  					BeforeEach(func() {
   486  						helpers.WithHelloWorldApp(func(appDir string) {
   487  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack")).Should(Exit(0))
   488  						})
   489  					})
   490  
   491  					It("displays the app isolation segment information", func() {
   492  						session := helpers.CF("app", appName)
   493  
   494  						Consistently(session).ShouldNot(Say("isolation segment:"))
   495  						Eventually(session).Should(Exit(0))
   496  					})
   497  				})
   498  
   499  				When("the app is a Docker app", func() {
   500  					BeforeEach(func() {
   501  						Eventually(helpers.CF("push", appName, "-o", DockerImage)).Should(Exit())
   502  					})
   503  
   504  					It("displays the docker image", func() {
   505  						session := helpers.CF("app", appName)
   506  						Eventually(session).Should(Say("name:\\s+%s", appName))
   507  						Eventually(session).Should(Say("docker image:\\s+%s", DockerImage))
   508  						Eventually(session).Should(Exit(0))
   509  					})
   510  
   511  					It("does not display buildpack", func() {
   512  						session := helpers.CF("app", appName)
   513  						Consistently(session).ShouldNot(Say("buildpacks?:"))
   514  						Eventually(session).Should(Exit(0))
   515  					})
   516  				})
   517  
   518  				When("the app has tcp routes", func() {
   519  					var tcpDomain helpers.Domain
   520  
   521  					BeforeEach(func() {
   522  						helpers.SkipIfVersionLessThan(ccversion.MinVersionRoutingV3)
   523  
   524  						tcpDomain = helpers.NewDomain(orgName, helpers.NewDomainName("tcp"))
   525  						tcpDomain.CreateWithRouterGroup(helpers.FindOrCreateTCPRouterGroup(GinkgoParallelNode()))
   526  						helpers.WithHelloWorldApp(func(appDir string) {
   527  							manifestContents := []byte(fmt.Sprintf(`
   528  ---
   529  applications:
   530  - name: %s
   531    routes:
   532    - route: %s:1024
   533  `, appName, tcpDomain.Name))
   534  							manifestPath := filepath.Join(appDir, "manifest.yml")
   535  							err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   536  							Expect(err).ToNot(HaveOccurred())
   537  
   538  							// Create manifest
   539  							Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   540  						})
   541  
   542  						It("displays the app information", func() {
   543  							session := helpers.CF("app", appName)
   544  							Eventually(session).Should(Say("routes:\\s+[\\w\\d-]+\\.%s", tcpDomain))
   545  							Eventually(session).Should(Exit(0))
   546  						})
   547  					})
   548  				})
   549  			})
   550  		})
   551  	})
   552  })