github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/integration/global/service_command_test.go (about) 1 package global 2 3 import ( 4 "code.cloudfoundry.org/cli/integration/helpers" 5 . "github.com/onsi/ginkgo" 6 . "github.com/onsi/gomega" 7 . "github.com/onsi/gomega/gbytes" 8 . "github.com/onsi/gomega/gexec" 9 ) 10 11 var _ = Describe("service command", func() { 12 var serviceInstanceName string 13 14 BeforeEach(func() { 15 serviceInstanceName = helpers.PrefixedRandomName("SI") 16 }) 17 18 Describe("help", func() { 19 Context("when --help flag is set", func() { 20 It("displays command usage to output", func() { 21 session := helpers.CF("service", "--help") 22 Eventually(session).Should(Say("NAME:")) 23 Eventually(session).Should(Say("\\s+service - Show service instance info")) 24 Eventually(session).Should(Say("USAGE:")) 25 Eventually(session).Should(Say("\\s+cf service SERVICE_INSTANCE")) 26 Eventually(session).Should(Say("OPTIONS:")) 27 Eventually(session).Should(Say("\\s+\\-\\-guid\\s+Retrieve and display the given service's guid\\. All other output for the service is suppressed\\.")) 28 Eventually(session).Should(Say("SEE ALSO:")) 29 Eventually(session).Should(Say("\\s+bind-service, rename-service, update-service")) 30 Eventually(session).Should(Exit(0)) 31 }) 32 }) 33 }) 34 35 Context("when the environment is not setup correctly", func() { 36 It("fails with the appropriate errors", func() { 37 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "service", "some-service") 38 }) 39 }) 40 41 Context("when an api is targeted, the user is logged in, and an org and space are targeted", func() { 42 var ( 43 orgName string 44 spaceName string 45 userName string 46 ) 47 48 BeforeEach(func() { 49 orgName = helpers.NewOrgName() 50 spaceName = helpers.NewSpaceName() 51 setupCF(orgName, spaceName) 52 53 userName, _ = helpers.GetCredentials() 54 }) 55 56 AfterEach(func() { 57 helpers.QuickDeleteOrg(orgName) 58 }) 59 60 Context("when the service instance does not exist", func() { 61 It("returns an error and exits 1", func() { 62 session := helpers.CF("service", serviceInstanceName) 63 Eventually(session).Should(Say("Showing info of service %s in org %s / space %s as %s", serviceInstanceName, orgName, spaceName, userName)) 64 Eventually(session).Should(Say("")) 65 Eventually(session).Should(Say("FAILED")) 66 Eventually(session.Err).Should(Say("Service instance %s not found", serviceInstanceName)) 67 Eventually(session).Should(Exit(1)) 68 }) 69 }) 70 71 Context("when the service instance belongs to this space", func() { 72 Context("when the service instance is a user provided service instance", func() { 73 BeforeEach(func() { 74 Eventually(helpers.CF("create-user-provided-service", serviceInstanceName)).Should(Exit(0)) 75 }) 76 77 AfterEach(func() { 78 Eventually(helpers.CF("delete-service", serviceInstanceName, "-f")).Should(Exit(0)) 79 }) 80 81 Context("when the --guid flag is provided", func() { 82 It("displays the service instance GUID", func() { 83 session := helpers.CF("service", serviceInstanceName, "--guid") 84 Consistently(session).ShouldNot(Say("Showing info of service %s in org %s / space %s as %s", serviceInstanceName, orgName, spaceName, userName)) 85 Eventually(session).Should(Say(helpers.UserProvidedServiceInstanceGUID(serviceInstanceName))) 86 Eventually(session).Should(Exit(0)) 87 }) 88 }) 89 90 Context("when apps are bound to the service instance", func() { 91 var ( 92 appName1 string 93 appName2 string 94 ) 95 96 BeforeEach(func() { 97 appName1 = helpers.NewAppName() 98 appName2 = helpers.NewAppName() 99 helpers.WithHelloWorldApp(func(appDir string) { 100 Eventually(helpers.CF("push", appName1, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 101 Eventually(helpers.CF("push", appName2, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 102 }) 103 Eventually(helpers.CF("bind-service", appName1, serviceInstanceName)).Should(Exit(0)) 104 Eventually(helpers.CF("bind-service", appName2, serviceInstanceName)).Should(Exit(0)) 105 }) 106 107 AfterEach(func() { 108 Eventually(helpers.CF("unbind-service", appName1, serviceInstanceName)).Should(Exit(0)) 109 Eventually(helpers.CF("unbind-service", appName2, serviceInstanceName)).Should(Exit(0)) 110 Eventually(helpers.CF("delete", appName1, "-f")).Should(Exit(0)) 111 Eventually(helpers.CF("delete", appName2, "-f")).Should(Exit(0)) 112 }) 113 114 It("displays service instance info", func() { 115 session := helpers.CF("service", serviceInstanceName) 116 Eventually(session).Should(Say("Showing info of service %s in org %s / space %s as %s", serviceInstanceName, orgName, spaceName, userName)) 117 Eventually(session).Should(Say("")) 118 Eventually(session).Should(Say("name:\\s+%s", serviceInstanceName)) 119 Consistently(session).ShouldNot(Say("shared from:")) 120 Eventually(session).Should(Say("service:\\s+user-provided")) 121 Eventually(session).Should(Say("bound apps:\\s+%s, %s", appName1, appName2)) 122 Consistently(session).ShouldNot(Say("tags:")) 123 Consistently(session).ShouldNot(Say("plan:")) 124 Consistently(session).ShouldNot(Say("description:")) 125 Consistently(session).ShouldNot(Say("documentation:")) 126 Consistently(session).ShouldNot(Say("dashboard:")) 127 Consistently(session).ShouldNot(Say("shared with spaces:")) 128 Consistently(session).ShouldNot(Say("last operation")) 129 Consistently(session).ShouldNot(Say("status:")) 130 Consistently(session).ShouldNot(Say("message:")) 131 Consistently(session).ShouldNot(Say("started:")) 132 Consistently(session).ShouldNot(Say("updated:")) 133 Eventually(session).Should(Exit(0)) 134 }) 135 }) 136 }) 137 138 Context("when the service instance is a managed service instance", func() { 139 var ( 140 domain string 141 service string 142 servicePlan string 143 broker helpers.ServiceBroker 144 ) 145 146 BeforeEach(func() { 147 domain = defaultSharedDomain() 148 service = helpers.PrefixedRandomName("SERVICE") 149 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 150 151 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 152 broker.Push() 153 broker.Configure(true) 154 broker.Create() 155 156 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 157 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstanceName, "-t", "database, email")).Should(Exit(0)) 158 }) 159 160 AfterEach(func() { 161 Eventually(helpers.CF("delete-service", serviceInstanceName, "-f")).Should(Exit(0)) 162 broker.Destroy() 163 }) 164 165 Context("when the --guid flag is provided", func() { 166 It("displays the service instance GUID", func() { 167 session := helpers.CF("service", serviceInstanceName, "--guid") 168 Consistently(session).ShouldNot(Say("Showing info of service %s in org %s / space %s as %s", serviceInstanceName, orgName, spaceName, userName)) 169 Eventually(session).Should(Say(helpers.ManagedServiceInstanceGUID(serviceInstanceName))) 170 Eventually(session).Should(Exit(0)) 171 }) 172 }) 173 174 Context("when apps are bound to the service instance", func() { 175 var ( 176 appName1 string 177 appName2 string 178 ) 179 180 BeforeEach(func() { 181 appName1 = helpers.NewAppName() 182 appName2 = helpers.NewAppName() 183 helpers.WithHelloWorldApp(func(appDir string) { 184 Eventually(helpers.CF("push", appName1, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 185 Eventually(helpers.CF("push", appName2, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 186 }) 187 Eventually(helpers.CF("bind-service", appName1, serviceInstanceName)).Should(Exit(0)) 188 Eventually(helpers.CF("bind-service", appName2, serviceInstanceName)).Should(Exit(0)) 189 }) 190 191 AfterEach(func() { 192 Eventually(helpers.CF("unbind-service", appName1, serviceInstanceName)).Should(Exit(0)) 193 Eventually(helpers.CF("unbind-service", appName2, serviceInstanceName)).Should(Exit(0)) 194 Eventually(helpers.CF("delete", appName1, "-f")).Should(Exit(0)) 195 Eventually(helpers.CF("delete", appName2, "-f")).Should(Exit(0)) 196 }) 197 198 It("displays service instance info", func() { 199 session := helpers.CF("service", serviceInstanceName) 200 Eventually(session).Should(Say("Showing info of service %s in org %s / space %s as %s\\.\\.\\.", serviceInstanceName, orgName, spaceName, userName)) 201 Eventually(session).Should(Say("\n\n")) 202 Eventually(session).Should(Say("name:\\s+%s", serviceInstanceName)) 203 Consistently(session).ShouldNot(Say("shared from:")) 204 Eventually(session).Should(Say("service:\\s+%s", service)) 205 Eventually(session).Should(Say("bound apps:\\s+%s, %s", appName1, appName2)) 206 Eventually(session).Should(Say("tags:\\s+database, email")) 207 Eventually(session).Should(Say("plan:\\s+%s", servicePlan)) 208 Eventually(session).Should(Say("description:\\s+fake service")) 209 Eventually(session).Should(Say("documentation:")) 210 Eventually(session).Should(Say("dashboard:\\s+http://example\\.com")) 211 Eventually(session).Should(Say("\n\n")) 212 Consistently(session).ShouldNot(Say("shared with spaces:")) 213 Eventually(session).Should(Say("Showing status of last operation from service %s\\.\\.\\.", serviceInstanceName)) 214 Eventually(session).Should(Say("\n\n")) 215 Eventually(session).Should(Say("status:\\s+create succeeded")) 216 Eventually(session).Should(Say("message:")) 217 Eventually(session).Should(Say("started:\\s+\\d{4}-[01]\\d-[0-3]\\dT[0-2][0-9]:[0-5]\\d:[0-5]\\dZ")) 218 Eventually(session).Should(Say("updated:\\s+\\d{4}-[01]\\d-[0-3]\\dT[0-2][0-9]:[0-5]\\d:[0-5]\\dZ")) 219 220 Eventually(session).Should(Exit(0)) 221 }) 222 }) 223 }) 224 }) 225 }) 226 227 Context("service instance sharing when there are multiple spaces", func() { 228 var ( 229 orgName string 230 sourceSpaceName string 231 232 service string 233 servicePlan string 234 broker helpers.ServiceBroker 235 ) 236 237 BeforeEach(func() { 238 orgName = helpers.NewOrgName() 239 sourceSpaceName = helpers.NewSpaceName() 240 setupCF(orgName, sourceSpaceName) 241 242 domain := defaultSharedDomain() 243 service = helpers.PrefixedRandomName("SERVICE") 244 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 245 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 246 broker.Push() 247 broker.Configure(true) 248 broker.Create() 249 250 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 251 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstanceName)).Should(Exit(0)) 252 }) 253 254 AfterEach(func() { 255 // need to login as admin 256 helpers.LoginCF() 257 helpers.TargetOrgAndSpace(orgName, sourceSpaceName) 258 broker.Destroy() 259 helpers.QuickDeleteOrg(orgName) 260 }) 261 262 Context("service has no type of shares", func() { 263 Context("when the service is shareable", func() { 264 It("should not display shared from or shared with information, but DOES display not currently shared info", func() { 265 session := helpers.CF("service", serviceInstanceName) 266 Eventually(session).Should(Say("This service is not currently shared.")) 267 Eventually(session).Should(Exit(0)) 268 }) 269 }) 270 }) 271 272 Context("service is shared between two spaces", func() { 273 var ( 274 targetSpaceName string 275 ) 276 277 BeforeEach(func() { 278 targetSpaceName = helpers.NewSpaceName() 279 helpers.CreateOrgAndSpace(orgName, targetSpaceName) 280 helpers.TargetOrgAndSpace(orgName, sourceSpaceName) 281 Eventually(helpers.CF("v3-share-service", serviceInstanceName, "-s", targetSpaceName)).Should(Exit(0)) 282 }) 283 284 Context("when the user is targeted to the source space", func() { 285 Context("when there are externally bound apps to the service", func() { 286 BeforeEach(func() { 287 helpers.TargetOrgAndSpace(orgName, targetSpaceName) 288 helpers.WithHelloWorldApp(func(appDir string) { 289 appName1 := helpers.NewAppName() 290 Eventually(helpers.CF("push", appName1, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 291 Eventually(helpers.CF("bind-service", appName1, serviceInstanceName)).Should(Exit(0)) 292 293 appName2 := helpers.NewAppName() 294 Eventually(helpers.CF("push", appName2, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 295 Eventually(helpers.CF("bind-service", appName2, serviceInstanceName)).Should(Exit(0)) 296 }) 297 helpers.TargetOrgAndSpace(orgName, sourceSpaceName) 298 }) 299 300 It("should display the number of bound apps next to the target space name", func() { 301 session := helpers.CF("service", serviceInstanceName) 302 Eventually(session).Should(Say("shared with spaces:")) 303 Eventually(session).Should(Say("org\\s+space\\s+bindings")) 304 Eventually(session).Should(Say("%s\\s+%s\\s+2", orgName, targetSpaceName)) 305 Eventually(session).Should(Exit(0)) 306 }) 307 }) 308 309 Context("when there are no externally bound apps to the service", func() { 310 It("should NOT display the number of bound apps next to the target space name", func() { 311 session := helpers.CF("service", serviceInstanceName) 312 Eventually(session).Should(Say("shared with spaces:")) 313 Eventually(session).Should(Say("org\\s+space\\s+bindings")) 314 Eventually(session).Should(Exit(0)) 315 }) 316 }) 317 318 Context("when the service is no longer shareable", func() { 319 Context("due to global settings", func() { 320 BeforeEach(func() { 321 helpers.DisableFeatureFlag("service_instance_sharing") 322 }) 323 324 AfterEach(func() { 325 helpers.EnableFeatureFlag("service_instance_sharing") 326 }) 327 328 It("should display that the service instance feature flag is disabled", func() { 329 session := helpers.CF("service", serviceInstanceName) 330 Eventually(session).Should(Say(`The "service_instance_sharing" feature flag is disabled for this Cloud Foundry platform.`)) 331 Eventually(session).Should(Exit(0)) 332 }) 333 }) 334 335 Context("due to service broker settings", func() { 336 BeforeEach(func() { 337 broker.Configure(false) 338 broker.Update() 339 }) 340 341 It("should display that service instance sharing is disabled for this service", func() { 342 session := helpers.CF("service", serviceInstanceName) 343 Eventually(session).Should(Say("Service instance sharing is disabled for this service.")) 344 Eventually(session).Should(Exit(0)) 345 }) 346 }) 347 348 Context("due to global settings AND service broker settings", func() { 349 BeforeEach(func() { 350 helpers.DisableFeatureFlag("service_instance_sharing") 351 broker.Configure(false) 352 broker.Update() 353 }) 354 355 AfterEach(func() { 356 helpers.EnableFeatureFlag("service_instance_sharing") 357 }) 358 359 It("should display that service instance sharing is disabled for this service", func() { 360 session := helpers.CF("service", serviceInstanceName) 361 Eventually(session).Should(Say(`The "service_instance_sharing" feature flag is disabled for this Cloud Foundry platform. Also, service instance sharing is disabled for this service.`)) 362 Eventually(session).Should(Exit(0)) 363 }) 364 }) 365 }) 366 }) 367 368 Context("when the user is targeted to the target space", func() { 369 var appName1, appName2 string 370 371 BeforeEach(func() { 372 helpers.TargetOrgAndSpace(orgName, targetSpaceName) 373 helpers.WithHelloWorldApp(func(appDir string) { 374 appName1 = helpers.NewAppName() 375 Eventually(helpers.CF("push", appName1, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 376 Eventually(helpers.CF("bind-service", appName1, serviceInstanceName)).Should(Exit(0)) 377 378 appName2 = helpers.NewAppName() 379 Eventually(helpers.CF("push", appName2, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 380 Eventually(helpers.CF("bind-service", appName2, serviceInstanceName)).Should(Exit(0)) 381 }) 382 }) 383 384 Context("when there are bound apps to the service", func() { 385 It("should display the bound apps", func() { 386 session := helpers.CF("service", serviceInstanceName) 387 Eventually(session).Should(Say("shared from org/space:\\s+%s / %s", orgName, sourceSpaceName)) 388 Eventually(session).Should(Say("bound apps:\\s+(%s, %s|%s, %s)", appName1, appName2, appName2, appName1)) 389 Eventually(session).Should(Exit(0)) 390 }) 391 }) 392 }) 393 }) 394 }) 395 })