github.com/arunkumar7540/cli@v6.45.0+incompatible/integration/v7/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/integration/helpers"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gbytes"
    12  	. "github.com/onsi/gomega/gexec"
    13  )
    14  
    15  var _ = Describe("app command", func() {
    16  	var (
    17  		orgName   string
    18  		spaceName string
    19  		appName   string
    20  	)
    21  
    22  	BeforeEach(func() {
    23  		orgName = helpers.NewOrgName()
    24  		spaceName = helpers.NewSpaceName()
    25  		appName = helpers.PrefixedRandomName("app")
    26  	})
    27  
    28  	Describe("help", func() {
    29  		When("--help flag is set", func() {
    30  			It("Displays command usage to output", func() {
    31  				session := helpers.CF("app", "--help")
    32  				Eventually(session).Should(Say("NAME:"))
    33  				Eventually(session).Should(Say("app - Display health and status for an app"))
    34  				Eventually(session).Should(Say("USAGE:"))
    35  				Eventually(session).Should(Say("cf app APP_NAME"))
    36  				Eventually(session).Should(Say("OPTIONS:"))
    37  				Eventually(session).Should(Say("--guid      Retrieve and display the given app's guid.  All other health and status output for the app is suppressed."))
    38  				Eventually(session).Should(Say("SEE ALSO:"))
    39  				Eventually(session).Should(Say("apps, events, logs, map-route, push, unmap-route"))
    40  				Eventually(session).Should(Exit(0))
    41  			})
    42  		})
    43  	})
    44  
    45  	When("the environment is not setup correctly", func() {
    46  		It("fails with the appropriate errors", func() {
    47  			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "app", appName)
    48  		})
    49  	})
    50  
    51  	When("the environment is set up correctly", func() {
    52  		BeforeEach(func() {
    53  			helpers.SetupCF(orgName, spaceName)
    54  		})
    55  
    56  		AfterEach(func() {
    57  			helpers.QuickDeleteOrg(orgName)
    58  		})
    59  
    60  		Describe("version dependent display", func() {
    61  			When("the app is created but not pushed", func() {
    62  				BeforeEach(func() {
    63  					Eventually(helpers.CF("v3-create-app", appName)).Should(Exit(0))
    64  				})
    65  
    66  				It("displays blank fields for unpopulated fields", func() {
    67  					session := helpers.CF("app", appName)
    68  					Eventually(session).Should(Say(`name:\s+%s`, appName))
    69  					Eventually(session).Should(Say(`requested state:\s+stopped`))
    70  					Eventually(session).Should(Say(`routes:\s+\n`))
    71  					Eventually(session).Should(Say(`last uploaded:\s+\n`))
    72  					Eventually(session).Should(Say(`stack:\s+\n`))
    73  					Eventually(session).Should(Say(`buildpacks:\s+\n`))
    74  					Eventually(session).Should(Exit(0))
    75  				})
    76  			})
    77  
    78  			When("the app is a buildpack app", func() {
    79  				var domainName string
    80  
    81  				BeforeEach(func() {
    82  					domainName = helpers.DefaultSharedDomain()
    83  				})
    84  
    85  				When("the app is started and has 2 instances", func() {
    86  					BeforeEach(func() {
    87  						helpers.WithHelloWorldApp(func(appDir string) {
    88  							manifestContents := []byte(fmt.Sprintf(`
    89  ---
    90  applications:
    91  - name: %s
    92    memory: 128M
    93    instances: 2
    94    disk_quota: 128M
    95    routes:
    96    - route: %s.%s
    97  `, appName, appName, domainName))
    98  							manifestPath := filepath.Join(appDir, "manifest.yml")
    99  							err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   100  							Expect(err).ToNot(HaveOccurred())
   101  
   102  							// Create manifest
   103  							Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   104  						})
   105  					})
   106  
   107  					// TODO: use multiprocess
   108  					It("uses the multiprocess display", func() {
   109  						userName, _ := helpers.GetCredentials()
   110  
   111  						session := helpers.CF("app", appName)
   112  
   113  						Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   114  
   115  						Eventually(session).ShouldNot(Say("This command is in EXPERIMENTAL stage and may change without notice"))
   116  						Eventually(session).Should(Say(`name:\s+%s`, appName))
   117  						Eventually(session).Should(Say(`requested state:\s+started`))
   118  						Eventually(session).Should(Say(`routes:\s+%s\.%s`, appName, domainName))
   119  						Eventually(session).Should(Say(`last uploaded:\s+\w{3} \d{1,2} \w{3} \d{2}:\d{2}:\d{2} \w{3} \d{4}`))
   120  						Eventually(session).Should(Say(`stack:\s+cflinuxfs`))
   121  						Eventually(session).Should(Say(`buildpacks:\s+staticfile`))
   122  						Eventually(session).Should(Say(`type:\s+web`))
   123  						Eventually(session).Should(Say(`instances:\s+\d/2`))
   124  						Eventually(session).Should(Say(`memory usage:\s+128M`))
   125  						Eventually(session).Should(Say(`\s+state\s+since\s+cpu\s+memory\s+disk\s+details`))
   126  						Eventually(session).Should(Say(`#0\s+(starting|running)\s+\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z`))
   127  
   128  						Eventually(session).Should(Exit(0))
   129  					})
   130  				})
   131  			})
   132  
   133  			When("the app is stopped", func() {
   134  				BeforeEach(func() {
   135  					helpers.WithHelloWorldApp(func(appDir string) {
   136  						Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   137  					})
   138  				})
   139  
   140  				It("displays that there are no running instances of the app", func() {
   141  					session := helpers.CF("app", appName)
   142  
   143  					userName, _ := helpers.GetCredentials()
   144  					Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   145  					Eventually(session).Should(Say(`name:\s+%s`, appName))
   146  					Eventually(session).Should(Say(`requested state:\s+stopped`))
   147  					Eventually(session).Should(Say(`type:\s+web`))
   148  					Eventually(session).Should(Say("#0\\s+down\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"))
   149  					Eventually(session).Should(Exit(0))
   150  				})
   151  			})
   152  
   153  			When("all instances of the app are down", func() {
   154  				BeforeEach(func() {
   155  					infiniteMemQuota := helpers.QuotaName()
   156  					Eventually(helpers.CF("create-quota", infiniteMemQuota, "-i", "-1", "-r", "-1", "-m", "2000G")).Should(Exit(0))
   157  					Eventually(helpers.CF("set-quota", orgName, infiniteMemQuota)).Should(Exit(0))
   158  					helpers.WithHelloWorldApp(func(appDir string) {
   159  						Eventually(helpers.CF("push", appName, "-p", appDir)).Should(Exit(0))
   160  					})
   161  					Eventually(helpers.CFWithEnv(map[string]string{"CF_STAGING_TIMEOUT": "0.1", "CF_STARTUP_TIMEOUT": "0.1"}, "scale", appName, "-m", "1000G", "-f")).Should(Exit(1))
   162  				})
   163  
   164  				It("displays the down app instances", func() {
   165  					session := helpers.CF("app", appName)
   166  					userName, _ := helpers.GetCredentials()
   167  					Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   168  					Eventually(session).Should(Say("name:\\s+%s", appName))
   169  					Eventually(session).Should(Say("requested state:\\s+started"))
   170  					Eventually(session).Should(Say("type:\\s+web"))
   171  					Eventually(session).Should(Say("#0\\s+down\\s+\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z"))
   172  					Eventually(session).Should(Exit(0))
   173  				})
   174  			})
   175  
   176  			When("the app has 0 instances", func() {
   177  				BeforeEach(func() {
   178  					helpers.WithHelloWorldApp(func(appDir string) {
   179  						Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-i", "0")).Should(Exit(0))
   180  					})
   181  				})
   182  
   183  				It("displays the app information", func() {
   184  					session := helpers.CF("app", appName)
   185  					userName, _ := helpers.GetCredentials()
   186  
   187  					Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName))
   188  					Eventually(session).Should(Say(`name:\s+%s`, appName))
   189  					Eventually(session).Should(Say(`requested state:\s+started`))
   190  					Eventually(session).Should(Say(`type:\s+web`))
   191  					Eventually(session).Should(Say("There are no running instances of this process"))
   192  					Eventually(session).Should(Exit(0))
   193  				})
   194  			})
   195  
   196  			When("the --guid flag is given", func() {
   197  				var appGUID string
   198  
   199  				BeforeEach(func() {
   200  					helpers.WithHelloWorldApp(func(appDir string) {
   201  						Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   202  					})
   203  
   204  					var AppInfo struct {
   205  						Resources []struct {
   206  							GUID string `json:"guid"`
   207  						} `json:"resources"`
   208  					}
   209  
   210  					helpers.Curl(&AppInfo, "/v3/apps?names=%s", appName)
   211  					appGUID = AppInfo.Resources[0].GUID
   212  				})
   213  
   214  				It("displays the app guid", func() {
   215  					session := helpers.CF("app", "--guid", appName)
   216  					Eventually(session).Should(Say(appGUID))
   217  					Eventually(session).Should(Exit(0))
   218  				})
   219  			})
   220  
   221  			When("the app uses multiple buildpacks", func() {
   222  				BeforeEach(func() {
   223  					helpers.WithMultiBuildpackApp(func(appDir string) {
   224  						Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "ruby_buildpack", "-b", "go_buildpack")).Should(Exit(0))
   225  					})
   226  				})
   227  
   228  				It("displays the app buildpacks", func() {
   229  					session := helpers.CF("app", appName)
   230  					Eventually(session).Should(Say(`buildpacks:\s+ruby_buildpack,\s+go`))
   231  					Eventually(session).Should(Exit(0))
   232  				})
   233  			})
   234  		})
   235  
   236  		Describe("version independent display", func() {
   237  			When("the app name is not provided", func() {
   238  				It("tells the user that the app name is required, prints help text, and exits 1", func() {
   239  					session := helpers.CF("app")
   240  
   241  					Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
   242  					Eventually(session).Should(Say("NAME:"))
   243  					Eventually(session).Should(Exit(1))
   244  				})
   245  			})
   246  
   247  			When("the app does not exist", func() {
   248  				When("no flags are given", func() {
   249  					It("tells the user that the app is not found and exits 1", func() {
   250  						session := helpers.CF("app", appName)
   251  
   252  						Eventually(session).Should(Say("FAILED"))
   253  						Eventually(session.Err).Should(Say("App '%s' not found", appName))
   254  						Eventually(session).Should(Exit(1))
   255  					})
   256  				})
   257  
   258  				When("the --guid flag is given", func() {
   259  					It("tells the user that the app is not found and exits 1", func() {
   260  						session := helpers.CF("app", "--guid", appName)
   261  
   262  						Eventually(session).Should(Say("FAILED"))
   263  						Eventually(session.Err).Should(Say("App '%s' not found", appName))
   264  						Eventually(session).Should(Exit(1))
   265  					})
   266  				})
   267  			})
   268  
   269  			When("the app exists", func() {
   270  				When("isolation segments are available", func() {
   271  					BeforeEach(func() {
   272  						Eventually(helpers.CF("create-isolation-segment", RealIsolationSegment)).Should(Exit(0))
   273  						Eventually(helpers.CF("enable-org-isolation", orgName, RealIsolationSegment)).Should(Exit(0))
   274  						Eventually(helpers.CF("set-space-isolation-segment", spaceName, RealIsolationSegment)).Should(Exit(0))
   275  
   276  						helpers.WithHelloWorldApp(func(appDir string) {
   277  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack")).Should(Exit(0))
   278  						})
   279  					})
   280  
   281  					It("displays the app isolation segment information", func() {
   282  						session := helpers.CF("app", appName)
   283  
   284  						Eventually(session).Should(Say(`isolation segment:\s+%s`, RealIsolationSegment))
   285  						Eventually(session).Should(Exit(0))
   286  					})
   287  				})
   288  
   289  				When("isolation segment is not set for the application", func() {
   290  					BeforeEach(func() {
   291  						helpers.WithHelloWorldApp(func(appDir string) {
   292  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack")).Should(Exit(0))
   293  						})
   294  					})
   295  
   296  					It("displays the app isolation segment information", func() {
   297  						session := helpers.CF("app", appName)
   298  
   299  						Consistently(session).ShouldNot(Say("isolation segment:"))
   300  						Eventually(session).Should(Exit(0))
   301  					})
   302  				})
   303  
   304  				When("the app is a Docker app", func() {
   305  					BeforeEach(func() {
   306  						Eventually(helpers.CF("push", appName, "-o", DockerImage)).Should(Exit())
   307  					})
   308  
   309  					It("displays the docker image", func() {
   310  						session := helpers.CF("app", appName)
   311  						Eventually(session).Should(Say(`name:\s+%s`, appName))
   312  						Eventually(session).Should(Say(`docker image:\s+%s`, DockerImage))
   313  						Eventually(session).Should(Exit(0))
   314  					})
   315  
   316  					It("does not display buildpack", func() {
   317  						session := helpers.CF("app", appName)
   318  						Consistently(session).ShouldNot(Say("buildpacks?:"))
   319  						Eventually(session).Should(Exit(0))
   320  					})
   321  				})
   322  
   323  				When("the app has tcp routes", func() {
   324  					var tcpDomain helpers.Domain
   325  
   326  					BeforeEach(func() {
   327  						tcpDomain = helpers.NewDomain(orgName, helpers.NewDomainName("tcp"))
   328  						tcpDomain.CreateWithRouterGroup(helpers.FindOrCreateTCPRouterGroup(GinkgoParallelNode()))
   329  						helpers.WithHelloWorldApp(func(appDir string) {
   330  							manifestContents := []byte(fmt.Sprintf(`
   331  ---
   332  applications:
   333  - name: %s
   334    routes:
   335    - route: %s:1024
   336  `, appName, tcpDomain.Name))
   337  							manifestPath := filepath.Join(appDir, "manifest.yml")
   338  							err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   339  							Expect(err).ToNot(HaveOccurred())
   340  
   341  							// Create manifest
   342  							Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   343  						})
   344  
   345  						It("displays the app information", func() {
   346  							session := helpers.CF("app", appName)
   347  							Eventually(session).Should(Say(`routes:\s+[\w\d-]+\.%s`, tcpDomain))
   348  							Eventually(session).Should(Exit(0))
   349  						})
   350  					})
   351  				})
   352  			})
   353  		})
   354  	})
   355  })