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  })