github.com/jenspinney/cli@v6.42.1-0.20190207184520-7450c600020e+incompatible/integration/shared/isolated/create_service_command_test.go (about) 1 package isolated 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 8 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 9 "code.cloudfoundry.org/cli/integration/helpers" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/gbytes" 13 . "github.com/onsi/gomega/gexec" 14 ) 15 16 var _ = Describe("create-service command", func() { 17 Describe("help", func() { 18 When("--help flag is set", func() { 19 It("displays command usage to output", func() { 20 session := helpers.CF("create-service", "--help") 21 Eventually(session).Should(Say("NAME:")) 22 Eventually(session).Should(Say(`\s+create-service - Create a service instance`)) 23 Eventually(session).Should(Say(`USAGE:`)) 24 Eventually(session).Should(Say(`\s+cf create-service SERVICE PLAN SERVICE_INSTANCE \[-c PARAMETERS_AS_JSON\] \[-t TAGS\]`)) 25 Eventually(session).Should(Say(`\s+Optionally provide service-specific configuration parameters in a valid JSON object in-line:`)) 26 Eventually(session).Should(Say(`\s+cf create-service SERVICE PLAN SERVICE_INSTANCE -c '{\"name\":\"value\",\"name\":\"value\"}'`)) 27 Eventually(session).Should(Say(`\s+Optionally provide a file containing service-specific configuration parameters in a valid JSON object\.`)) 28 Eventually(session).Should(Say(`\s+The path to the parameters file can be an absolute or relative path to a file:`)) 29 Eventually(session).Should(Say(`\s+cf create-service SERVICE PLAN SERVICE_INSTANCE -c PATH_TO_FILE`)) 30 Eventually(session).Should(Say(`\s+Example of valid JSON object:`)) 31 Eventually(session).Should(Say(`\s+{`)) 32 Eventually(session).Should(Say(`\s+\"cluster_nodes\": {`)) 33 Eventually(session).Should(Say(`\s+\"count\": 5,`)) 34 Eventually(session).Should(Say(`\s+\"memory_mb\": 1024`)) 35 Eventually(session).Should(Say(`\s+}`)) 36 Eventually(session).Should(Say(`\s+}`)) 37 Eventually(session).Should(Say(`TIP:`)) 38 Eventually(session).Should(Say(`\s+Use 'cf create-user-provided-service' to make user-provided services available to CF apps`)) 39 Eventually(session).Should(Say(`EXAMPLES:`)) 40 Eventually(session).Should(Say(`\s+Linux/Mac:`)) 41 Eventually(session).Should(Say(`\s+cf create-service db-service silver mydb -c '{\"ram_gb\":4}'`)) 42 Eventually(session).Should(Say(`\s+Windows Command Line:`)) 43 Eventually(session).Should(Say(`\s+cf create-service db-service silver mydb -c \"{\\\"ram_gb\\\":4}\"`)) 44 Eventually(session).Should(Say(`\s+Windows PowerShell:`)) 45 Eventually(session).Should(Say(`\s+cf create-service db-service silver mydb -c '{\\\"ram_gb\\\":4}'`)) 46 Eventually(session).Should(Say(`\s+cf create-service db-service silver mydb -c ~/workspace/tmp/instance_config.json`)) 47 Eventually(session).Should(Say(`\s+cf create-service db-service silver mydb -t \"list, of, tags\"`)) 48 Eventually(session).Should(Say(`ALIAS:`)) 49 Eventually(session).Should(Say(`\s+cs`)) 50 Eventually(session).Should(Say(`OPTIONS:`)) 51 Eventually(session).Should(Say(`\s+-c Valid JSON object containing service-specific configuration parameters, provided either in-line or in a file\. For a list of supported configuration parameters, see documentation for the particular service offering\.`)) 52 Eventually(session).Should(Say(`\s+-t User provided tags`)) 53 Eventually(session).Should(Say(`SEE ALSO:`)) 54 Eventually(session).Should(Say(`\s+bind-service, create-user-provided-service, marketplace, services`)) 55 Eventually(session).Should(Exit(0)) 56 }) 57 }) 58 }) 59 60 When("not logged in", func() { 61 BeforeEach(func() { 62 helpers.LogoutCF() 63 }) 64 65 It("displays FAILED, an informative error message, and exits 1", func() { 66 session := helpers.CF("create-service", "service", "plan", "my-service") 67 Eventually(session).Should(Say("FAILED")) 68 Eventually(session.Err).Should(Say("Not logged in. Use 'cf login' to log in\\.")) 69 Eventually(session).Should(Exit(1)) 70 }) 71 }) 72 73 When("logged in", func() { 74 BeforeEach(func() { 75 helpers.LoginCF() 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-service", "service-name", "simple", "new-service") 81 }) 82 }) 83 84 When("the environment is setup correctly", func() { 85 var ( 86 org string 87 space string 88 domain string 89 username string 90 ) 91 92 BeforeEach(func() { 93 org = helpers.NewOrgName() 94 space = helpers.NewSpaceName() 95 96 helpers.SetupCF(org, space) 97 98 username, _ = helpers.GetCredentials() 99 domain = helpers.DefaultSharedDomain() 100 }) 101 102 AfterEach(func() { 103 helpers.QuickDeleteOrg(org) 104 }) 105 106 When("not providing any arguments", func() { 107 It("displays an invalid usage error and the help text, and exits 1", func() { 108 session := helpers.CF("create-service") 109 Eventually(session.Err).Should(Say("Incorrect Usage: the required arguments `SERVICE`, `SERVICE_PLAN` and `SERVICE_INSTANCE` were not provided")) 110 111 // checking partial help text, too long and it's tested earlier 112 Eventually(session).Should(Say("NAME:")) 113 Eventually(session).Should(Say(`\s+create-service - Create a service instance`)) 114 Eventually(session).Should(Exit(1)) 115 }) 116 }) 117 118 When("invalid arguments are passed", func() { 119 When("with an invalid json for -c", func() { 120 It("displays an informative error message, exits 1", func() { 121 session := helpers.CF("create-service", "foo", "bar", "my-service", "-c", "{") 122 Eventually(session.Err).Should(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object\\.")) 123 Eventually(session).Should(Exit(1)) 124 }) 125 }) 126 127 When("the provided file contains invalid json", func() { 128 var tempFilePath string 129 130 BeforeEach(func() { 131 tempFilePath = helpers.TempFileWithContent(`{"invalid"}`) 132 }) 133 134 AfterEach(func() { 135 Expect(os.Remove(tempFilePath)).To(Succeed()) 136 }) 137 138 It("displays an informative message and exits 1", func() { 139 session := helpers.CF("create-service", "foo", "bar", "my-service", "-c", tempFilePath) 140 Eventually(session.Err).Should(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object\\.")) 141 Eventually(session).Should(Exit(1)) 142 }) 143 }) 144 145 When("the provided file cannot be read", func() { 146 var emptyDir string 147 148 BeforeEach(func() { 149 var err error 150 emptyDir, err = ioutil.TempDir("", "") 151 Expect(err).NotTo(HaveOccurred()) 152 }) 153 154 AfterEach(func() { 155 Expect(os.RemoveAll(emptyDir)).To(Succeed()) 156 }) 157 158 It("displays an informative message and exits 1", func() { 159 session := helpers.CF("create-service", "foo", "bar", "my-service", "-c", filepath.Join(emptyDir, "non-existent-file")) 160 Eventually(session.Err).Should(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object\\.")) 161 Eventually(session).Should(Exit(1)) 162 }) 163 }) 164 }) 165 166 When("the service provided is not accessible", func() { 167 It("displays an informative message, exits 1", func() { 168 session := helpers.CF("create-service", "some-service", "some-plan", "my-service") 169 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 170 "my-service", org, space, username)) 171 Eventually(session).Should(Say("FAILED")) 172 Eventually(session.Err).Should(Say("Service offering 'some-service' not found")) 173 Eventually(session).Should(Exit(1)) 174 }) 175 }) 176 177 When("the service provided is accessible", func() { 178 var ( 179 service string 180 servicePlan string 181 broker helpers.ServiceBroker 182 ) 183 184 BeforeEach(func() { 185 service = helpers.PrefixedRandomName("SERVICE") 186 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 187 188 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 189 broker.Push() 190 broker.Configure(true) 191 broker.Create() 192 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 193 }) 194 195 AfterEach(func() { 196 broker.Destroy() 197 }) 198 199 It("displays an informative success message, exits 0", func() { 200 By("creating the service") 201 session := helpers.CF("create-service", service, servicePlan, "my-service") 202 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 203 "my-service", org, space, username)) 204 Eventually(session).Should(Say("OK")) 205 Eventually(session).Should(Exit(0)) 206 207 session = helpers.CF("services") 208 Eventually(session).Should(Exit(0)) 209 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 210 "my-service", 211 service, 212 servicePlan, 213 )) 214 215 By("displaying the service already exists when using a duplicate name") 216 session = helpers.CF("create-service", service, servicePlan, "my-service") 217 Eventually(session).Should(Say("OK")) 218 Eventually(session).Should(Say("Service my-service already exists")) 219 Eventually(session).Should(Exit(0)) 220 }) 221 222 When("the provided plan does not exist", func() { 223 It("displays an informative error message, exits 1", func() { 224 session := helpers.CF("create-service", service, "some-plan", "service-instance") 225 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 226 "service-instance", org, space, username)) 227 Eventually(session).Should(Say("FAILED")) 228 Eventually(session.Err).Should(Say("The plan %s could not be found for service %s", "some-plan", service)) 229 Eventually(session).Should(Exit(1)) 230 }) 231 }) 232 233 When("creating with valid params json", func() { 234 It("displays an informative success message, exits 0", func() { 235 session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", "{}") 236 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 237 "my-service", org, space, username)) 238 Eventually(session).Should(Say("OK")) 239 Eventually(session).Should(Exit(0)) 240 241 session = helpers.CF("services") 242 Eventually(session).Should(Exit(0)) 243 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 244 "my-service", 245 service, 246 servicePlan, 247 )) 248 }) 249 }) 250 251 When("creating with valid params json in a file", func() { 252 var tempFilePath string 253 254 BeforeEach(func() { 255 tempFilePath = helpers.TempFileWithContent(`{"valid":"json"}`) 256 }) 257 258 AfterEach(func() { 259 Expect(os.Remove(tempFilePath)).To(Succeed()) 260 }) 261 262 It("displays an informative success message, exits 0", func() { 263 session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", tempFilePath) 264 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 265 "my-service", org, space, username)) 266 Eventually(session).Should(Say("OK")) 267 Eventually(session).Should(Exit(0)) 268 269 session = helpers.CF("services") 270 Eventually(session).Should(Exit(0)) 271 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 272 "my-service", 273 service, 274 servicePlan, 275 )) 276 }) 277 }) 278 279 When("creating with tags", func() { 280 It("displays an informative message, exits 0, and creates the service with tags", func() { 281 session := helpers.CF("create-service", service, servicePlan, "my-service", "-t", "sapi, rocks") 282 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 283 "my-service", org, space, username)) 284 Eventually(session).Should(Say("OK")) 285 Eventually(session).Should(Exit(0)) 286 287 session = helpers.CF("service", "my-service") 288 Eventually(session).Should(Exit(0)) 289 Eventually(session).Should(Say("tags:\\s+sapi, rocks")) 290 }) 291 }) 292 }) 293 294 When("the service provided is async and accessible", func() { 295 var ( 296 service string 297 servicePlan string 298 broker helpers.ServiceBroker 299 ) 300 301 BeforeEach(func() { 302 service = helpers.PrefixedRandomName("SERVICE") 303 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 304 305 broker = helpers.NewAsynchServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 306 broker.Push() 307 broker.Configure(true) 308 broker.Create() 309 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 310 }) 311 312 AfterEach(func() { 313 broker.Destroy() 314 }) 315 316 It("creates the service and displays a message that creation is in progress", func() { 317 session := helpers.CF("create-service", service, servicePlan, "my-service", "-v") 318 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 319 "my-service", org, space, username)) 320 Eventually(session).Should(Say("OK")) 321 Eventually(session).Should(Say("Create in progress. Use 'cf services' or 'cf service my-service' to check operation status.")) 322 Eventually(session).Should(Exit(0)) 323 }) 324 }) 325 326 When("there are two services with the same name from different brokers", func() { 327 var ( 328 service string 329 servicePlan string 330 broker1 helpers.ServiceBroker 331 broker2 helpers.ServiceBroker 332 ) 333 334 BeforeEach(func() { 335 helpers.SkipIfVersionLessThan(ccversion.MinVersionMultiServiceRegistrationV2) 336 service = helpers.PrefixedRandomName("SERVICE") 337 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 338 339 broker1 = helpers.CreateBroker(domain, service, servicePlan) 340 broker2 = helpers.CreateBroker(domain, service, servicePlan) 341 342 Eventually(helpers.CF("enable-service-access", service, "-b", broker1.Name)).Should(Exit(0)) 343 Eventually(helpers.CF("enable-service-access", service, "-b", broker2.Name)).Should(Exit(0)) 344 }) 345 346 AfterEach(func() { 347 broker1.Destroy() 348 broker2.Destroy() 349 }) 350 351 When("the user does not specify which broker to use", func() { 352 It("displays an informative error message, exits 1", func() { 353 session := helpers.CF("create-service", service, servicePlan, "my-service") 354 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 355 "my-service", org, space, username)) 356 Eventually(session.Err).Should(Say("Service '%s' is provided by multiple service brokers\\.", service)) 357 Eventually(session).Should(Say("FAILED")) 358 Eventually(session).Should(Exit(1)) 359 }) 360 }) 361 362 When("the user specifies which broker to use", func() { 363 It("displays an informative success message, exits 0", func() { 364 By("creating the service with -b flag") 365 session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", broker1.Name) 366 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 367 "my-service", org, space, username)) 368 Eventually(session).Should(Say("OK")) 369 Eventually(session).Should(Exit(0)) 370 371 session = helpers.CF("services") 372 Eventually(session).Should(Exit(0)) 373 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 374 "my-service", 375 service, 376 servicePlan, 377 )) 378 }) 379 380 Context("the broker does not exist", func() { 381 It("displays an informative error message, exits 1", func() { 382 session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", "non-existent-broker") 383 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 384 "my-service", org, space, username)) 385 Eventually(session.Err).Should(Say("Service broker '%s' not found\\.", "non-existent-broker")) 386 Eventually(session).Should(Say("FAILED")) 387 Eventually(session).Should(Exit(1)) 388 }) 389 }) 390 }) 391 }) 392 }) 393 }) 394 })