github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/integration/v7/isolated/restart_command_test.go (about) 1 package isolated 2 3 import ( 4 "regexp" 5 6 . "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers" 7 "code.cloudfoundry.org/cli/integration/helpers" 8 . "github.com/onsi/ginkgo" 9 . "github.com/onsi/gomega" 10 . "github.com/onsi/gomega/gbytes" 11 . "github.com/onsi/gomega/gexec" 12 ) 13 14 var _ = Describe("restart command", func() { 15 16 const ( 17 instanceStatsTitles = `\s+state\s+since\s+cpu\s+memory\s+disk\s+logging\s+details` 18 instanceStatsValues = `#0\s+(starting|running)\s+\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z` 19 ) 20 21 var ( 22 orgName string 23 spaceName string 24 appName string 25 ) 26 27 BeforeEach(func() { 28 orgName = helpers.NewOrgName() 29 spaceName = helpers.NewSpaceName() 30 appName = helpers.PrefixedRandomName("app") 31 }) 32 33 Describe("help", func() { 34 When("--help flag is set", func() { 35 It("appears in cf help -a", func() { 36 session := helpers.CF("help", "-a") 37 Eventually(session).Should(Exit(0)) 38 Expect(session).To(HaveCommandInCategoryWithDescription("restart", "APPS", "Stop all instances of the app, then start them again.")) 39 }) 40 41 It("displays command usage to output", func() { 42 session := helpers.CF("restart", "--help") 43 44 Eventually(session).Should(Say("NAME:")) 45 Eventually(session).Should(Say(`restart - Stop all instances of the app, then start them again\.`)) 46 Eventually(session).Should(Say("USAGE:")) 47 Eventually(session).Should(Say("cf restart APP_NAME")) 48 Eventually(session).Should(Say("This command will cause downtime unless you use '--strategy rolling'.")) 49 Eventually(session).Should(Say("If the app's most recent package is unstaged, restarting the app will stage and run that package.")) 50 Eventually(session).Should(Say("Otherwise, the app's current droplet will be run.")) 51 Eventually(session).Should(Say("ALIAS:")) 52 Eventually(session).Should(Say("rs")) 53 Eventually(session).Should(Say("OPTIONS:")) 54 Eventually(session).Should(Say("--strategy Deployment strategy, either rolling or null")) 55 Eventually(session).Should(Say("--no-wait Exit when the first instance of the web process is healthy")) 56 Eventually(session).Should(Say("ENVIRONMENT:")) 57 Eventually(session).Should(Say(`CF_STAGING_TIMEOUT=15\s+Max wait time for staging, in minutes`)) 58 Eventually(session).Should(Say(`CF_STARTUP_TIMEOUT=5\s+Max wait time for app instance startup, in minutes`)) 59 Eventually(session).Should(Say("SEE ALSO:")) 60 Eventually(session).Should(Say("restage, restart-app-instance")) 61 62 Eventually(session).Should(Exit(0)) 63 }) 64 }) 65 }) 66 67 When("the app name is not provided", func() { 68 It("tells the user that the app name is required, prints help text, and exits 1", func() { 69 session := helpers.CF("restart") 70 71 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided")) 72 Eventually(session).Should(Say("NAME:")) 73 Eventually(session).Should(Exit(1)) 74 }) 75 }) 76 77 When("the environment is not setup correctly", func() { 78 It("fails with the appropriate errors", func() { 79 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "restart", appName) 80 }) 81 }) 82 83 When("the environment is set up correctly", func() { 84 var ( 85 userName string 86 ) 87 BeforeEach(func() { 88 helpers.SetupCF(orgName, spaceName) 89 userName, _ = helpers.GetCredentials() 90 }) 91 92 AfterEach(func() { 93 helpers.QuickDeleteOrg(orgName) 94 }) 95 96 When("the app exists", func() { 97 When("strategy rolling is given", func() { 98 BeforeEach(func() { 99 helpers.WithHelloWorldApp(func(appDir string) { 100 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName)).Should(Exit(0)) 101 }) 102 }) 103 It("creates a deploy", func() { 104 session := helpers.CF("restart", appName, "--strategy=rolling") 105 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 106 Eventually(session).Should(Say(`Creating deployment for app %s\.\.\.`, appName)) 107 Eventually(session).Should(Say(`Waiting for app to deploy\.\.\.`)) 108 Eventually(session).Should(Say(`name:\s+%s`, appName)) 109 Eventually(session).Should(Say(`requested state:\s+started`)) 110 Eventually(session).Should(Say(`routes:\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 111 Eventually(session).Should(Say(`type:\s+web`)) 112 Eventually(session).Should(Say(`instances:\s+1/1`)) 113 Eventually(session).Should(Say(`memory usage:\s+\d+(M|G)`)) 114 Eventually(session).Should(Say(instanceStatsTitles)) 115 Eventually(session).Should(Say(instanceStatsValues)) 116 }) 117 }) 118 119 When("the app is running with no new packages", func() { 120 BeforeEach(func() { 121 helpers.WithHelloWorldApp(func(appDir string) { 122 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName)).Should(Exit(0)) 123 }) 124 }) 125 126 It("stops then restarts the app, without staging a package", func() { 127 session := helpers.CF("restart", appName) 128 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 129 Eventually(session).Should(Say(`Stopping app\.\.\.`)) 130 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 131 Eventually(session).Should(Say(`name:\s+%s`, appName)) 132 Eventually(session).Should(Say(`requested state:\s+started`)) 133 Eventually(session).Should(Say(`routes:\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 134 Eventually(session).Should(Say(`type:\s+web`)) 135 Eventually(session).Should(Say(`instances:\s+1/1`)) 136 Eventually(session).Should(Say(`memory usage:\s+\d+(M|G)`)) 137 Eventually(session).Should(Say(instanceStatsTitles)) 138 Eventually(session).Should(Say(instanceStatsValues)) 139 140 Expect(session.Out.Contents()).NotTo(ContainSubstring("Staging app and tracing logs...")) 141 142 Eventually(session).Should(Exit(0)) 143 Expect(session.Err).ToNot(Say(`timeout connecting to log server, no log will be shown`)) 144 }) 145 }) 146 147 When("the app is running with a new packages", func() { 148 BeforeEach(func() { 149 helpers.WithHelloWorldApp(func(appDir string) { 150 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName)).Should(Exit(0)) 151 }) 152 helpers.WithHelloWorldApp(func(appDir string) { 153 pkgSession := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "create-package", appName) 154 Eventually(pkgSession).Should(Exit(0)) 155 regex := regexp.MustCompile(`Package with guid '(.+)' has been created\.`) 156 matches := regex.FindStringSubmatch(string(pkgSession.Out.Contents())) 157 Expect(matches).To(HaveLen(2)) 158 }) 159 }) 160 161 It("stages the new package, stops then restarts the app", func() { 162 session := helpers.CF("restart", appName) 163 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 164 165 Eventually(session).Should(Say("Staging app and tracing logs...")) 166 Eventually(session).Should(Say(`Stopping app\.\.\.`)) 167 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 168 Eventually(session).Should(Say(`name:\s+%s`, appName)) 169 Eventually(session).Should(Say(`requested state:\s+started`)) 170 Eventually(session).Should(Say(`routes:\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 171 Eventually(session).Should(Say(`type:\s+web`)) 172 Eventually(session).Should(Say(`instances:\s+1/1`)) 173 Eventually(session).Should(Say(`memory usage:\s+\d+(M|G)`)) 174 Eventually(session).Should(Say(instanceStatsTitles)) 175 Eventually(session).Should(Say(instanceStatsValues)) 176 177 Eventually(session).Should(Exit(0)) 178 Expect(session.Err).ToNot(Say(`timeout connecting to log server, no log will be shown`)) 179 }) 180 }) 181 182 When("the app is stopped", func() { 183 When("the app does not have a new package, and has a current droplet", func() { 184 BeforeEach(func() { 185 helpers.WithHelloWorldApp(func(appDir string) { 186 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName)).Should(Exit(0)) 187 }) 188 Eventually(helpers.CF("stop", appName)).Should(Exit(0)) 189 }) 190 191 It("starts the app", func() { 192 193 session := helpers.CF("restart", appName) 194 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 195 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 196 Eventually(session).Should(Say(`name:\s+%s`, appName)) 197 Eventually(session).Should(Say(`requested state:\s+started`)) 198 Eventually(session).Should(Say(`routes:\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 199 Eventually(session).Should(Say(`type:\s+web`)) 200 Eventually(session).Should(Say(`instances:\s+1/1`)) 201 Eventually(session).Should(Say(`memory usage:\s+\d+(M|G)`)) 202 Eventually(session).Should(Say(instanceStatsTitles)) 203 Eventually(session).Should(Say(instanceStatsValues)) 204 205 Expect(session.Out.Contents()).NotTo(ContainSubstring("Staging app and tracing logs...")) 206 Expect(session.Out.Contents()).NotTo(ContainSubstring("Stopping app...")) 207 208 Eventually(session).Should(Exit(0)) 209 }) 210 }) 211 212 When("the app has a new package", func() { 213 BeforeEach(func() { 214 helpers.WithHelloWorldApp(func(appDir string) { 215 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-start")).Should(Exit(0)) 216 }) 217 }) 218 219 It("stages the new package and starts the app", func() { 220 221 session := helpers.CF("restart", appName) 222 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 223 Eventually(session).Should(Say("Staging app and tracing logs...")) 224 Eventually(session).Should(Say(`Waiting for app to start\.\.\.`)) 225 Eventually(session).Should(Say(`name:\s+%s`, appName)) 226 Eventually(session).Should(Say(`requested state:\s+started`)) 227 Eventually(session).Should(Say(`routes:\s+%s.%s`, appName, helpers.DefaultSharedDomain())) 228 Eventually(session).Should(Say(`type:\s+web`)) 229 Eventually(session).Should(Say(`instances:\s+1/1`)) 230 Eventually(session).Should(Say(`memory usage:\s+\d+(M|G)`)) 231 Eventually(session).Should(Say(instanceStatsTitles)) 232 Eventually(session).Should(Say(instanceStatsValues)) 233 234 Expect(session.Out.Contents()).NotTo(ContainSubstring("Stopping app...")) 235 236 Eventually(session).Should(Exit(0)) 237 }) 238 }) 239 240 When("the app does *not* have a ready package or current droplet", func() { 241 BeforeEach(func() { 242 Eventually(helpers.CF("create-app", appName)).Should(Exit(0)) 243 }) 244 245 It("complains about not having a droplet", func() { 246 247 session := helpers.CF("restart", appName) 248 Eventually(session).Should(Say(`Restarting app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 249 Eventually(session.Err).Should(Say(`App cannot start without a package to stage or a droplet to run\.`)) 250 Eventually(session).Should(Say("FAILED")) 251 Eventually(session).Should(Exit(1)) 252 }) 253 }) 254 }) 255 }) 256 257 When("the app does not exist", func() { 258 It("displays app not found and exits 1", func() { 259 invalidAppName := helpers.PrefixedRandomName("invalid-app") 260 session := helpers.CF("restart", invalidAppName) 261 262 Eventually(session.Err).Should(Say(`App '%s' not found\.`, invalidAppName)) 263 Eventually(session).Should(Say("FAILED")) 264 265 Eventually(session).Should(Exit(1)) 266 }) 267 }) 268 }) 269 })