github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+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 \[-b BROKER\] \[-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+-b Create a service instance from a particular broker\. Required when service name is ambiguous`)) 52 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\.`)) 53 Eventually(session).Should(Say(`\s+-t User provided tags`)) 54 Eventually(session).Should(Say(`SEE ALSO:`)) 55 Eventually(session).Should(Say(`\s+bind-service, create-user-provided-service, marketplace, services`)) 56 Eventually(session).Should(Exit(0)) 57 }) 58 }) 59 }) 60 61 When("not logged in", func() { 62 BeforeEach(func() { 63 helpers.LogoutCF() 64 }) 65 66 It("displays FAILED, an informative error message, and exits 1", func() { 67 session := helpers.CF("create-service", "service", "plan", "my-service") 68 Eventually(session).Should(Say("FAILED")) 69 Eventually(session.Err).Should(Say("Not logged in. Use 'cf login' to log in\\.")) 70 Eventually(session).Should(Exit(1)) 71 }) 72 }) 73 74 When("logged in", func() { 75 BeforeEach(func() { 76 helpers.LoginCF() 77 }) 78 79 When("the environment is not setup correctly", func() { 80 It("fails with the appropriate errors", func() { 81 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "create-service", "service-name", "simple", "new-service") 82 }) 83 }) 84 85 When("the environment is setup correctly", func() { 86 var ( 87 org string 88 space string 89 domain string 90 username string 91 ) 92 93 BeforeEach(func() { 94 org = helpers.NewOrgName() 95 space = helpers.NewSpaceName() 96 97 helpers.SetupCF(org, space) 98 99 username, _ = helpers.GetCredentials() 100 domain = helpers.DefaultSharedDomain() 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 helpers.ServiceBroker 183 ) 184 185 BeforeEach(func() { 186 service = helpers.PrefixedRandomName("SERVICE") 187 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 188 189 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 190 broker.Push() 191 broker.Configure(true) 192 broker.Create() 193 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 194 }) 195 196 AfterEach(func() { 197 broker.Destroy() 198 }) 199 200 It("displays an informative success message, exits 0", func() { 201 By("creating the service") 202 session := helpers.CF("create-service", service, servicePlan, "my-service") 203 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 204 "my-service", org, space, username)) 205 Eventually(session).Should(Say("OK")) 206 Eventually(session).Should(Exit(0)) 207 208 session = helpers.CF("services") 209 Eventually(session).Should(Exit(0)) 210 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 211 "my-service", 212 service, 213 servicePlan, 214 )) 215 216 By("displaying the service already exists when using a duplicate name") 217 session = helpers.CF("create-service", service, servicePlan, "my-service") 218 Eventually(session).Should(Say("OK")) 219 Eventually(session).Should(Say("Service my-service already exists")) 220 Eventually(session).Should(Exit(0)) 221 }) 222 223 When("the provided plan does not exist", func() { 224 It("displays an informative error message, exits 1", func() { 225 session := helpers.CF("create-service", service, "some-plan", "service-instance") 226 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 227 "service-instance", org, space, username)) 228 Eventually(session).Should(Say("FAILED")) 229 Eventually(session.Err).Should(Say("The plan %s could not be found for service %s", "some-plan", service)) 230 Eventually(session).Should(Exit(1)) 231 }) 232 }) 233 234 When("creating with valid params json", func() { 235 It("displays an informative success message, exits 0", func() { 236 session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", "{}") 237 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 238 "my-service", org, space, username)) 239 Eventually(session).Should(Say("OK")) 240 Eventually(session).Should(Exit(0)) 241 242 session = helpers.CF("services") 243 Eventually(session).Should(Exit(0)) 244 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 245 "my-service", 246 service, 247 servicePlan, 248 )) 249 }) 250 }) 251 252 When("creating with valid params json in a file", func() { 253 var tempFilePath string 254 255 BeforeEach(func() { 256 tempFilePath = helpers.TempFileWithContent(`{"valid":"json"}`) 257 }) 258 259 AfterEach(func() { 260 Expect(os.Remove(tempFilePath)).To(Succeed()) 261 }) 262 263 It("displays an informative success message, exits 0", func() { 264 session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", tempFilePath) 265 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 266 "my-service", org, space, username)) 267 Eventually(session).Should(Say("OK")) 268 Eventually(session).Should(Exit(0)) 269 270 session = helpers.CF("services") 271 Eventually(session).Should(Exit(0)) 272 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 273 "my-service", 274 service, 275 servicePlan, 276 )) 277 }) 278 }) 279 280 When("creating with tags", func() { 281 It("displays an informative message, exits 0, and creates the service with tags", func() { 282 session := helpers.CF("create-service", service, servicePlan, "my-service", "-t", "sapi, rocks") 283 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 284 "my-service", org, space, username)) 285 Eventually(session).Should(Say("OK")) 286 Eventually(session).Should(Exit(0)) 287 288 session = helpers.CF("service", "my-service") 289 Eventually(session).Should(Exit(0)) 290 Eventually(session).Should(Say("tags:\\s+sapi, rocks")) 291 }) 292 }) 293 }) 294 295 When("the service provided is async and accessible", func() { 296 var ( 297 service string 298 servicePlan string 299 broker helpers.ServiceBroker 300 ) 301 302 BeforeEach(func() { 303 service = helpers.PrefixedRandomName("SERVICE") 304 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 305 306 broker = helpers.NewAsynchServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 307 broker.Push() 308 broker.Configure(true) 309 broker.Create() 310 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 311 }) 312 313 AfterEach(func() { 314 broker.Destroy() 315 }) 316 317 It("creates the service and displays a message that creation is in progress", func() { 318 session := helpers.CF("create-service", service, servicePlan, "my-service", "-v") 319 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 320 "my-service", org, space, username)) 321 Eventually(session).Should(Say("OK")) 322 Eventually(session).Should(Say("Create in progress. Use 'cf services' or 'cf service my-service' to check operation status.")) 323 Eventually(session).Should(Exit(0)) 324 }) 325 }) 326 327 When("there are two services with the same name from different brokers", func() { 328 var ( 329 service string 330 servicePlan string 331 broker1 helpers.ServiceBroker 332 broker2 helpers.ServiceBroker 333 ) 334 335 BeforeEach(func() { 336 helpers.SkipIfVersionLessThan(ccversion.MinVersionMultiServiceRegistrationV2) 337 service = helpers.PrefixedRandomName("SERVICE") 338 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 339 340 broker1 = helpers.CreateBroker(domain, service, servicePlan) 341 broker2 = helpers.CreateBroker(domain, service, servicePlan) 342 343 Eventually(helpers.CF("enable-service-access", service, "-b", broker1.Name)).Should(Exit(0)) 344 Eventually(helpers.CF("enable-service-access", service, "-b", broker2.Name)).Should(Exit(0)) 345 }) 346 347 AfterEach(func() { 348 broker1.Destroy() 349 broker2.Destroy() 350 }) 351 352 When("the user does not specify which broker to use", func() { 353 It("displays an informative error message, exits 1", func() { 354 session := helpers.CF("create-service", service, servicePlan, "my-service") 355 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 356 "my-service", org, space, username)) 357 Eventually(session.Err).Should(Say("Service '%s' is provided by multiple service brokers\\. Specify a broker by using the '-b' flag\\.", service)) 358 Eventually(session).Should(Say("FAILED")) 359 Eventually(session).Should(Exit(1)) 360 }) 361 }) 362 363 When("the user specifies which broker to use", func() { 364 When("the user is a space developer", func() { 365 BeforeEach(func() { 366 username = helpers.SwitchToSpaceRole(org, space, "SpaceDeveloper") 367 helpers.TargetOrgAndSpace(org, space) 368 }) 369 370 AfterEach(func() { 371 helpers.SetupCF(org, space) 372 }) 373 374 It("displays an informative success message, exits 0", func() { 375 By("creating the service with -b flag") 376 session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", broker1.Name) 377 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 378 "my-service", org, space, username)) 379 Eventually(session).Should(Say("OK")) 380 Eventually(session).Should(Exit(0)) 381 382 session = helpers.CF("services") 383 Eventually(session).Should(Exit(0)) 384 Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded", 385 "my-service", 386 service, 387 servicePlan, 388 )) 389 }) 390 391 Context("the broker is not accessible by that user", func() { 392 It("displays an informative error message, exits 1", func() { 393 session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", "non-existent-broker") 394 Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.", 395 "my-service", org, space, username)) 396 Eventually(session.Err).Should(Say("Service '%s' provided by service broker '%s' not found\\.", service, "non-existent-broker")) 397 Eventually(session).Should(Say("FAILED")) 398 Eventually(session).Should(Exit(1)) 399 }) 400 }) 401 }) 402 }) 403 }) 404 }) 405 }) 406 })