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