github.com/arunkumar7540/cli@v6.45.0+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.CreateBroker(domain, service, servicePlan)
   190  
   191  					Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0))
   192  				})
   193  
   194  				AfterEach(func() {
   195  					broker.Destroy()
   196  				})
   197  
   198  				It("displays an informative success message, exits 0", func() {
   199  					By("creating the service")
   200  					session := helpers.CF("create-service", service, servicePlan, "my-service")
   201  					Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   202  						"my-service", org, space, username))
   203  					Eventually(session).Should(Say("OK"))
   204  					Eventually(session).Should(Exit(0))
   205  
   206  					session = helpers.CF("services")
   207  					Eventually(session).Should(Exit(0))
   208  					Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded",
   209  						"my-service",
   210  						service,
   211  						servicePlan,
   212  					))
   213  
   214  					By("displaying the service already exists when using a duplicate name")
   215  					session = helpers.CF("create-service", service, servicePlan, "my-service")
   216  					Eventually(session).Should(Say("OK"))
   217  					Eventually(session).Should(Say("Service my-service already exists"))
   218  					Eventually(session).Should(Exit(0))
   219  				})
   220  
   221  				When("the provided plan does not exist", func() {
   222  					It("displays an informative error message, exits 1", func() {
   223  						session := helpers.CF("create-service", service, "some-plan", "service-instance")
   224  						Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   225  							"service-instance", org, space, username))
   226  						Eventually(session).Should(Say("FAILED"))
   227  						Eventually(session.Err).Should(Say("The plan %s could not be found for service %s", "some-plan", service))
   228  						Eventually(session).Should(Exit(1))
   229  					})
   230  				})
   231  
   232  				When("creating with valid params json", func() {
   233  					It("displays an informative success message, exits 0", func() {
   234  						session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", "{}")
   235  						Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   236  							"my-service", org, space, username))
   237  						Eventually(session).Should(Say("OK"))
   238  						Eventually(session).Should(Exit(0))
   239  
   240  						session = helpers.CF("services")
   241  						Eventually(session).Should(Exit(0))
   242  						Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded",
   243  							"my-service",
   244  							service,
   245  							servicePlan,
   246  						))
   247  					})
   248  				})
   249  
   250  				When("creating with valid params json in a file", func() {
   251  					var tempFilePath string
   252  
   253  					BeforeEach(func() {
   254  						tempFilePath = helpers.TempFileWithContent(`{"valid":"json"}`)
   255  					})
   256  
   257  					AfterEach(func() {
   258  						Expect(os.Remove(tempFilePath)).To(Succeed())
   259  					})
   260  
   261  					It("displays an informative success message, exits 0", func() {
   262  						session := helpers.CF("create-service", service, servicePlan, "my-service", "-c", tempFilePath)
   263  						Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   264  							"my-service", org, space, username))
   265  						Eventually(session).Should(Say("OK"))
   266  						Eventually(session).Should(Exit(0))
   267  
   268  						session = helpers.CF("services")
   269  						Eventually(session).Should(Exit(0))
   270  						Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded",
   271  							"my-service",
   272  							service,
   273  							servicePlan,
   274  						))
   275  					})
   276  				})
   277  
   278  				When("creating with tags", func() {
   279  					It("displays an informative message, exits 0, and creates the service with tags", func() {
   280  						session := helpers.CF("create-service", service, servicePlan, "my-service", "-t", "sapi, rocks")
   281  						Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   282  							"my-service", org, space, username))
   283  						Eventually(session).Should(Say("OK"))
   284  						Eventually(session).Should(Exit(0))
   285  
   286  						session = helpers.CF("service", "my-service")
   287  						Eventually(session).Should(Exit(0))
   288  						Eventually(session).Should(Say("tags:\\s+sapi, rocks"))
   289  					})
   290  				})
   291  			})
   292  
   293  			When("the service provided is async and accessible", func() {
   294  				var (
   295  					service     string
   296  					servicePlan string
   297  					broker      helpers.ServiceBroker
   298  				)
   299  
   300  				BeforeEach(func() {
   301  					service = helpers.PrefixedRandomName("SERVICE")
   302  					servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN")
   303  
   304  					broker = helpers.CreateAsyncBroker(domain, service, servicePlan)
   305  
   306  					Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0))
   307  				})
   308  
   309  				AfterEach(func() {
   310  					broker.Destroy()
   311  				})
   312  
   313  				It("creates the service and displays a message that creation is in progress", func() {
   314  					session := helpers.CF("create-service", service, servicePlan, "my-service", "-v")
   315  					Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   316  						"my-service", org, space, username))
   317  					Eventually(session).Should(Say("OK"))
   318  					Eventually(session).Should(Say("Create in progress. Use 'cf services' or 'cf service my-service' to check operation status."))
   319  					Eventually(session).Should(Exit(0))
   320  				})
   321  			})
   322  
   323  			When("there are two services with the same name from different brokers", func() {
   324  				var (
   325  					service     string
   326  					servicePlan string
   327  					broker1     helpers.ServiceBroker
   328  					broker2     helpers.ServiceBroker
   329  				)
   330  
   331  				BeforeEach(func() {
   332  					helpers.SkipIfVersionLessThan(ccversion.MinVersionMultiServiceRegistrationV2)
   333  					service = helpers.PrefixedRandomName("SERVICE")
   334  					servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN")
   335  
   336  					broker1 = helpers.CreateBroker(domain, service, servicePlan)
   337  					broker2 = helpers.CreateBroker(domain, service, servicePlan)
   338  
   339  					Eventually(helpers.CF("enable-service-access", service, "-b", broker1.Name)).Should(Exit(0))
   340  					Eventually(helpers.CF("enable-service-access", service, "-b", broker2.Name)).Should(Exit(0))
   341  				})
   342  
   343  				AfterEach(func() {
   344  					broker1.Destroy()
   345  					broker2.Destroy()
   346  				})
   347  
   348  				When("the user does not specify which broker to use", func() {
   349  					It("displays an informative error message, exits 1", func() {
   350  						session := helpers.CF("create-service", service, servicePlan, "my-service")
   351  						Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   352  							"my-service", org, space, username))
   353  						Eventually(session.Err).Should(Say("Service '%s' is provided by multiple service brokers\\. Specify a broker by using the '-b' flag\\.", service))
   354  						Eventually(session).Should(Say("FAILED"))
   355  						Eventually(session).Should(Exit(1))
   356  					})
   357  				})
   358  
   359  				When("the user specifies which broker to use", func() {
   360  					When("the user is a space developer", func() {
   361  						BeforeEach(func() {
   362  							username = helpers.SwitchToSpaceRole(org, space, "SpaceDeveloper")
   363  							helpers.TargetOrgAndSpace(org, space)
   364  						})
   365  
   366  						AfterEach(func() {
   367  							helpers.SetupCF(org, space)
   368  						})
   369  
   370  						It("displays an informative success message, exits 0", func() {
   371  							By("creating the service with -b flag")
   372  							session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", broker1.Name)
   373  							Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   374  								"my-service", org, space, username))
   375  							Eventually(session).Should(Say("OK"))
   376  							Eventually(session).Should(Exit(0))
   377  
   378  							session = helpers.CF("services")
   379  							Eventually(session).Should(Exit(0))
   380  							Eventually(session).Should(Say("%s\\s+%s\\s+%s\\s+create succeeded",
   381  								"my-service",
   382  								service,
   383  								servicePlan,
   384  							))
   385  						})
   386  
   387  						Context("the broker is not accessible by that user", func() {
   388  							It("displays an informative error message, exits 1", func() {
   389  								session := helpers.CF("create-service", service, servicePlan, "my-service", "-b", "non-existent-broker")
   390  								Eventually(session).Should(Say("Creating service instance %s in org %s / space %s as %s\\.\\.\\.",
   391  									"my-service", org, space, username))
   392  								Eventually(session.Err).Should(Say("Service '%s' provided by service broker '%s' not found\\.", service, "non-existent-broker"))
   393  								Eventually(session).Should(Say("FAILED"))
   394  								Eventually(session).Should(Exit(1))
   395  							})
   396  						})
   397  					})
   398  				})
   399  			})
   400  		})
   401  	})
   402  })