github.com/sleungcy-sap/cli@v7.1.0+incompatible/integration/v7/isolated/bind_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("bind-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("bind-service", "--help") 23 Eventually(session).Should(Say("NAME:")) 24 Eventually(session).Should(Say("bind-service - Bind a service instance to an app")) 25 26 Eventually(session).Should(Say("USAGE:")) 27 Eventually(session).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE \\[-c PARAMETERS_AS_JSON\\] \\[--binding-name BINDING_NAME\\]")) 28 Eventually(session).Should(Say("Optionally provide service-specific configuration parameters in a valid JSON object in-line:")) 29 Eventually(session).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE -c '{\"name\":\"value\",\"name\":\"value\"}'")) 30 Eventually(session).Should(Say("Optionally provide a file containing service-specific configuration parameters in a valid JSON object.")) 31 Eventually(session).Should(Say("The path to the parameters file can be an absolute or relative path to a file.")) 32 Eventually(session).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE -c PATH_TO_FILE")) 33 Eventually(session).Should(Say("Example of valid JSON object:")) 34 Eventually(session).Should(Say("{")) 35 Eventually(session).Should(Say("\"permissions\": \"read-only\"")) 36 Eventually(session).Should(Say("}")) 37 Eventually(session).Should(Say("Optionally provide a binding name for the association between an app and a service instance:")) 38 Eventually(session).Should(Say("cf bind-service APP_NAME SERVICE_INSTANCE --binding-name BINDING_NAME")) 39 Eventually(session).Should(Say("EXAMPLES:")) 40 Eventually(session).Should(Say("Linux/Mac:")) 41 Eventually(session).Should(Say("cf bind-service myapp mydb -c '{\"permissions\":\"read-only\"}'")) 42 Eventually(session).Should(Say("Windows Command Line:")) 43 Eventually(session).Should(Say("cf bind-service myapp mydb -c \"{\\\\\"permissions\\\\\":\\\\\"read-only\\\\\"}\"")) 44 Eventually(session).Should(Say("Windows PowerShell:")) 45 Eventually(session).Should(Say("cf bind-service myapp mydb -c '{\\\\\"permissions\\\\\":\\\\\"read-only\\\\\"}'")) 46 Eventually(session).Should(Say("cf bind-service myapp mydb -c ~/workspace/tmp/instance_config.json --binding-name BINDING_NAME")) 47 Eventually(session).Should(Say("ALIAS:")) 48 Eventually(session).Should(Say("bs")) 49 Eventually(session).Should(Say("OPTIONS:")) 50 Eventually(session).Should(Say("--binding-name\\s+Name to expose service instance to app process with \\(Default: service instance name\\)")) 51 Eventually(session).Should(Say("-c\\s+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("SEE ALSO:")) 53 Eventually(session).Should(Say("services")) 54 Eventually(session).Should(Exit(0)) 55 }) 56 }) 57 }) 58 59 var ( 60 serviceInstance string 61 appName string 62 ) 63 64 BeforeEach(func() { 65 serviceInstance = helpers.PrefixedRandomName("si") 66 appName = helpers.PrefixedRandomName("app") 67 }) 68 69 When("the environment is not setup correctly", func() { 70 It("fails with the appropriate errors", func() { 71 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "bind-service", "app-name", "service-name") 72 }) 73 }) 74 75 When("provided invalid flag values", func() { 76 When("the --binding-name flag is provided and its value is the empty string", func() { 77 It("returns an invalid usage error and the help text", func() { 78 session := helpers.CF("bind-service", appName, serviceInstance, "--binding-name", "") 79 Eventually(session.Err).Should(Say("--binding-name must be at least 1 character in length")) 80 81 Eventually(session).Should(Say("NAME:")) 82 Eventually(session).Should(Exit(1)) 83 }) 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 username, _ = helpers.GetCredentials() 98 99 helpers.SetupCF(org, space) 100 }) 101 102 AfterEach(func() { 103 helpers.QuickDeleteOrg(org) 104 }) 105 106 When("the app does not exist", func() { 107 It("displays FAILED and app not found", func() { 108 session := helpers.CF("bind-service", "does-not-exist", serviceInstance) 109 Eventually(session).Should(Say("FAILED")) 110 Eventually(session.Err).Should(Say("App '%s' not found", "does-not-exist")) 111 Eventually(session).Should(Exit(1)) 112 }) 113 }) 114 115 When("the app exists", func() { 116 BeforeEach(func() { 117 helpers.WithHelloWorldApp(func(appDir string) { 118 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 119 }) 120 }) 121 122 When("the service does not exist", func() { 123 It("displays FAILED and service not found", func() { 124 session := helpers.CF("bind-service", appName, "does-not-exist") 125 Eventually(session).Should(Say("FAILED")) 126 Eventually(session.Err).Should(Say("Service instance %s not found", "does-not-exist")) 127 Eventually(session).Should(Exit(1)) 128 }) 129 }) 130 131 When("the service exists", func() { 132 BeforeEach(func() { 133 Eventually(helpers.CF("create-user-provided-service", serviceInstance, "-p", "{}")).Should(Exit(0)) 134 helpers.WithHelloWorldApp(func(appDir string) { 135 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 136 }) 137 }) 138 139 AfterEach(func() { 140 Eventually(helpers.CF("unbind-service", appName, serviceInstance)).Should(Exit(0)) 141 Eventually(helpers.CF("delete-service", serviceInstance, "-f")).Should(Exit(0)) 142 }) 143 144 It("binds the service to the app, displays OK and TIP", func() { 145 session := helpers.CF("bind-service", appName, serviceInstance) 146 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 147 148 Eventually(session).Should(Say("OK")) 149 Eventually(session).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 150 Eventually(session).Should(Exit(0)) 151 }) 152 153 When("the service is already bound to an app", func() { 154 BeforeEach(func() { 155 Eventually(helpers.CF("bind-service", appName, serviceInstance)).Should(Exit(0)) 156 }) 157 158 It("displays OK and that the app is already bound to the service", func() { 159 session := helpers.CF("bind-service", appName, serviceInstance) 160 161 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 162 Eventually(session).Should(Say("App %s is already bound to %s.", appName, serviceInstance)) 163 Eventually(session).Should(Say("OK")) 164 165 Eventually(session).Should(Exit(0)) 166 }) 167 }) 168 169 When("the --binding-name flag is provided and the value is a non-empty string", func() { 170 It("binds the service to the app, displays OK and TIP", func() { 171 session := helpers.CF("bind-service", appName, serviceInstance, "--binding-name", "i-am-a-binding") 172 Eventually(session.Out).Should(Say("Binding service %s to app %s with binding name %s in org %s / space %s as %s...", serviceInstance, appName, "i-am-a-binding", org, space, username)) 173 174 Eventually(session.Out).Should(Say("OK")) 175 Eventually(session.Out).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 176 Eventually(session).Should(Exit(0)) 177 }) 178 }) 179 180 When("configuration parameters are provided in a file", func() { 181 var configurationFile *os.File 182 183 When("the file-path does not exist", func() { 184 It("displays FAILED and the invalid configuration error", func() { 185 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-do-not-exist") 186 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.")) 187 188 Eventually(session).Should(Exit(1)) 189 }) 190 }) 191 192 When("the file contians invalid json", func() { 193 BeforeEach(func() { 194 var err error 195 content := []byte("{i-am-very-bad-json") 196 configurationFile, err = ioutil.TempFile("", "CF_CLI") 197 Expect(err).ToNot(HaveOccurred()) 198 199 _, err = configurationFile.Write(content) 200 Expect(err).ToNot(HaveOccurred()) 201 202 err = configurationFile.Close() 203 Expect(err).ToNot(HaveOccurred()) 204 }) 205 206 AfterEach(func() { 207 Expect(os.RemoveAll(configurationFile.Name())).ToNot(HaveOccurred()) 208 }) 209 210 It("displays FAILED and the invalid configuration error", func() { 211 session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name()) 212 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.")) 213 214 Eventually(session).Should(Exit(1)) 215 }) 216 }) 217 218 When("the file-path is relative", func() { 219 BeforeEach(func() { 220 var err error 221 content := []byte("{\"i-am-good-json\":\"good-boy\"}") 222 configurationFile, err = ioutil.TempFile("", "CF_CLI") 223 Expect(err).ToNot(HaveOccurred()) 224 225 _, err = configurationFile.Write(content) 226 Expect(err).ToNot(HaveOccurred()) 227 228 err = configurationFile.Close() 229 Expect(err).ToNot(HaveOccurred()) 230 }) 231 232 AfterEach(func() { 233 Expect(os.RemoveAll(configurationFile.Name())).ToNot(HaveOccurred()) 234 }) 235 236 It("binds the service to the app, displays OK and TIP", func() { 237 session := helpers.CF("bind-service", appName, serviceInstance, "-c", configurationFile.Name()) 238 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 239 240 Eventually(session).Should(Say("OK")) 241 Eventually(session).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 242 Eventually(session).Should(Exit(0)) 243 }) 244 }) 245 246 When("the file-path is absolute", func() { 247 BeforeEach(func() { 248 var err error 249 content := []byte("{\"i-am-good-json\":\"good-boy\"}") 250 configurationFile, err = ioutil.TempFile("", "CF_CLI") 251 Expect(err).ToNot(HaveOccurred()) 252 253 _, err = configurationFile.Write(content) 254 Expect(err).ToNot(HaveOccurred()) 255 256 err = configurationFile.Close() 257 Expect(err).ToNot(HaveOccurred()) 258 }) 259 260 AfterEach(func() { 261 Expect(os.RemoveAll(configurationFile.Name())).ToNot(HaveOccurred()) 262 }) 263 264 It("binds the service to the app, displays OK and TIP", func() { 265 absolutePath, err := filepath.Abs(configurationFile.Name()) 266 Expect(err).ToNot(HaveOccurred()) 267 session := helpers.CF("bind-service", appName, serviceInstance, "-c", absolutePath) 268 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 269 270 Eventually(session).Should(Say("OK")) 271 Eventually(session).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 272 Eventually(session).Should(Exit(0)) 273 }) 274 }) 275 }) 276 277 When("configuration paramters are provided as in-line JSON", func() { 278 When("the JSON is invalid", func() { 279 It("displays FAILED and the invalid configuration error", func() { 280 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "i-am-invalid-json") 281 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.")) 282 283 Eventually(session).Should(Exit(1)) 284 }) 285 }) 286 287 When("the JSON is valid", func() { 288 It("binds the service to the app, displays OK and TIP", func() { 289 session := helpers.CF("bind-service", appName, serviceInstance, "-c", "{\"i-am-valid-json\":\"dope dude\"}") 290 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 291 292 Eventually(session).Should(Say("OK")) 293 Eventually(session).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 294 Eventually(session).Should(Exit(0)) 295 }) 296 }) 297 }) 298 }) 299 300 When("the service is provided by a broker", func() { 301 var broker *servicebrokerstub.ServiceBrokerStub 302 303 AfterEach(func() { 304 broker.Forget() 305 }) 306 307 When("the service binding is blocking", func() { 308 BeforeEach(func() { 309 broker = servicebrokerstub.EnableServiceAccess() 310 311 Eventually(helpers.CF("create-service", broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstance)).Should(Exit(0)) 312 }) 313 314 It("binds the service to the app, displays OK and TIP", func() { 315 session := helpers.CF("bind-service", appName, serviceInstance, "-c", `{"wheres":"waldo"}`) 316 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 317 318 Eventually(session).Should(Say("OK")) 319 Eventually(session).Should(Say("TIP: Use 'cf restage %s' to ensure your env variable changes take effect", appName)) 320 Eventually(session).Should(Exit(0)) 321 322 session = helpers.CF("service", serviceInstance) 323 Eventually(session).Should(Say(appName)) 324 Eventually(session).Should(Exit(0)) 325 }) 326 }) 327 328 When("the service binding is asynchronous", func() { 329 BeforeEach(func() { 330 broker = servicebrokerstub.New().WithAsyncDelay(time.Millisecond).EnableServiceAccess() 331 332 Eventually(helpers.CF("create-service", broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstance)).Should(Exit(0)) 333 334 Eventually(func() *Session { 335 session := helpers.CF("service", serviceInstance) 336 return session.Wait() 337 }, time.Minute*5, time.Second*5).Should(Say("create succeeded")) 338 }) 339 340 It("binds the service to the app, displays OK and TIP", func() { 341 session := helpers.CF("bind-service", appName, serviceInstance, "-c", `{"wheres":"waldo"}`) 342 Eventually(session).Should(Say("Binding service %s to app %s in org %s / space %s as %s...", serviceInstance, appName, org, space, username)) 343 344 Eventually(session).Should(Say("OK")) 345 Eventually(session).Should(Say("Binding in progress. Use 'cf service %s' to check operation status.", serviceInstance)) 346 Eventually(session).Should(Say("TIP: Once this operation succeeds, use 'cf restage %s' to ensure your env variable changes take effect", appName)) 347 Eventually(session).Should(Exit(0)) 348 349 session = helpers.CF("service", serviceInstance) 350 Eventually(session).Should(Say(appName)) 351 Eventually(session).Should(Exit(0)) 352 }) 353 }) 354 }) 355 }) 356 }) 357 })