github.com/jghiloni/cli@v6.28.1-0.20170628223758-0ce05fe032a2+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 Context("when the app does not exist", func() { 145 It("displays FAILED and app not found", func() { 146 session := helpers.CF("bind-service", "does-not-exist", serviceInstance) 147 Eventually(session.Out).Should(Say("FAILED")) 148 Eventually(session.Err).Should(Say("App %s not found", "does-not-exist")) 149 Eventually(session).Should(Exit(1)) 150 }) 151 }) 152 153 Context("when the app exists", func() { 154 BeforeEach(func() { 155 helpers.WithHelloWorldApp(func(appDir string) { 156 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 157 }) 158 }) 159 160 Context("when the service does not exist", func() { 161 It("displays FAILED and service not found", func() { 162 session := helpers.CF("bind-service", appName, "does-not-exist") 163 Eventually(session.Out).Should(Say("FAILED")) 164 Eventually(session.Err).Should(Say("Service instance %s not found", "does-not-exist")) 165 Eventually(session).Should(Exit(1)) 166 }) 167 }) 168 169 Context("when the service exists", func() { 170 BeforeEach(func() { 171 Eventually(helpers.CF("create-user-provided-service", serviceInstance, "-p", "{}")).Should(Exit(0)) 172 helpers.WithHelloWorldApp(func(appDir string) { 173 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 174 }) 175 }) 176 177 AfterEach(func() { 178 Eventually(helpers.CF("unbind-service", appName, serviceInstance)).Should(Exit(0)) 179 Eventually(helpers.CF("delete-service", serviceInstance, "-f")).Should(Exit(0)) 180 }) 181 182 It("binds the service to the app, displays OK and TIP", func() { 183 session := helpers.CF("bind-service", appName, serviceInstance) 184 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 185 186 Eventually(session.Out).Should(Say("OK")) 187 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 188 Eventually(session).Should(Exit(0)) 189 }) 190 191 Context("when the service is already bound to an app", func() { 192 BeforeEach(func() { 193 Eventually(helpers.CF("bind-service", appName, serviceInstance)).Should(Exit(0)) 194 }) 195 196 It("displays OK and that the app is already bound to the service", func() { 197 session := helpers.CF("bind-service", appName, serviceInstance) 198 199 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 200 Eventually(session.Out).Should(Say("App %s is already bound to %s.", appName, serviceInstance)) 201 Eventually(session.Out).Should(Say("OK")) 202 203 Eventually(session).Should(Exit(0)) 204 }) 205 }) 206 207 Context("when configuration parameters are provided in a file", func() { 208 var configurationFile *os.File 209 210 Context("when the file-path does not exist", func() { 211 It("displays FAILED and the invalid configuration error", func() { 212 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-do-not-exist") 213 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.")) 214 215 Eventually(session).Should(Exit(1)) 216 }) 217 }) 218 219 Context("when the file contians invalid json", func() { 220 BeforeEach(func() { 221 var err error 222 content := []byte("{i-am-very-bad-json") 223 configurationFile, err = ioutil.TempFile("", "CF_CLI") 224 Expect(err).ToNot(HaveOccurred()) 225 226 _, err = configurationFile.Write(content) 227 Expect(err).ToNot(HaveOccurred()) 228 229 err = configurationFile.Close() 230 Expect(err).ToNot(HaveOccurred()) 231 }) 232 233 AfterEach(func() { 234 os.Remove(configurationFile.Name()) 235 }) 236 237 It("displays FAILED and the invalid configuration error", func() { 238 session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name()) 239 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.")) 240 241 Eventually(session).Should(Exit(1)) 242 }) 243 }) 244 245 Context("when the file-path is relative", func() { 246 BeforeEach(func() { 247 var err error 248 content := []byte("{\"i-am-good-json\":\"good-boy\"}") 249 configurationFile, err = ioutil.TempFile("", "CF_CLI") 250 Expect(err).ToNot(HaveOccurred()) 251 252 _, err = configurationFile.Write(content) 253 Expect(err).ToNot(HaveOccurred()) 254 255 err = configurationFile.Close() 256 Expect(err).ToNot(HaveOccurred()) 257 }) 258 259 AfterEach(func() { 260 os.Remove(configurationFile.Name()) 261 }) 262 263 It("binds the service to the app, displays OK and TIP", func() { 264 session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name()) 265 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 266 267 Eventually(session.Out).Should(Say("OK")) 268 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 269 Eventually(session).Should(Exit(0)) 270 }) 271 }) 272 273 Context("when the file-path is absolute", func() { 274 BeforeEach(func() { 275 var err error 276 content := []byte("{\"i-am-good-json\":\"good-boy\"}") 277 configurationFile, err = ioutil.TempFile("", "CF_CLI") 278 Expect(err).ToNot(HaveOccurred()) 279 280 _, err = configurationFile.Write(content) 281 Expect(err).ToNot(HaveOccurred()) 282 283 err = configurationFile.Close() 284 Expect(err).ToNot(HaveOccurred()) 285 }) 286 287 It("binds the service to the app, displays OK and TIP", func() { 288 absolutePath, err := filepath.Abs(configurationFile.Name()) 289 Expect(err).ToNot(HaveOccurred()) 290 session := helpers.CF("bind-service", appName, serviceInstance, "-c", absolutePath) 291 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 292 293 Eventually(session.Out).Should(Say("OK")) 294 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 295 Eventually(session).Should(Exit(0)) 296 }) 297 }) 298 }) 299 300 Context("when configuration paramters are provided as in-line JSON", func() { 301 Context("when the JSON is invalid", func() { 302 It("displays FAILED and the invalid configuration error", func() { 303 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-am-invalid-json") 304 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.")) 305 306 Eventually(session).Should(Exit(1)) 307 }) 308 }) 309 310 Context("when the JSON is valid", func() { 311 It("binds the service to the app, displays OK and TIP", func() { 312 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "{\"i-am-valid-json\":\"dope dude\"}") 313 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 314 315 Eventually(session.Out).Should(Say("OK")) 316 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 317 Eventually(session).Should(Exit(0)) 318 }) 319 }) 320 }) 321 }) 322 323 Context("when the service is provided by a broker", func() { 324 var broker helpers.ServiceBroker 325 326 BeforeEach(func() { 327 broker = helpers.NewServiceBroker(helpers.PrefixedRandomName("SERVICE-BROKER"), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 328 broker.Push() 329 broker.Configure() 330 broker.Create() 331 332 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 333 334 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0)) 335 }) 336 337 AfterEach(func() { 338 broker.Destroy() 339 }) 340 341 It("binds the service to the app, displays OK and TIP", func() { 342 session := helpers.CF("bind-service", appName, serviceInstance, "-c", `{"wheres":"waldo"}`) 343 Eventually(session.Out).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 344 345 Eventually(session.Out).Should(Say("OK")) 346 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 347 Eventually(session).Should(Exit(0)) 348 349 logsSession := helpers.CF("logs", broker.Name, "--recent") 350 Eventually(logsSession).Should(Say("{\"wheres\":\"waldo\"}")) 351 Eventually(logsSession).Should(Exit(0)) 352 }) 353 }) 354 }) 355 }) 356 })