github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/integration/v7/isolated/apply_manifest_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"regexp"
     9  
    10  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    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("apply-manifest command", func() {
    19  	var (
    20  		orgName      string
    21  		spaceName    string
    22  		appName      string
    23  		manifestPath string
    24  		appDir       string
    25  	)
    26  
    27  	BeforeEach(func() {
    28  		orgName = helpers.NewOrgName()
    29  		spaceName = helpers.NewSpaceName()
    30  		appName = helpers.PrefixedRandomName("app")
    31  
    32  		appDir = helpers.TempDirAbsolutePath("", "simple-app")
    33  
    34  		manifestPath = filepath.Join(appDir, "manifest.yml")
    35  		// Ensure the file exists at the minimum
    36  		helpers.WriteManifest(manifestPath, map[string]interface{}{})
    37  	})
    38  
    39  	AfterEach(func() {
    40  		Expect(os.RemoveAll(appDir)).ToNot(HaveOccurred())
    41  	})
    42  
    43  	Describe("help", func() {
    44  		It("appears in cf help -a", func() {
    45  			session := helpers.CF("help", "-a")
    46  			Eventually(session).Should(Exit(0))
    47  			Expect(session).To(HaveCommandInCategoryWithDescription("apply-manifest", "SPACES", "Apply manifest properties to a space"))
    48  		})
    49  
    50  		When("--help flag is set", func() {
    51  			It("displays command usage to output", func() {
    52  				session := helpers.CF("apply-manifest", "--help")
    53  
    54  				Eventually(session).Should(Say("NAME:"))
    55  				Eventually(session).Should(Say("apply-manifest - Apply manifest properties to a space"))
    56  				Eventually(session).Should(Say("USAGE:"))
    57  				Eventually(session).Should(Say("cf apply-manifest -f APP_MANIFEST_PATH"))
    58  				Eventually(session).Should(Say("SEE ALSO:"))
    59  				Eventually(session).Should(Say("create-app, create-app-manifest, push"))
    60  
    61  				Eventually(session).Should(Exit(0))
    62  			})
    63  		})
    64  	})
    65  
    66  	When("the environment is not setup correctly", func() {
    67  		It("fails with the appropriate errors", func() {
    68  			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "apply-manifest", "-f", manifestPath)
    69  		})
    70  	})
    71  
    72  	When("the environment is set up correctly", func() {
    73  		BeforeEach(func() {
    74  			helpers.SetupCF(orgName, spaceName)
    75  		})
    76  
    77  		AfterEach(func() {
    78  			helpers.QuickDeleteOrg(orgName)
    79  		})
    80  
    81  		When("the app name in the manifest is missing", func() {
    82  			BeforeEach(func() {
    83  				helpers.WriteManifest(manifestPath, map[string]interface{}{
    84  					"applications": []map[string]interface{}{
    85  						{
    86  							"instances": 3,
    87  						},
    88  					},
    89  				})
    90  			})
    91  
    92  			It("reports an error", func() {
    93  				session := helpers.CF("apply-manifest", "-f", manifestPath)
    94  				Eventually(session.Err).Should(Say("For application at index 0: Name must not be empty"))
    95  				Eventually(session).Should(Say("FAILED"))
    96  				Eventually(session).Should(Exit(1))
    97  			})
    98  		})
    99  
   100  		When("there is a CC error", func() {
   101  			BeforeEach(func() {
   102  				helpers.WriteManifest(manifestPath, map[string]interface{}{
   103  					"applications": []map[string]interface{}{
   104  						{
   105  							"name":      appName,
   106  							"instances": -1,
   107  						},
   108  					},
   109  				})
   110  			})
   111  
   112  			It("displays the error", func() {
   113  				session := helpers.CF("apply-manifest", "-f", manifestPath)
   114  				Eventually(session.Err).Should(Say("Instances must be greater than or equal to 0"))
   115  				Eventually(session).Should(Say("FAILED"))
   116  
   117  				Eventually(session).Should(Exit(1))
   118  			})
   119  		})
   120  
   121  		When("-f is provided", func() {
   122  			When("the -f flag is not given an arg", func() {
   123  				It("tells the user that the flag requires an arg, prints help text, and exits 1", func() {
   124  					session := helpers.CF("apply-manifest", "-f")
   125  
   126  					Eventually(session.Err).Should(Say("Incorrect Usage: expected argument for flag `-f'"))
   127  					Eventually(session).Should(Say("NAME:"))
   128  					Eventually(session).Should(Exit(1))
   129  				})
   130  			})
   131  
   132  			When("the -f flag points to a directory that does not have a manifest.yml file", func() {
   133  				var (
   134  					emptyDir string
   135  				)
   136  
   137  				BeforeEach(func() {
   138  					emptyDir = helpers.TempDirAbsolutePath("", "empty")
   139  				})
   140  
   141  				AfterEach(func() {
   142  					Expect(os.RemoveAll(emptyDir)).ToNot(HaveOccurred())
   143  				})
   144  
   145  				It("tells the user that the provided path doesn't exist, prints help text, and exits 1", func() {
   146  					session := helpers.CF("apply-manifest", "-f", emptyDir)
   147  
   148  					Eventually(session.Err).Should(helpers.SayPath("Incorrect Usage: The specified directory '%s' does not contain a file named 'manifest.yml'.", emptyDir))
   149  					Eventually(session).Should(Say("NAME:"))
   150  					Eventually(session).Should(Exit(1))
   151  				})
   152  			})
   153  
   154  			When("the -f flag points to a file that does not exist", func() {
   155  				It("tells the user that the provided path doesn't exist, prints help text, and exits 1", func() {
   156  					session := helpers.CF("apply-manifest", "-f", "path/that/does/not/exist")
   157  
   158  					Eventually(session.Err).Should(Say("Incorrect Usage: The specified path 'path/that/does/not/exist' does not exist."))
   159  					Eventually(session).Should(Say("NAME:"))
   160  					Eventually(session).Should(Exit(1))
   161  				})
   162  			})
   163  
   164  			When("the manifest exists where -f points", func() {
   165  				It("applies the manifest successfully", func() {
   166  					userName, _ := helpers.GetCredentials()
   167  					helpers.WriteManifest(filepath.Join(appDir, "manifest.yml"), map[string]interface{}{
   168  						"applications": []map[string]interface{}{
   169  							{
   170  								"name":      appName,
   171  								"instances": 3,
   172  							},
   173  						},
   174  					})
   175  
   176  					session := helpers.CF("apply-manifest", "-f", appDir)
   177  					Eventually(session).Should(Say("Applying manifest %s in org %s / space %s as %s...", regexp.QuoteMeta(manifestPath), orgName, spaceName, userName))
   178  					Eventually(session).Should(Exit())
   179  
   180  					session = helpers.CF("app", appName)
   181  					Eventually(session).Should(Say(`instances:\s+%s`, `\d/3`))
   182  					Eventually(session).Should(Exit())
   183  				})
   184  			})
   185  
   186  		})
   187  
   188  		When("-f is not provided", func() {
   189  			When("a properly formatted manifest is present in the pwd", func() {
   190  				It("autodetects and applies the manifest", func() {
   191  					userName, _ := helpers.GetCredentials()
   192  					helpers.WriteManifest(filepath.Join(appDir, "manifest.yml"), map[string]interface{}{
   193  						"applications": []map[string]interface{}{
   194  							{
   195  								"name":      appName,
   196  								"instances": 3,
   197  							},
   198  						},
   199  					})
   200  
   201  					session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "apply-manifest")
   202  					formatString := fmt.Sprintf("Applying manifest %%s in org %s / space %s as %s...", orgName, spaceName, userName)
   203  					Eventually(session).Should(helpers.SayPath(formatString, manifestPath))
   204  					Eventually(session).Should(Exit())
   205  
   206  					session = helpers.CF("app", appName)
   207  					Eventually(session).Should(Say(`instances:\s+%s`, `\d/3`))
   208  					Eventually(session).Should(Exit())
   209  				})
   210  			})
   211  
   212  			When("the current directory does not have a manifest", func() {
   213  				It("fails nicely", func() {
   214  					currentDir, err := os.Getwd()
   215  					Expect(err).NotTo(HaveOccurred())
   216  					session := helpers.CF("apply-manifest")
   217  
   218  					Eventually(session.Err).Should(helpers.SayPath(`Could not find 'manifest.yml' file in %s`, currentDir))
   219  					Eventually(session).Should(Say("FAILED"))
   220  					Eventually(session).Should(Exit(1))
   221  				})
   222  			})
   223  		})
   224  
   225  		When("testing manifest diffing output", func() {
   226  			var (
   227  				userName string
   228  			)
   229  
   230  			BeforeEach(func() {
   231  				userName, _ = helpers.GetCredentials()
   232  			})
   233  
   234  			When("there are no changes in the manifest", func() {
   235  				It("shows no changes", func() {
   236  					helpers.WithHelloWorldApp(func(dir string) {
   237  						manifest, manifestPath := pushAppAndGenerateManifest(appName, dir)
   238  						helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifest)
   239  						session := helpers.CF("apply-manifest", "-f", manifestPath)
   240  						Eventually(session).Should(Say("Applying manifest %s in org %s / space %s as %s...", regexp.QuoteMeta(manifestPath), orgName, spaceName, userName))
   241  						Eventually(session).Should(Say("Updating with these attributes..."))
   242  						Consistently(session).ShouldNot(Say(`^\+ `))
   243  						Consistently(session).ShouldNot(Say(`^- `))
   244  						Eventually(session).Should(Exit(0))
   245  					})
   246  				})
   247  			})
   248  
   249  			When("there are changes in the manifest", func() {
   250  				It("shows changes", func() {
   251  					helpers.WithHelloWorldApp(func(dir string) {
   252  						manifest, manifestPath := pushAppAndGenerateManifest(appName, dir)
   253  						helpers.WriteManifest(filepath.Join(dir, "manifest.yml"), manifest)
   254  
   255  						session := helpers.CF("scale", appName, "-i", "3")
   256  						Eventually(session).Should(Exit(0))
   257  
   258  						session = helpers.CF("apply-manifest", "-f", manifestPath)
   259  						Eventually(session).Should(Say("Applying manifest %s in org %s / space %s as %s...", regexp.QuoteMeta(manifestPath), orgName, spaceName, userName))
   260  						Eventually(session).Should(Say("Updating with these attributes..."))
   261  						Eventually(session).Should(Say("applications"))
   262  						Eventually(session).Should(Say(`\n-\s+instances: 3`))
   263  						Eventually(session).Should(Say(`\n\+\s+instances: 1`))
   264  						Eventually(session).Should(Exit(0))
   265  					})
   266  				})
   267  			})
   268  		})
   269  
   270  		When("--vars are provided", func() {
   271  			var (
   272  				tempDir        string
   273  				pathToManifest string
   274  			)
   275  
   276  			BeforeEach(func() {
   277  				var err error
   278  				tempDir, err = ioutil.TempDir("", "simple-manifest-test")
   279  				Expect(err).ToNot(HaveOccurred())
   280  				pathToManifest = filepath.Join(tempDir, "manifest.yml")
   281  				helpers.WriteManifest(pathToManifest, map[string]interface{}{
   282  					"applications": []map[string]interface{}{
   283  						{
   284  							"name": appName,
   285  							"env": map[string]interface{}{
   286  								"key1": "((var1))",
   287  								"key4": "((var2))",
   288  							},
   289  						},
   290  					},
   291  				})
   292  			})
   293  
   294  			It("uses the manifest with substituted variables", func() {
   295  				helpers.WithHelloWorldApp(func(dir string) {
   296  					session := helpers.CF("apply-manifest", "-f", pathToManifest, "--var=var1=secret-key", "--var=var2=foobar")
   297  					Eventually(session).Should(Exit(0))
   298  				})
   299  
   300  				session := helpers.CF("env", appName)
   301  				Eventually(session).Should(Say(`key1:\s+secret-key`))
   302  				Eventually(session).Should(Say(`key4:\s+foobar`))
   303  				Eventually(session).Should(Exit(0))
   304  			})
   305  		})
   306  	})
   307  })
   308  
   309  func pushAppAndGenerateManifest(appName, dir string) (map[string]interface{}, string) {
   310  	session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: dir}, PushCommandName, appName)
   311  	Eventually(session).Should(Exit(0))
   312  	manifestPath := filepath.Join(dir, "manifest.yml")
   313  	session = helpers.CF("create-app-manifest", appName, "-p", manifestPath)
   314  	Eventually(session).Should(helpers.SayPath(`Manifest file created successfully at %s`, manifestPath))
   315  	Eventually(session).Should(Exit(0))
   316  	manifest := helpers.ReadManifest(manifestPath)
   317  
   318  	return manifest, manifestPath
   319  }