github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/integration/v6/isolated/create_app_manifest_command_test.go (about) 1 package isolated 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "code.cloudfoundry.org/cli/integration/helpers" 11 "code.cloudfoundry.org/cli/util/manifest" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 . "github.com/onsi/gomega/gbytes" 15 . "github.com/onsi/gomega/gexec" 16 yaml "gopkg.in/yaml.v2" 17 ) 18 19 func createManifest(appName string) (manifest.Manifest, string, error) { 20 tmpDir, err := ioutil.TempDir("", "") 21 defer os.RemoveAll(tmpDir) 22 if err != nil { 23 return manifest.Manifest{}, "", err 24 } 25 26 manifestPath := filepath.Join(tmpDir, "manifest.yml") 27 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tmpDir}, "create-app-manifest", appName, "-p", manifestPath)).Should(Exit(0)) 28 29 manifestContents, err := ioutil.ReadFile(manifestPath) 30 if err != nil { 31 return manifest.Manifest{}, "", err 32 } 33 34 var appsManifest manifest.Manifest 35 err = yaml.Unmarshal(manifestContents, &appsManifest) 36 if err != nil { 37 return manifest.Manifest{}, "", err 38 } 39 40 return appsManifest, string(manifestContents), nil 41 } 42 43 var _ = Describe("create-app-manifest command", func() { 44 var appName string 45 var manifestFilePath string 46 var tempDir string 47 48 BeforeEach(func() { 49 appName = helpers.NewAppName() 50 var err error 51 tempDir, err = ioutil.TempDir("", "create-manifest") 52 Expect(err).ToNot(HaveOccurred()) 53 54 manifestFilePath = filepath.Join(tempDir, fmt.Sprintf("%s_manifest.yml", appName)) 55 }) 56 57 AfterEach(func() { 58 os.RemoveAll(tempDir) 59 }) 60 61 Context("Help", func() { 62 It("displays the help information", func() { 63 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", "--help") 64 Eventually(session).Should(Say("NAME:")) 65 Eventually(session).Should(Say("create-app-manifest - Create an app manifest for an app that has been pushed successfully")) 66 Eventually(session).Should(Say("USAGE:")) 67 Eventually(session).Should(Say(`cf create-app-manifest APP_NAME \[-p \/path\/to\/<app-name>_manifest\.yml\]`)) 68 Eventually(session).Should(Say("")) 69 Eventually(session).Should(Say("OPTIONS:")) 70 Eventually(session).Should(Say("-p Specify a path for file creation. If path not specified, manifest file is created in current working directory.")) 71 Eventually(session).Should(Say("SEE ALSO:")) 72 Eventually(session).Should(Say("apps, push")) 73 74 Eventually(session).Should(Exit(0)) 75 }) 76 }) 77 78 When("the environment is not setup correctly", func() { 79 It("fails with the appropriate errors", func() { 80 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "create-app-manifest", "some-app-name") 81 }) 82 }) 83 84 When("app name not provided", func() { 85 It("displays a usage error", func() { 86 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest") 87 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided")) 88 Eventually(session).Should(Say("USAGE:")) 89 90 Eventually(session).Should(Exit(1)) 91 }) 92 }) 93 94 When("the environment is setup correctly", func() { 95 var ( 96 orgName string 97 spaceName string 98 userName string 99 100 domainName string 101 ) 102 103 BeforeEach(func() { 104 orgName = helpers.NewOrgName() 105 spaceName = helpers.NewSpaceName() 106 107 helpers.SetupCF(orgName, spaceName) 108 userName, _ = helpers.GetCredentials() 109 domainName = helpers.DefaultSharedDomain() 110 }) 111 112 AfterEach(func() { 113 helpers.QuickDeleteOrg(orgName) 114 }) 115 116 When("the app does not exist", func() { 117 It("displays a usage error", func() { 118 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 119 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 120 Eventually(session).Should(Say("FAILED")) 121 Eventually(session.Err).Should(Say("App '%s' not found", appName)) 122 123 Eventually(session).Should(Exit(1)) 124 }) 125 }) 126 127 When("the app exists", func() { 128 When("the app does not have routes", func() { 129 BeforeEach(func() { 130 helpers.WithHelloWorldApp(func(appDir string) { 131 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-route")).Should(Exit(0)) 132 }) 133 }) 134 135 It("creates the manifest with no-route set to true", func() { 136 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 137 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 138 Eventually(session).Should(Say("OK")) 139 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 140 Eventually(session).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 141 142 expectedFile := fmt.Sprintf(`applications: 143 - name: %s 144 disk_quota: 1G 145 instances: 1 146 memory: 32M 147 no-route: true 148 stack: cflinuxfs\d 149 `, appName) 150 151 createdFile, err := ioutil.ReadFile(manifestFilePath) 152 Expect(err).ToNot(HaveOccurred()) 153 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 154 155 Eventually(session).Should(Exit(0)) 156 }) 157 }) 158 159 When("the app has routes", func() { 160 BeforeEach(func() { 161 helpers.WithHelloWorldApp(func(appDir string) { 162 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName)).Should(Exit(0)) 163 }) 164 }) 165 166 It("creates the manifest", func() { 167 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 168 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 169 Eventually(session).Should(Say("OK")) 170 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 171 Eventually(session).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 172 173 expectedFile := fmt.Sprintf(`applications: 174 - name: %s 175 disk_quota: 1G 176 instances: 1 177 memory: 32M 178 routes: 179 - route: %s.%s 180 stack: cflinuxfs\d 181 `, appName, strings.ToLower(appName), domainName) 182 183 createdFile, err := ioutil.ReadFile(manifestFilePath) 184 Expect(err).ToNot(HaveOccurred()) 185 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 186 187 Eventually(session).Should(Exit(0)) 188 }) 189 190 When("the -p flag is provided", func() { 191 When("the specified file is a directory", func() { 192 It("displays a file creation error", func() { 193 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", tempDir) 194 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 195 Eventually(session).Should(Say("FAILED")) 196 Eventually(session.Err).Should(Say("Error creating manifest file: open %s: is a directory", helpers.ConvertPathToRegularExpression(tempDir))) 197 198 Eventually(session).Should(Exit(1)) 199 }) 200 }) 201 202 When("the specified file does not exist", func() { 203 var newFile string 204 205 BeforeEach(func() { 206 newFile = filepath.Join(tempDir, "new-file.yml") 207 }) 208 209 It("creates the manifest in the file", func() { 210 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", newFile) 211 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 212 Eventually(session).Should(Say("OK")) 213 Eventually(session).Should(Say("Manifest file created successfully at %s", helpers.ConvertPathToRegularExpression(newFile))) 214 215 expectedFile := fmt.Sprintf(`applications: 216 - name: %s 217 disk_quota: 1G 218 instances: 1 219 memory: 32M 220 routes: 221 - route: %s.%s 222 stack: cflinuxfs\d 223 `, appName, strings.ToLower(appName), domainName) 224 225 createdFile, err := ioutil.ReadFile(newFile) 226 Expect(err).ToNot(HaveOccurred()) 227 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 228 229 Eventually(session).Should(Exit(0)) 230 }) 231 }) 232 233 When("the specified file exists", func() { 234 var existingFile string 235 236 BeforeEach(func() { 237 existingFile = filepath.Join(tempDir, "some-file") 238 f, err := os.Create(existingFile) 239 Expect(err).ToNot(HaveOccurred()) 240 Expect(f.Close()).To(Succeed()) 241 }) 242 243 It("overrides the previous file with the new manifest", func() { 244 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", existingFile) 245 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 246 Eventually(session).Should(Say("OK")) 247 Eventually(session).Should(Say("Manifest file created successfully at %s", helpers.ConvertPathToRegularExpression(existingFile))) 248 249 expectedFile := fmt.Sprintf(`applications: 250 - name: %s 251 disk_quota: 1G 252 instances: 1 253 memory: 32M 254 routes: 255 - route: %s.%s 256 stack: cflinuxfs\d 257 `, appName, strings.ToLower(appName), domainName) 258 259 createdFile, err := ioutil.ReadFile(existingFile) 260 Expect(err).ToNot(HaveOccurred()) 261 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 262 263 Eventually(session).Should(Exit(0)) 264 }) 265 }) 266 }) 267 }) 268 }) 269 270 When("app was created with docker image", func() { 271 BeforeEach(func() { 272 Eventually(helpers.CF("push", appName, "-o", DockerImage)).Should(Exit(0)) 273 }) 274 275 It("creates the manifest", func() { 276 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-v") 277 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 278 Eventually(session).Should(Say("OK")) 279 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 280 Eventually(session).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 281 Eventually(session).Should(Exit(0)) 282 283 expectedFile := fmt.Sprintf(`applications: 284 - name: %s 285 disk_quota: 1G 286 docker: 287 image: %s 288 instances: 1 289 memory: 32M 290 routes: 291 - route: %s.%s 292 stack: cflinuxfs\d 293 `, appName, DockerImage, strings.ToLower(appName), domainName) 294 295 createdFile, err := ioutil.ReadFile(manifestFilePath) 296 Expect(err).ToNot(HaveOccurred()) 297 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 298 }) 299 }) 300 301 When("the API supports docker credentials", func() { 302 var oldDockerPassword string 303 304 BeforeEach(func() { 305 oldDockerPassword = os.Getenv("CF_DOCKER_PASSWORD") 306 Expect(os.Setenv("CF_DOCKER_PASSWORD", "my-docker-password")).To(Succeed()) 307 308 Eventually(helpers.CF("push", appName, "-o", DockerImage, "--docker-username", "some-docker-username")).Should(Exit()) 309 }) 310 311 AfterEach(func() { 312 Expect(os.Setenv("CF_DOCKER_PASSWORD", oldDockerPassword)).To(Succeed()) 313 }) 314 315 It("creates the manifest", func() { 316 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-v") 317 Eventually(session).Should(Say(`Creating an app manifest from current settings of app %s in org %s / space %s as %s\.\.\.`, appName, orgName, spaceName, userName)) 318 Eventually(session).Should(Say("OK")) 319 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 320 Eventually(session).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 321 322 expectedFile := fmt.Sprintf(`applications: 323 - name: %s 324 disk_quota: 1G 325 docker: 326 image: %s 327 username: some-docker-username 328 instances: 1 329 memory: 32M 330 routes: 331 - route: %s.%s 332 stack: cflinuxfs\d 333 `, appName, DockerImage, strings.ToLower(appName), domainName) 334 335 createdFile, err := ioutil.ReadFile(manifestFilePath) 336 Expect(err).ToNot(HaveOccurred()) 337 Expect(string(createdFile)).To(MatchRegexp(expectedFile)) 338 339 Eventually(session).Should(Exit(0)) 340 }) 341 }) 342 343 When("app has no hostname", func() { 344 var domain helpers.Domain 345 346 BeforeEach(func() { 347 domain = helpers.NewDomain(orgName, helpers.NewDomainName("")) 348 domain.Create() 349 350 helpers.WithHelloWorldApp(func(appDir string) { 351 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-start", "-b", "staticfile_buildpack", "--no-hostname", "-d", domain.Name)).Should(Exit(0)) 352 }) 353 }) 354 355 It("contains routes without hostnames", func() { 356 appManifest, _, err := createManifest(appName) 357 Expect(err).ToNot(HaveOccurred()) 358 359 Expect(appManifest.Applications).To(HaveLen(1)) 360 Expect(appManifest.Applications[0].Routes).To(HaveLen(1)) 361 Expect(appManifest.Applications[0].Routes[0]).To(Equal(domain.Name)) 362 }) 363 }) 364 365 When("the app has a buildpack", func() { 366 BeforeEach(func() { 367 helpers.WithHelloWorldApp(func(appDir string) { 368 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-start", "-b", "staticfile_buildpack")).Should(Exit(0)) 369 }) 370 }) 371 372 It("returns a manifest with one buildpack under buildpacks", func() { 373 appManifest, rawManifest, err := createManifest(appName) 374 Expect(err).ToNot(HaveOccurred()) 375 376 Expect(appManifest.Applications).To(HaveLen(1)) 377 Expect(appManifest.Applications[0].Buildpacks).To(ConsistOf("staticfile_buildpack"), fmt.Sprintf("Manifest should have a staticfile_buildpack:\n%s\n", rawManifest)) 378 }) 379 }) 380 381 When("the app has multiple buildpacks", func() { 382 BeforeEach(func() { 383 helpers.WithHelloWorldApp(func(appDir string) { 384 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-start", "-b", "ruby_buildpack", "-b", "staticfile_buildpack")).Should(Exit(0)) 385 }) 386 }) 387 388 It("returns a manifest with multiple buildpacks", func() { 389 appManifest, rawManifest, err := createManifest(appName) 390 Expect(err).ToNot(HaveOccurred()) 391 392 Expect(appManifest.Applications).To(HaveLen(1)) 393 Expect(appManifest.Applications[0].Buildpacks).To(ConsistOf("ruby_buildpack", "staticfile_buildpack"), fmt.Sprintf("Manifest should have ruby and staticfile:\n%s\n", rawManifest)) 394 }) 395 }) 396 }) 397 })