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