github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/integration/isolated/app_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"path/filepath"
     8  	"strings"
     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  )
    17  
    18  var _ = Describe("app command", func() {
    19  	Describe("help", func() {
    20  		Context("when --help flag is set", func() {
    21  			It("Displays command usage to output", func() {
    22  				session := helpers.CF("app", "--help")
    23  				Eventually(session).Should(Say("NAME:"))
    24  				Eventually(session).Should(Say("app - Display health and status for an app"))
    25  				Eventually(session).Should(Say("USAGE:"))
    26  				Eventually(session).Should(Say("cf app APP_NAME"))
    27  				Eventually(session).Should(Say("OPTIONS:"))
    28  				Eventually(session).Should(Say("--guid      Retrieve and display the given app's guid.  All other health and status output for the app is suppressed."))
    29  				Eventually(session).Should(Say("SEE ALSO:"))
    30  				Eventually(session).Should(Say("apps, events, logs, map-route, push, unmap-route"))
    31  				Eventually(session).Should(Exit(0))
    32  			})
    33  		})
    34  	})
    35  
    36  	Context("when the environment is not setup correctly", func() {
    37  		It("fails with the appropriate errors", func() {
    38  			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "app", "some-app")
    39  		})
    40  	})
    41  
    42  	Context("when the environment is set up correctly", func() {
    43  		var (
    44  			orgName   string
    45  			spaceName string
    46  		)
    47  
    48  		BeforeEach(func() {
    49  			orgName = helpers.NewOrgName()
    50  			spaceName = helpers.NewSpaceName()
    51  
    52  			helpers.SetupCF(orgName, spaceName)
    53  		})
    54  
    55  		AfterEach(func() {
    56  			helpers.QuickDeleteOrg(orgName)
    57  		})
    58  
    59  		Context("when the app name is not provided", func() {
    60  			It("tells the user that the app name is required, prints help text, and exits 1", func() {
    61  				session := helpers.CF("app")
    62  
    63  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided"))
    64  				Eventually(session).Should(Say("NAME:"))
    65  				Eventually(session).Should(Exit(1))
    66  			})
    67  		})
    68  
    69  		Context("when the app does not exist", func() {
    70  			Context("when no flags are given", func() {
    71  				It("tells the user that the app is not found and exits 1", func() {
    72  					appName := helpers.PrefixedRandomName("app")
    73  					session := helpers.CF("app", appName)
    74  
    75  					Eventually(session).Should(Say("FAILED"))
    76  					Eventually(session.Err).Should(Say("App %s not found", appName))
    77  					Eventually(session).Should(Exit(1))
    78  				})
    79  			})
    80  
    81  			Context("when the --guid flag is given", func() {
    82  				It("tells the user that the app is not found and exits 1", func() {
    83  					appName := helpers.PrefixedRandomName("app")
    84  					session := helpers.CF("app", "--guid", appName)
    85  
    86  					Eventually(session).Should(Say("FAILED"))
    87  					Eventually(session.Err).Should(Say("App %s not found", appName))
    88  					Eventually(session).Should(Exit(1))
    89  				})
    90  			})
    91  		})
    92  
    93  		Context("when the app does exist", func() {
    94  			Context("when the app is a buildpack app", func() {
    95  				var (
    96  					domainName string
    97  					appName    string
    98  				)
    99  
   100  				BeforeEach(func() {
   101  					appName = helpers.PrefixedRandomName("app")
   102  					domainName = helpers.DefaultSharedDomain()
   103  				})
   104  
   105  				Context("when the app is started and has 2 instances", func() {
   106  					BeforeEach(func() {
   107  						helpers.WithHelloWorldApp(func(appDir string) {
   108  							manifestContents := []byte(fmt.Sprintf(`
   109  ---
   110  applications:
   111  - name: %s
   112    memory: 128M
   113    instances: 2
   114    disk_quota: 128M
   115    routes:
   116    - route: %s.%s
   117  `, appName, appName, domainName))
   118  							manifestPath := filepath.Join(appDir, "manifest.yml")
   119  							err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   120  							Expect(err).ToNot(HaveOccurred())
   121  
   122  							// Create manifest
   123  							Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   124  						})
   125  					})
   126  
   127  					It("displays the app information with instances table", func() {
   128  						session := helpers.CF("app", appName)
   129  						Eventually(session).Should(Say("name:\\s+%s", appName))
   130  						Eventually(session).Should(Say("requested state:\\s+started"))
   131  						Eventually(session).Should(Say("instances:\\s+2/2"))
   132  						Eventually(session).Should(Say("usage:\\s+128M x 2 instances"))
   133  						Eventually(session).Should(Say("routes:\\s+[\\w\\d-]+\\.%s", domainName))
   134  						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}"))
   135  						Eventually(session).Should(Say("stack:\\s+cflinuxfs2"))
   136  						Eventually(session).Should(Say("buildpack:\\s+staticfile_buildpack"))
   137  						Eventually(session).Should(Say(""))
   138  						Eventually(session).Should(Say("state\\s+since\\s+cpu\\s+memory\\s+disk\\s+details"))
   139  						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"))
   140  						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"))
   141  						Eventually(session).Should(Exit(0))
   142  					})
   143  				})
   144  
   145  				Context("when isolation segments are available", func() {
   146  					BeforeEach(func() {
   147  						helpers.SkipIfVersionLessThan(ccversion.MinVersionIsolationSegmentV3)
   148  
   149  						Eventually(helpers.CF("create-isolation-segment", RealIsolationSegment)).Should(Exit(0))
   150  						Eventually(helpers.CF("enable-org-isolation", orgName, RealIsolationSegment)).Should(Exit(0))
   151  						Eventually(helpers.CF("set-space-isolation-segment", spaceName, RealIsolationSegment)).Should(Exit(0))
   152  
   153  						helpers.WithHelloWorldApp(func(appDir string) {
   154  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack")).Should(Exit(0))
   155  						})
   156  					})
   157  
   158  					It("displays the app isolation segment information", func() {
   159  						session := helpers.CF("app", appName)
   160  
   161  						Eventually(session).Should(Say("isolation segment:\\s+%s", RealIsolationSegment))
   162  						Eventually(session).Should(Exit(0))
   163  					})
   164  				})
   165  
   166  				Context("when the app is stopped", func() {
   167  					BeforeEach(func() {
   168  						helpers.WithHelloWorldApp(func(appDir string) {
   169  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   170  						})
   171  					})
   172  
   173  					It("displays the app information", func() {
   174  						session := helpers.CF("app", appName)
   175  						Eventually(session).Should(Say("name:\\s+%s", appName))
   176  						Eventually(session).Should(Say("requested state:\\s+stopped"))
   177  						Eventually(session).Should(Say("instances:\\s+0/1"))
   178  						Eventually(session).Should(Say("usage:\\s+\\d+M x 1 instances"))
   179  
   180  						Eventually(session).Should(Say("There are no running instances of this app."))
   181  						Eventually(session).Should(Exit(0))
   182  					})
   183  				})
   184  
   185  				Context("when the app has 0 instances", func() {
   186  					BeforeEach(func() {
   187  						helpers.SkipIfVersionLessThan(ccversion.MinVersionZeroAppInstancesV2)
   188  						helpers.WithHelloWorldApp(func(appDir string) {
   189  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "-i", "0")).Should(Exit(0))
   190  						})
   191  					})
   192  
   193  					It("displays the app information", func() {
   194  						session := helpers.CF("app", appName)
   195  						Eventually(session).Should(Say("name:\\s+%s", appName))
   196  						Eventually(session).Should(Say("requested state:\\s+started"))
   197  						Eventually(session).Should(Say("instances:\\s+0/0"))
   198  						Eventually(session).Should(Say("usage:\\s+\\d+M x 0 instances"))
   199  
   200  						Eventually(session).Should(Say("There are no running instances of this app."))
   201  						Eventually(session).Should(Exit(0))
   202  					})
   203  				})
   204  
   205  				Context("when the --guid flag is given", func() {
   206  					var appGUID string
   207  
   208  					BeforeEach(func() {
   209  						helpers.WithHelloWorldApp(func(appDir string) {
   210  							Eventually(helpers.CF("push", appName, "-p", appDir, "-b", "staticfile_buildpack", "--no-start")).Should(Exit(0))
   211  						})
   212  
   213  						session := helpers.CF("curl", fmt.Sprintf("/v2/apps?q=name:%s", appName))
   214  						Eventually(session).Should(Exit(0))
   215  						rawJSON := strings.TrimSpace(string(session.Out.Contents()))
   216  						var AppInfo struct {
   217  							Resources []struct {
   218  								Metadata struct {
   219  									GUID string `json:"guid"`
   220  								} `json:"metadata"`
   221  							} `json:"resources"`
   222  						}
   223  
   224  						err := json.Unmarshal([]byte(rawJSON), &AppInfo)
   225  						Expect(err).NotTo(HaveOccurred())
   226  
   227  						appGUID = AppInfo.Resources[0].Metadata.GUID
   228  					})
   229  
   230  					It("displays the app guid", func() {
   231  						session := helpers.CF("app", "--guid", appName)
   232  						Eventually(session).Should(Say(appGUID))
   233  						Eventually(session).Should(Exit(0))
   234  					})
   235  				})
   236  			})
   237  
   238  			Context("when the app is a Docker app", func() {
   239  				var (
   240  					appName string
   241  				)
   242  
   243  				BeforeEach(func() {
   244  					appName = helpers.PrefixedRandomName("app")
   245  					domainName := helpers.DefaultSharedDomain()
   246  					Eventually(helpers.CF("push", appName, "-o", DockerImage, "-d", domainName)).Should(Exit())
   247  				})
   248  
   249  				It("displays the docker image and does not display buildpack", func() {
   250  					session := helpers.CF("app", appName)
   251  					Eventually(session).Should(Say("name:\\s+%s", appName))
   252  					Consistently(session).ShouldNot(Say("buildpack:"))
   253  					Eventually(session).Should(Say("docker image:\\s+%s", DockerImage))
   254  					Consistently(session).ShouldNot(Say("buildpack:"))
   255  					Eventually(session).Should(Exit(0))
   256  				})
   257  			})
   258  
   259  			Context("when the app has tcp routes", func() {
   260  				var (
   261  					appName   string
   262  					tcpDomain helpers.Domain
   263  				)
   264  
   265  				BeforeEach(func() {
   266  					helpers.SkipIfVersionLessThan(ccversion.MinVersionRoutingV3)
   267  
   268  					appName = helpers.PrefixedRandomName("app")
   269  					tcpDomain = helpers.NewDomain(orgName, helpers.DomainName("tcp"))
   270  					tcpDomain.CreateWithRouterGroup(helpers.FindOrCreateTCPRouterGroup(GinkgoParallelNode()))
   271  					helpers.WithHelloWorldApp(func(appDir string) {
   272  						manifestContents := []byte(fmt.Sprintf(`
   273  ---
   274  applications:
   275  - name: %s
   276    routes:
   277    - route: %s:1024
   278  `, appName, tcpDomain.Name))
   279  						manifestPath := filepath.Join(appDir, "manifest.yml")
   280  						err := ioutil.WriteFile(manifestPath, manifestContents, 0666)
   281  						Expect(err).ToNot(HaveOccurred())
   282  
   283  						// Create manifest
   284  						Eventually(helpers.CF("push", appName, "-p", appDir, "-f", manifestPath, "-b", "staticfile_buildpack")).Should(Exit(0))
   285  					})
   286  
   287  					It("displays the app information", func() {
   288  						session := helpers.CF("app", appName)
   289  						Eventually(session).Should(Say("routes:\\s+[\\w\\d-]+\\.%s", tcpDomain))
   290  					})
   291  				})
   292  			})
   293  		})
   294  	})
   295  })