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  })