github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/integration/experimental/v3_app_command_test.go (about) 1 package experimental 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 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 . "github.com/onsi/gomega/ghttp" 14 ) 15 16 var _ = Describe("v3-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 Context("when --help flag is set", func() { 31 It("Displays command usage to output", func() { 32 session := helpers.CF("v3-app", "--help") 33 34 Eventually(session).Should(Say("NAME:")) 35 Eventually(session).Should(Say("v3-app - Display health and status for an app")) 36 Eventually(session).Should(Say("USAGE:")) 37 Eventually(session).Should(Say("cf v3-app APP_NAME [--guid]")) 38 Eventually(session).Should(Say("OPTIONS:")) 39 Eventually(session).Should(Say("--guid\\s+Retrieve and display the given app's guid. All other health and status output for the app is suppressed.")) 40 41 Eventually(session).Should(Exit(0)) 42 }) 43 }) 44 }) 45 46 Context("when the app name is not provided", func() { 47 It("tells the user that the app name is required, prints help text, and exits 1", func() { 48 session := helpers.CF("v3-app") 49 50 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided")) 51 Eventually(session).Should(Say("NAME:")) 52 Eventually(session).Should(Exit(1)) 53 }) 54 }) 55 56 It("displays the experimental warning", func() { 57 session := helpers.CF("v3-app", appName) 58 Eventually(session).Should(Say("This command is in EXPERIMENTAL stage and may change without notice")) 59 Eventually(session).Should(Exit()) 60 }) 61 62 Context("when the environment is not setup correctly", func() { 63 Context("when no API endpoint is set", func() { 64 BeforeEach(func() { 65 helpers.UnsetAPI() 66 }) 67 68 It("fails with no API endpoint set message", func() { 69 session := helpers.CF("v3-app", appName) 70 Eventually(session).Should(Say("FAILED")) 71 Eventually(session.Err).Should(Say("No API endpoint set\\. Use 'cf login' or 'cf api' to target an endpoint\\.")) 72 Eventually(session).Should(Exit(1)) 73 }) 74 }) 75 76 Context("when the v3 api does not exist", func() { 77 var server *Server 78 79 BeforeEach(func() { 80 server = helpers.StartAndTargetServerWithoutV3API() 81 }) 82 83 AfterEach(func() { 84 server.Close() 85 }) 86 87 It("fails with error message that the minimum version is not met", func() { 88 session := helpers.CF("v3-app", appName) 89 Eventually(session).Should(Say("FAILED")) 90 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.27\\.0 or higher\\.")) 91 Eventually(session).Should(Exit(1)) 92 }) 93 }) 94 95 Context("when the v3 api version is lower than the minimum version", func() { 96 var server *Server 97 98 BeforeEach(func() { 99 server = helpers.StartAndTargetServerWithV3Version("3.0.0") 100 }) 101 102 AfterEach(func() { 103 server.Close() 104 }) 105 106 It("fails with error message that the minimum version is not met", func() { 107 session := helpers.CF("v3-app", appName) 108 Eventually(session).Should(Say("FAILED")) 109 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.27\\.0 or higher\\.")) 110 Eventually(session).Should(Exit(1)) 111 }) 112 }) 113 114 Context("when not logged in", func() { 115 BeforeEach(func() { 116 helpers.LogoutCF() 117 }) 118 119 It("fails with not logged in message", func() { 120 session := helpers.CF("v3-app", appName) 121 Eventually(session).Should(Say("FAILED")) 122 Eventually(session.Err).Should(Say("Not logged in\\. Use 'cf login' to log in\\.")) 123 Eventually(session).Should(Exit(1)) 124 }) 125 }) 126 127 Context("when there is no org set", func() { 128 BeforeEach(func() { 129 helpers.LogoutCF() 130 helpers.LoginCF() 131 }) 132 133 It("fails with no org targeted error message", func() { 134 session := helpers.CF("v3-app", appName) 135 Eventually(session).Should(Say("FAILED")) 136 Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org\\.")) 137 Eventually(session).Should(Exit(1)) 138 }) 139 }) 140 141 Context("when there is no space set", func() { 142 BeforeEach(func() { 143 helpers.LogoutCF() 144 helpers.LoginCF() 145 helpers.TargetOrg(ReadOnlyOrg) 146 }) 147 148 It("fails with no space targeted error message", func() { 149 session := helpers.CF("v3-app", appName) 150 Eventually(session).Should(Say("FAILED")) 151 Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space\\.")) 152 Eventually(session).Should(Exit(1)) 153 }) 154 }) 155 }) 156 157 Context("when the environment is set up correctly", func() { 158 BeforeEach(func() { 159 setupCF(orgName, spaceName) 160 }) 161 162 AfterEach(func() { 163 helpers.QuickDeleteOrg(orgName) 164 }) 165 166 Context("when the app exists", func() { 167 var domainName string 168 169 BeforeEach(func() { 170 helpers.WithHelloWorldApp(func(appDir string) { 171 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v3-push", appName)).Should(Exit(0)) 172 }) 173 174 domainName = defaultSharedDomain() 175 }) 176 177 It("displays the app summary", func() { 178 userName, _ := helpers.GetCredentials() 179 180 session := helpers.CF("v3-app", appName) 181 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 182 183 Eventually(session).Should(Say("name:\\s+%s", appName)) 184 Eventually(session).Should(Say("requested state:\\s+started")) 185 Eventually(session).Should(Say("processes:\\s+web:1/1")) 186 Eventually(session).Should(Say("memory usage:\\s+\\d+[KMG] x 1")) 187 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 188 Eventually(session).Should(Say("stack:\\s+cflinuxfs2")) 189 Eventually(session).Should(Say("buildpacks:\\s+staticfile")) 190 Eventually(session).Should(Say("web:1/1")) 191 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 192 193 Eventually(session).Should(Exit(0)) 194 }) 195 196 Context("when the app is stopped", func() { 197 BeforeEach(func() { 198 Eventually(helpers.CF("stop", appName)).Should(Exit(0)) 199 }) 200 201 It("displays that there are no running instances of the app", func() { 202 userName, _ := helpers.GetCredentials() 203 204 session := helpers.CF("v3-app", appName) 205 206 Eventually(session).Should(Say(`Showing health and status for app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 207 Consistently(session).ShouldNot(Say(`state\s+since\s+cpu\s+memory\s+disk`)) 208 Eventually(session).Should(Say("There are no running instances of this app")) 209 Eventually(session).Should(Exit(0)) 210 }) 211 }) 212 213 Context("when the --guid flag is given", func() { 214 var appGUID string 215 216 BeforeEach(func() { 217 session := helpers.CF("curl", fmt.Sprintf("/v3/apps?names=%s", appName)) 218 Eventually(session).Should(Exit(0)) 219 rawJSON := strings.TrimSpace(string(session.Out.Contents())) 220 var AppInfo struct { 221 Resources []struct { 222 GUID string `json:"guid"` 223 } `json:"resources"` 224 } 225 226 err := json.Unmarshal([]byte(rawJSON), &AppInfo) 227 Expect(err).NotTo(HaveOccurred()) 228 229 appGUID = AppInfo.Resources[0].GUID 230 }) 231 232 It("displays the app guid", func() { 233 session := helpers.CF("v3-app", "--guid", appName) 234 Eventually(session).Should(Say(appGUID)) 235 Eventually(session).Should(Exit(0)) 236 }) 237 }) 238 }) 239 240 Context("when the app is a docker app", func() { 241 var domainName string 242 243 BeforeEach(func() { 244 Eventually(helpers.CF("v3-push", appName, "-o", PublicDockerImage)).Should(Exit(0)) 245 domainName = defaultSharedDomain() 246 }) 247 248 It("displays the app summary", func() { 249 userName, _ := helpers.GetCredentials() 250 251 session := helpers.CF("v3-app", appName) 252 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 253 254 Eventually(session).Should(Say("name:\\s+%s", appName)) 255 Eventually(session).Should(Say("requested state:\\s+started")) 256 Eventually(session).Should(Say("processes:\\s+web:1/1")) 257 Eventually(session).Should(Say("memory usage:\\s+\\d+[KMG] x 1")) 258 Eventually(session).Should(Say("routes:\\s+%s\\.%s", appName, domainName)) 259 Eventually(session).Should(Say("stack:\\s+")) 260 Eventually(session).Should(Say("docker image:\\s+cloudfoundry/diego-docker-app-custom")) 261 Eventually(session).Should(Say("web:1/1")) 262 Eventually(session).Should(Say("#0\\s+running\\s+\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2} [AP]M")) 263 264 Eventually(session).Should(Exit(0)) 265 }) 266 }) 267 268 Context("when the app does not exist", func() { 269 It("displays app not found and exits 1", func() { 270 invalidAppName := "invalid-app-name" 271 session := helpers.CF("v3-app", invalidAppName) 272 userName, _ := helpers.GetCredentials() 273 274 Eventually(session).Should(Say("Showing health and status for app %s in org %s / space %s as %s\\.\\.\\.", invalidAppName, orgName, spaceName, userName)) 275 Eventually(session.Err).Should(Say("App %s not found", invalidAppName)) 276 Eventually(session).Should(Say("FAILED")) 277 278 Eventually(session).Should(Exit(1)) 279 }) 280 281 Context("when the --guid flag is given", func() { 282 It("tells the user that the app is not found and exits 1", func() { 283 appName := helpers.PrefixedRandomName("invalid-app") 284 session := helpers.CF("v3-app", "--guid", appName) 285 286 Eventually(session).Should(Say("FAILED")) 287 Eventually(session.Err).Should(Say("App %s not found", appName)) 288 Eventually(session).Should(Exit(1)) 289 }) 290 }) 291 }) 292 }) 293 })