github.com/sleungcy-sap/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  })