github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+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/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, 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, 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.Out).Should(Say("NAME:")) 65 Eventually(session.Out).Should(Say("create-app-manifest - Create an app manifest for an app that has been pushed successfully")) 66 Eventually(session.Out).Should(Say("USAGE:")) 67 Eventually(session.Out).Should(Say("cf create-app-manifest APP_NAME \\[-p \\/path\\/to\\/<app-name>_manifest\\.yml\\]")) 68 Eventually(session.Out).Should(Say("")) 69 Eventually(session.Out).Should(Say("OPTIONS:")) 70 Eventually(session.Out).Should(Say("-p Specify a path for file creation. If path not specified, manifest file is created in current working directory.")) 71 Eventually(session.Out).Should(Say("SEE ALSO:")) 72 Eventually(session.Out).Should(Say("apps, push")) 73 74 Eventually(session).Should(Exit(0)) 75 }) 76 }) 77 78 Context("when the environment is not setup correctly", func() { 79 Context("when no API endpoint is set", func() { 80 BeforeEach(func() { 81 helpers.UnsetAPI() 82 }) 83 84 It("fails with no API endpoint set message", func() { 85 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 86 Eventually(session.Out).Should(Say("FAILED")) 87 Eventually(session.Err).Should(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint.")) 88 89 Eventually(session).Should(Exit(1)) 90 }) 91 }) 92 93 Context("when not logged in", func() { 94 BeforeEach(func() { 95 helpers.LogoutCF() 96 }) 97 98 It("fails with not logged in message", func() { 99 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 100 Eventually(session.Out).Should(Say("FAILED")) 101 Eventually(session.Err).Should(Say("Not logged in. Use 'cf login' to log in.")) 102 103 Eventually(session).Should(Exit(1)) 104 }) 105 }) 106 107 Context("when there is no org set", func() { 108 BeforeEach(func() { 109 helpers.LogoutCF() 110 helpers.LoginCF() 111 }) 112 113 It("fails with no targeted org error message", func() { 114 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 115 Eventually(session.Out).Should(Say("FAILED")) 116 Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org.")) 117 118 Eventually(session).Should(Exit(1)) 119 }) 120 }) 121 122 Context("when there is no space set", func() { 123 BeforeEach(func() { 124 helpers.LogoutCF() 125 helpers.LoginCF() 126 helpers.TargetOrg(ReadOnlyOrg) 127 }) 128 129 It("fails with no targeted space error message", func() { 130 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 131 Eventually(session.Out).Should(Say("FAILED")) 132 Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space.")) 133 134 Eventually(session).Should(Exit(1)) 135 }) 136 }) 137 }) 138 139 Context("when app name not provided", func() { 140 It("displays a usage error", func() { 141 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest") 142 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `APP_NAME` was not provided")) 143 Eventually(session.Out).Should(Say("USAGE:")) 144 145 Eventually(session).Should(Exit(1)) 146 }) 147 }) 148 149 Context("when the environment is setup correctly", func() { 150 var ( 151 orgName string 152 spaceName string 153 userName string 154 155 domainName string 156 ) 157 158 BeforeEach(func() { 159 orgName = helpers.NewOrgName() 160 spaceName = helpers.NewSpaceName() 161 162 setupCF(orgName, spaceName) 163 userName, _ = helpers.GetCredentials() 164 domainName = defaultSharedDomain() 165 }) 166 167 AfterEach(func() { 168 helpers.QuickDeleteOrg(orgName) 169 }) 170 171 Context("when the app does not exist", func() { 172 It("displays a usage error", func() { 173 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 174 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 175 Eventually(session.Out).Should(Say("FAILED")) 176 Eventually(session.Err).Should(Say("App %s not found", appName)) 177 178 Eventually(session).Should(Exit(1)) 179 }) 180 }) 181 182 Context("when the app exists", func() { 183 Context("when the app does not have routes", func() { 184 BeforeEach(func() { 185 helpers.WithHelloWorldApp(func(appDir string) { 186 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-route")).Should(Exit(0)) 187 }) 188 }) 189 190 It("creates the manifest with no-route set to true", func() { 191 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 192 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 193 Eventually(session.Out).Should(Say("OK")) 194 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 195 Eventually(session.Out).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 196 197 expectedFile := fmt.Sprintf(`applications: 198 - name: %s 199 disk_quota: 1G 200 instances: 1 201 memory: 32M 202 no-route: true 203 stack: cflinuxfs2 204 `, appName) 205 206 createdFile, err := ioutil.ReadFile(manifestFilePath) 207 Expect(err).ToNot(HaveOccurred()) 208 Expect(string(createdFile)).To(Equal(expectedFile)) 209 210 Eventually(session).Should(Exit(0)) 211 }) 212 }) 213 214 Context("when the app has routes", func() { 215 BeforeEach(func() { 216 helpers.WithHelloWorldApp(func(appDir string) { 217 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "v2-push", appName)).Should(Exit(0)) 218 }) 219 }) 220 221 It("creates the manifest", func() { 222 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName) 223 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 224 Eventually(session.Out).Should(Say("OK")) 225 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 226 Eventually(session.Out).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 227 228 expectedFile := fmt.Sprintf(`applications: 229 - name: %s 230 disk_quota: 1G 231 instances: 1 232 memory: 32M 233 routes: 234 - route: %s.%s 235 stack: cflinuxfs2 236 `, appName, strings.ToLower(appName), domainName) 237 238 createdFile, err := ioutil.ReadFile(manifestFilePath) 239 Expect(err).ToNot(HaveOccurred()) 240 Expect(string(createdFile)).To(Equal(expectedFile)) 241 242 Eventually(session).Should(Exit(0)) 243 }) 244 245 Context("when the -p flag is provided", func() { 246 Context("when the specified file is a directory", func() { 247 It("displays a file creation error", func() { 248 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", tempDir) 249 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 250 Eventually(session.Out).Should(Say("FAILED")) 251 Eventually(session.Err).Should(Say("Error creating manifest file: open %s: is a directory", helpers.ConvertPathToRegularExpression(tempDir))) 252 253 Eventually(session).Should(Exit(1)) 254 }) 255 }) 256 257 Context("when the specified file does not exist", func() { 258 var newFile string 259 260 BeforeEach(func() { 261 newFile = filepath.Join(tempDir, "new-file.yml") 262 }) 263 264 It("creates the manifest in the file", func() { 265 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", newFile) 266 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 267 Eventually(session.Out).Should(Say("OK")) 268 Eventually(session.Out).Should(Say("Manifest file created successfully at %s", helpers.ConvertPathToRegularExpression(newFile))) 269 270 expectedFile := fmt.Sprintf(`applications: 271 - name: %s 272 disk_quota: 1G 273 instances: 1 274 memory: 32M 275 routes: 276 - route: %s.%s 277 stack: cflinuxfs2 278 `, appName, strings.ToLower(appName), domainName) 279 280 createdFile, err := ioutil.ReadFile(newFile) 281 Expect(err).ToNot(HaveOccurred()) 282 Expect(string(createdFile)).To(Equal(expectedFile)) 283 284 Eventually(session).Should(Exit(0)) 285 }) 286 }) 287 288 Context("when the specified file exists", func() { 289 var existingFile string 290 291 BeforeEach(func() { 292 existingFile = filepath.Join(tempDir, "some-file") 293 f, err := os.Create(existingFile) 294 Expect(err).ToNot(HaveOccurred()) 295 Expect(f.Close()).To(Succeed()) 296 }) 297 298 It("overrides the previous file with the new manifest", func() { 299 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-p", existingFile) 300 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 301 Eventually(session.Out).Should(Say("OK")) 302 Eventually(session.Out).Should(Say("Manifest file created successfully at %s", helpers.ConvertPathToRegularExpression(existingFile))) 303 304 expectedFile := fmt.Sprintf(`applications: 305 - name: %s 306 disk_quota: 1G 307 instances: 1 308 memory: 32M 309 routes: 310 - route: %s.%s 311 stack: cflinuxfs2 312 `, appName, strings.ToLower(appName), domainName) 313 314 createdFile, err := ioutil.ReadFile(existingFile) 315 Expect(err).ToNot(HaveOccurred()) 316 Expect(string(createdFile)).To(Equal(expectedFile)) 317 318 Eventually(session).Should(Exit(0)) 319 }) 320 }) 321 }) 322 }) 323 }) 324 325 Context("when app was created with docker image", func() { 326 var ( 327 oldDockerPassword string 328 ) 329 330 BeforeEach(func() { 331 oldDockerPassword = os.Getenv("CF_DOCKER_PASSWORD") 332 Expect(os.Setenv("CF_DOCKER_PASSWORD", "my-docker-password")).To(Succeed()) 333 334 Eventually(helpers.CF("v2-push", appName, "-o", DockerImage, "--docker-username", "some-docker-username")).Should(Exit()) 335 }) 336 337 AfterEach(func() { 338 Expect(os.Setenv("CF_DOCKER_PASSWORD", oldDockerPassword)).To(Succeed()) 339 }) 340 341 It("creates the manifest", func() { 342 session := helpers.CustomCF(helpers.CFEnv{WorkingDirectory: tempDir}, "create-app-manifest", appName, "-v") 343 Eventually(session.Out).Should(Say("Creating an app manifest from current settings of app %s in org %s / space %s as %s\\.\\.\\.", appName, orgName, spaceName, userName)) 344 Eventually(session.Out).Should(Say("OK")) 345 expectedFilePath := helpers.ConvertPathToRegularExpression(fmt.Sprintf(".%s%s_manifest.yml", string(os.PathSeparator), appName)) 346 Eventually(session.Out).Should(Say("Manifest file created successfully at %s", expectedFilePath)) 347 348 expectedFile := fmt.Sprintf(`applications: 349 - name: %s 350 disk_quota: 1G 351 docker: 352 image: %s 353 username: some-docker-username 354 instances: 1 355 memory: 32M 356 routes: 357 - route: %s.%s 358 stack: cflinuxfs2 359 `, appName, DockerImage, strings.ToLower(appName), domainName) 360 361 createdFile, err := ioutil.ReadFile(manifestFilePath) 362 Expect(err).ToNot(HaveOccurred()) 363 Expect(string(createdFile)).To(Equal(expectedFile)) 364 365 Eventually(session).Should(Exit(0)) 366 }) 367 }) 368 369 Context("when app has no hostname", func() { 370 var domain helpers.Domain 371 372 BeforeEach(func() { 373 domain = helpers.NewDomain(orgName, helpers.DomainName("")) 374 domain.Create() 375 376 helpers.WithHelloWorldApp(func(appDir string) { 377 Eventually(helpers.CustomCF(helpers.CFEnv{WorkingDirectory: appDir}, "push", appName, "--no-start", "-b", "staticfile_buildpack", "--no-hostname", "-d", domain.Name)).Should(Exit(0)) 378 }) 379 }) 380 381 It("contains routes without hostnames", func() { 382 appManifest, err := createManifest(appName) 383 Expect(err).ToNot(HaveOccurred()) 384 385 Expect(appManifest.Applications).To(HaveLen(1)) 386 Expect(appManifest.Applications[0].Routes).To(HaveLen(1)) 387 Expect(appManifest.Applications[0].Routes[0]).To(Equal(domain.Name)) 388 }) 389 }) 390 }) 391 })