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