github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/integration/isolated/bind_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/integration/helpers"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gbytes"
    12  	. "github.com/onsi/gomega/gexec"
    13  )
    14  
    15  var _ = Describe("bind-service command", func() {
    16  	BeforeEach(func() {
    17  		helpers.RunIfExperimental("command is currently experimental")
    18  	})
    19  
    20  	Describe("help", func() {
    21  		Context("when --help flag is set", func() {
    22  			It("Displays command usage to output", func() {
    23  				session := helpers.CF("bind-service", "--help")
    24  				Eventually(session.Out).Should(Say("NAME:"))
    25  				Eventually(session.Out).Should(Say("bind-service - Bind a service instance to an app"))
    26  
    27  				Eventually(session.Out).Should(Say("USAGE:"))
    28  				Eventually(session.Out).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE \\[-c PARAMETERS_AS_JSON\\]"))
    29  				Eventually(session.Out).Should(Say("Optionally provide service-specific configuration parameters in a valid JSON object in-line:"))
    30  				Eventually(session.Out).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE -c '{\"name\":\"value\",\"name\":\"value\"}'"))
    31  				Eventually(session.Out).Should(Say("Optionally provide a file containing service-specific configuration parameters in a valid JSON object."))
    32  				Eventually(session.Out).Should(Say("The path to the parameters file can be an absolute or relative path to a file."))
    33  				Eventually(session.Out).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE -c PATH_TO_FILE"))
    34  				Eventually(session.Out).Should(Say("Example of valid JSON object:"))
    35  				Eventually(session.Out).Should(Say("{"))
    36  				Eventually(session.Out).Should(Say("\"permissions\": \"read-only\""))
    37  				Eventually(session.Out).Should(Say("}"))
    38  				Eventually(session.Out).Should(Say("EXAMPLES:"))
    39  				Eventually(session.Out).Should(Say("Linux/Mac:"))
    40  				Eventually(session.Out).Should(Say("cf bind-service myapp mydb -c '{\"permissions\":\"read-only\"}'"))
    41  				Eventually(session.Out).Should(Say("Windows Command Line:"))
    42  				Eventually(session.Out).Should(Say("cf bind-service myapp mydb -c \"{\\\\\"permissions\\\\\":\\\\\"read-only\\\\\"}\""))
    43  				Eventually(session.Out).Should(Say("Windows PowerShell:"))
    44  				Eventually(session.Out).Should(Say("cf bind-service myapp mydb -c '{\\\\\"permissions\\\\\":\\\\\"read-only\\\\\"}'"))
    45  				Eventually(session.Out).Should(Say("cf bind-service myapp mydb -c ~/workspace/tmp/instance_config.json"))
    46  				Eventually(session.Out).Should(Say("ALIAS:"))
    47  				Eventually(session.Out).Should(Say("bs"))
    48  				Eventually(session.Out).Should(Say("OPTIONS:"))
    49  				Eventually(session.Out).Should(Say("-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."))
    50  				Eventually(session.Out).Should(Say("SEE ALSO:"))
    51  				Eventually(session.Out).Should(Say("services"))
    52  			})
    53  		})
    54  	})
    55  
    56  	var (
    57  		serviceInstance string
    58  		appName         string
    59  	)
    60  
    61  	BeforeEach(func() {
    62  		serviceInstance = helpers.PrefixedRandomName("si")
    63  		appName = helpers.PrefixedRandomName("app")
    64  	})
    65  
    66  	Context("when the environment is not setup correctly", func() {
    67  		Context("when no API endpoint is set", func() {
    68  			BeforeEach(func() {
    69  				helpers.UnsetAPI()
    70  			})
    71  
    72  			It("fails with no API endpoint set message", func() {
    73  				session := helpers.CF("bind-service", appName, serviceInstance)
    74  				Eventually(session.Out).Should(Say("FAILED"))
    75  				Eventually(session.Err).Should(Say("No API endpoint set. Use 'cf login' or 'cf api' to target an endpoint."))
    76  				Eventually(session).Should(Exit(1))
    77  			})
    78  		})
    79  
    80  		Context("when not logged in", func() {
    81  			BeforeEach(func() {
    82  				helpers.LogoutCF()
    83  			})
    84  
    85  			It("fails with not logged in message", func() {
    86  				session := helpers.CF("bind-service", appName, serviceInstance)
    87  				Eventually(session.Out).Should(Say("FAILED"))
    88  				Eventually(session.Err).Should(Say("Not logged in. Use 'cf login' to log in."))
    89  				Eventually(session).Should(Exit(1))
    90  			})
    91  		})
    92  
    93  		Context("when there no org set", func() {
    94  			BeforeEach(func() {
    95  				helpers.LogoutCF()
    96  				helpers.LoginCF()
    97  			})
    98  
    99  			It("fails with no targeted org error message", func() {
   100  				session := helpers.CF("bind-service", appName, serviceInstance)
   101  				Eventually(session.Out).Should(Say("FAILED"))
   102  				Eventually(session.Err).Should(Say("No org targeted, use 'cf target -o ORG' to target an org."))
   103  				Eventually(session).Should(Exit(1))
   104  			})
   105  		})
   106  
   107  		Context("when there no space set", func() {
   108  			BeforeEach(func() {
   109  				helpers.LogoutCF()
   110  				helpers.LoginCF()
   111  				helpers.TargetOrg(ReadOnlyOrg)
   112  			})
   113  
   114  			It("fails with no targeted space error message", func() {
   115  				session := helpers.CF("bind-service", appName, serviceInstance)
   116  				Eventually(session.Out).Should(Say("FAILED"))
   117  				Eventually(session.Err).Should(Say("No space targeted, use 'cf target -s SPACE' to target a space."))
   118  				Eventually(session).Should(Exit(1))
   119  			})
   120  		})
   121  	})
   122  
   123  	Context("when the environment is setup correctly", func() {
   124  		var (
   125  			org         string
   126  			space       string
   127  			service     string
   128  			servicePlan string
   129  			domain      string
   130  			username    string
   131  		)
   132  
   133  		BeforeEach(func() {
   134  			org = helpers.NewOrgName()
   135  			space = helpers.NewSpaceName()
   136  			service = helpers.PrefixedRandomName("SERVICE")
   137  			servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN")
   138  			username, _ = helpers.GetCredentials()
   139  
   140  			setupCF(org, space)
   141  			domain = defaultSharedDomain()
   142  		})
   143  
   144  		AfterEach(func() {
   145  			helpers.QuickDeleteOrg(org)
   146  		})
   147  
   148  		Context("when the app does not exist", func() {
   149  			It("displays FAILED and app not found", func() {
   150  				session := helpers.CF("bind-service", "does-not-exist", serviceInstance)
   151  				Eventually(session.Out).Should(Say("FAILED"))
   152  				Eventually(session.Err).Should(Say("App %s not found", "does-not-exist"))
   153  				Eventually(session).Should(Exit(1))
   154  			})
   155  		})
   156  
   157  		Context("when the app exists", func() {
   158  			BeforeEach(func() {
   159  				helpers.WithHelloWorldApp(func(appDir string) {
   160  					Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0))
   161  				})
   162  			})
   163  
   164  			Context("when the service does not exist", func() {
   165  				It("displays FAILED and service not found", func() {
   166  					session := helpers.CF("bind-service", appName, "does-not-exist")
   167  					Eventually(session.Out).Should(Say("FAILED"))
   168  					Eventually(session.Err).Should(Say("Service instance %s not found", "does-not-exist"))
   169  					Eventually(session).Should(Exit(1))
   170  				})
   171  			})
   172  
   173  			Context("when the service exists", func() {
   174  				BeforeEach(func() {
   175  					Eventually(helpers.CF("create-user-provided-service", serviceInstance, "-p", "{}")).Should(Exit(0))
   176  					helpers.WithHelloWorldApp(func(appDir string) {
   177  						Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0))
   178  					})
   179  				})
   180  
   181  				AfterEach(func() {
   182  					Eventually(helpers.CF("unbind-service", appName, serviceInstance)).Should(Exit(0))
   183  					Eventually(helpers.CF("delete-service", serviceInstance, "-f")).Should(Exit(0))
   184  				})
   185  
   186  				It("binds the service to the app, displays OK and TIP", func() {
   187  					session := helpers.CF("bind-service", appName, serviceInstance)
   188  					Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   189  
   190  					Eventually(session.Out).Should(Say("OK"))
   191  					Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName))
   192  					Eventually(session).Should(Exit(0))
   193  				})
   194  
   195  				Context("when the service is already bound to an app", func() {
   196  					BeforeEach(func() {
   197  						Eventually(helpers.CF("bind-service", appName, serviceInstance)).Should(Exit(0))
   198  					})
   199  
   200  					It("displays OK and that the app is already bound to the service", func() {
   201  						session := helpers.CF("bind-service", appName, serviceInstance)
   202  
   203  						Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   204  						Eventually(session.Out).Should(Say("App %s is already bound to %s.", appName, serviceInstance))
   205  						Eventually(session.Out).Should(Say("OK"))
   206  
   207  						Eventually(session).Should(Exit(0))
   208  					})
   209  				})
   210  
   211  				Context("when configuration parameters are provided in a file", func() {
   212  					var configurationFile *os.File
   213  
   214  					Context("when the file-path does not exist", func() {
   215  						It("displays FAILED and the invalid configuration error", func() {
   216  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-do-not-exist")
   217  							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."))
   218  
   219  							Eventually(session).Should(Exit(1))
   220  						})
   221  					})
   222  
   223  					Context("when the file contians invalid json", func() {
   224  						BeforeEach(func() {
   225  							var err error
   226  							content := []byte("{i-am-very-bad-json")
   227  							configurationFile, err = ioutil.TempFile("", "CF_CLI")
   228  							Expect(err).ToNot(HaveOccurred())
   229  
   230  							_, err = configurationFile.Write(content)
   231  							Expect(err).ToNot(HaveOccurred())
   232  
   233  							err = configurationFile.Close()
   234  							Expect(err).ToNot(HaveOccurred())
   235  						})
   236  
   237  						AfterEach(func() {
   238  							os.Remove(configurationFile.Name())
   239  						})
   240  
   241  						It("displays FAILED and the invalid configuration error", func() {
   242  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name())
   243  							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."))
   244  
   245  							Eventually(session).Should(Exit(1))
   246  						})
   247  					})
   248  
   249  					Context("when the file-path is relative", func() {
   250  						BeforeEach(func() {
   251  							var err error
   252  							content := []byte("{\"i-am-good-json\":\"good-boy\"}")
   253  							configurationFile, err = ioutil.TempFile("", "CF_CLI")
   254  							Expect(err).ToNot(HaveOccurred())
   255  
   256  							_, err = configurationFile.Write(content)
   257  							Expect(err).ToNot(HaveOccurred())
   258  
   259  							err = configurationFile.Close()
   260  							Expect(err).ToNot(HaveOccurred())
   261  						})
   262  
   263  						AfterEach(func() {
   264  							os.Remove(configurationFile.Name())
   265  						})
   266  
   267  						It("binds the service to the app, displays OK and TIP", func() {
   268  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name())
   269  							Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   270  
   271  							Eventually(session.Out).Should(Say("OK"))
   272  							Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName))
   273  							Eventually(session).Should(Exit(0))
   274  						})
   275  					})
   276  
   277  					Context("when the file-path is absolute", func() {
   278  						BeforeEach(func() {
   279  							var err error
   280  							content := []byte("{\"i-am-good-json\":\"good-boy\"}")
   281  							configurationFile, err = ioutil.TempFile("", "CF_CLI")
   282  							Expect(err).ToNot(HaveOccurred())
   283  
   284  							_, err = configurationFile.Write(content)
   285  							Expect(err).ToNot(HaveOccurred())
   286  
   287  							err = configurationFile.Close()
   288  							Expect(err).ToNot(HaveOccurred())
   289  						})
   290  
   291  						It("binds the service to the app, displays OK and TIP", func() {
   292  							absolutePath, err := filepath.Abs(configurationFile.Name())
   293  							Expect(err).ToNot(HaveOccurred())
   294  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", absolutePath)
   295  							Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   296  
   297  							Eventually(session.Out).Should(Say("OK"))
   298  							Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName))
   299  							Eventually(session).Should(Exit(0))
   300  						})
   301  					})
   302  				})
   303  
   304  				Context("when configuration paramters are provided as in-line JSON", func() {
   305  					Context("when the JSON is invalid", func() {
   306  						It("displays FAILED and the invalid configuration error", func() {
   307  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-am-invalid-json")
   308  							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."))
   309  
   310  							Eventually(session).Should(Exit(1))
   311  						})
   312  					})
   313  
   314  					Context("when the JSON is valid", func() {
   315  						It("binds the service to the app, displays OK and TIP", func() {
   316  							session := helpers.CF("bind-service", appName, serviceInstance, "-c", "{\"i-am-valid-json\":\"dope dude\"}")
   317  							Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   318  
   319  							Eventually(session.Out).Should(Say("OK"))
   320  							Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName))
   321  							Eventually(session).Should(Exit(0))
   322  						})
   323  					})
   324  				})
   325  			})
   326  
   327  			Context("when the service is provided by a broker", func() {
   328  				var broker helpers.ServiceBroker
   329  
   330  				BeforeEach(func() {
   331  					broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan)
   332  					broker.Push()
   333  					broker.Configure()
   334  					broker.Create()
   335  
   336  					Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0))
   337  
   338  					Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0))
   339  				})
   340  
   341  				AfterEach(func() {
   342  					broker.Destroy()
   343  				})
   344  
   345  				It("binds the service to the app, displays OK and TIP", func() {
   346  					session := helpers.CF("bind-service", appName, serviceInstance, "-c", `{"wheres":"waldo"}`)
   347  					Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username))
   348  
   349  					Eventually(session.Out).Should(Say("OK"))
   350  					Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName))
   351  					Eventually(session).Should(Exit(0))
   352  
   353  					logsSession := helpers.CF("logs", broker.Name, "--recent")
   354  					Eventually(logsSession).Should(Say("{\"wheres\":\"waldo\"}"))
   355  					Eventually(logsSession).Should(Exit(0))
   356  				})
   357  			})
   358  		})
   359  	})
   360  })