github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/integration/v7/isolated/unbind_service_command_test.go (about) 1 package isolated 2 3 import ( 4 "time" 5 6 "code.cloudfoundry.org/cli/integration/helpers" 7 "code.cloudfoundry.org/cli/integration/helpers/servicebrokerstub" 8 "code.cloudfoundry.org/cli/resources" 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("unbind-service command", func() { 16 const command = "unbind-service" 17 18 Describe("help", func() { 19 matchHelpMessage := SatisfyAll( 20 Say(`NAME:\n`), 21 Say(`\s+unbind-service - Unbind a service instance from an app\n`), 22 Say(`\n`), 23 Say(`USAGE:\n`), 24 Say(`\s+cf unbind-service APP_NAME SERVICE_INSTANCE\n`), 25 Say(`\n`), 26 Say(`ALIAS:\n`), 27 Say(`\s+us\n`), 28 Say(`\n`), 29 Say(`OPTIONS:\n`), 30 Say(`\s+--wait, -w\s+Wait for the operation to complete\n`), 31 Say(`\n`), 32 Say(`SEE ALSO:\n`), 33 Say(`\s+apps, delete-service, services\n`), 34 ) 35 36 When("the -h flag is specified", func() { 37 It("succeeds and prints help", func() { 38 session := helpers.CF(command, "-h") 39 Eventually(session).Should(Exit(0)) 40 Expect(session.Out).To(matchHelpMessage) 41 }) 42 }) 43 44 When("the --help flag is specified", func() { 45 It("succeeds and prints help", func() { 46 session := helpers.CF(command, "--help") 47 Eventually(session).Should(Exit(0)) 48 Expect(session.Out).To(matchHelpMessage) 49 }) 50 }) 51 52 When("no arguments are provided", func() { 53 It("displays a warning, the help text, and exits 1", func() { 54 session := helpers.CF(command) 55 Eventually(session).Should(Exit(1)) 56 Expect(session.Err).To(Say("Incorrect Usage: the required arguments `APP_NAME` and `SERVICE_INSTANCE` were not provided")) 57 Expect(session.Out).To(matchHelpMessage) 58 }) 59 }) 60 61 When("unknown flag is passed", func() { 62 It("displays a warning, the help text, and exits 1", func() { 63 session := helpers.CF(command, "-u") 64 Eventually(session).Should(Exit(1)) 65 Expect(session.Err).To(Say("Incorrect Usage: unknown flag `u")) 66 Expect(session.Out).To(matchHelpMessage) 67 }) 68 }) 69 }) 70 71 When("the environment is not setup correctly", func() { 72 It("fails with the appropriate errors", func() { 73 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "bind-service", "app-name", "service-name") 74 }) 75 }) 76 77 When("targeting a space", func() { 78 var ( 79 orgName string 80 spaceName string 81 username string 82 ) 83 84 getBindingCount := func(serviceInstanceName string) int { 85 var receiver struct { 86 Resources []resources.ServiceCredentialBinding `json:"resources"` 87 } 88 helpers.Curl(&receiver, "/v3/service_credential_bindings?service_instance_names=%s", serviceInstanceName) 89 return len(receiver.Resources) 90 } 91 92 BeforeEach(func() { 93 orgName = helpers.NewOrgName() 94 spaceName = helpers.NewSpaceName() 95 helpers.SetupCF(orgName, spaceName) 96 97 username, _ = helpers.GetCredentials() 98 }) 99 100 AfterEach(func() { 101 helpers.QuickDeleteOrg(orgName) 102 }) 103 104 Context("user-provided route service", func() { 105 var ( 106 serviceInstanceName string 107 appName string 108 ) 109 110 BeforeEach(func() { 111 serviceInstanceName = helpers.NewServiceInstanceName() 112 Eventually(helpers.CF("cups", serviceInstanceName)).Should(Exit(0)) 113 114 appName = helpers.NewAppName() 115 helpers.WithHelloWorldApp(func(appDir string) { 116 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 117 }) 118 119 Eventually(helpers.CF("bind-service", appName, serviceInstanceName, "--wait")).Should(Exit(0)) 120 }) 121 122 It("deletes the binding", func() { 123 session := helpers.CF(command, appName, serviceInstanceName) 124 Eventually(session).Should(Exit(0)) 125 126 Expect(session.Out).To(SatisfyAll( 127 Say(`Unbinding app %s from service %s in org %s / space %s as %s\.\.\.\n`, appName, serviceInstanceName, orgName, spaceName, username), 128 Say(`OK\n`), 129 )) 130 131 Expect(string(session.Err.Contents())).To(BeEmpty()) 132 Expect(getBindingCount(serviceInstanceName)).To(BeZero()) 133 }) 134 }) 135 136 Context("managed service instance with synchronous broker response", func() { 137 var ( 138 broker *servicebrokerstub.ServiceBrokerStub 139 serviceInstanceName string 140 appName string 141 ) 142 143 BeforeEach(func() { 144 broker = servicebrokerstub.EnableServiceAccess() 145 serviceInstanceName = helpers.NewServiceInstanceName() 146 helpers.CreateManagedServiceInstance(broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstanceName) 147 148 appName = helpers.NewAppName() 149 helpers.WithHelloWorldApp(func(appDir string) { 150 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 151 }) 152 153 Eventually(helpers.CF("bind-service", appName, serviceInstanceName, "--wait")).Should(Exit(0)) 154 }) 155 156 AfterEach(func() { 157 broker.Forget() 158 }) 159 160 It("deletes the binding", func() { 161 session := helpers.CF(command, appName, serviceInstanceName) 162 Eventually(session).Should(Exit(0)) 163 164 Expect(session.Out).To(SatisfyAll( 165 Say(`Unbinding app %s from service %s in org %s / space %s as %s\.\.\.\n`, appName, serviceInstanceName, orgName, spaceName, username), 166 Say(`OK\n`), 167 )) 168 169 Expect(string(session.Err.Contents())).To(BeEmpty()) 170 Expect(getBindingCount(serviceInstanceName)).To(BeZero()) 171 }) 172 }) 173 174 Context("managed service instance with asynchronous broker response", func() { 175 var ( 176 broker *servicebrokerstub.ServiceBrokerStub 177 serviceInstanceName string 178 appName string 179 ) 180 181 BeforeEach(func() { 182 broker = servicebrokerstub.EnableServiceAccess() 183 serviceInstanceName = helpers.NewServiceInstanceName() 184 helpers.CreateManagedServiceInstance(broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstanceName) 185 186 appName = helpers.NewAppName() 187 helpers.WithHelloWorldApp(func(appDir string) { 188 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 189 }) 190 191 Eventually(helpers.CF("bind-service", appName, serviceInstanceName, "--wait")).Should(Exit(0)) 192 193 broker.WithAsyncDelay(time.Second).Configure() 194 }) 195 196 AfterEach(func() { 197 broker.Forget() 198 }) 199 200 It("starts to delete the binding", func() { 201 session := helpers.CF(command, appName, serviceInstanceName) 202 Eventually(session).Should(Exit(0)) 203 204 Expect(session.Out).To(SatisfyAll( 205 Say(`Unbinding app %s from service %s in org %s / space %s as %s\.\.\.\n`, appName, serviceInstanceName, orgName, spaceName, username), 206 Say(`OK\n`), 207 Say(`Unbinding in progress. Use 'cf service %s' to check operation status\.\n`, serviceInstanceName), 208 )) 209 210 Expect(string(session.Err.Contents())).To(BeEmpty()) 211 Expect(getBindingCount(serviceInstanceName)).NotTo(BeZero()) 212 }) 213 214 When("--wait flag specified", func() { 215 It("waits for completion", func() { 216 session := helpers.CF(command, appName, serviceInstanceName, "--wait") 217 Eventually(session).Should(Exit(0)) 218 219 Expect(session.Out).To(SatisfyAll( 220 Say(`Unbinding app %s from service %s in org %s / space %s as %s\.\.\.\n`, appName, serviceInstanceName, orgName, spaceName, username), 221 Say(`Waiting for the operation to complete\.+\n`), 222 Say(`\n`), 223 Say(`OK\n`), 224 )) 225 226 Expect(string(session.Err.Contents())).To(BeEmpty()) 227 Expect(getBindingCount(serviceInstanceName)).To(BeZero()) 228 }) 229 }) 230 }) 231 232 Context("binding does not exist", func() { 233 var ( 234 serviceInstanceName string 235 appName string 236 ) 237 238 BeforeEach(func() { 239 serviceInstanceName = helpers.NewServiceInstanceName() 240 Eventually(helpers.CF("cups", serviceInstanceName)).Should(Exit(0)) 241 242 appName = helpers.NewAppName() 243 helpers.WithHelloWorldApp(func(appDir string) { 244 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 245 }) 246 }) 247 248 It("succeeds saying the binding did not exist", func() { 249 session := helpers.CF(command, appName, serviceInstanceName) 250 Eventually(session).Should(Exit(0)) 251 252 Expect(session.Out).To(SatisfyAll( 253 Say(`Unbinding app %s from service %s in org %s / space %s as %s\.\.\.\n`, appName, serviceInstanceName, orgName, spaceName, username), 254 Say(`Binding between %s and %s did not exist\n`, serviceInstanceName, appName), 255 Say(`OK\n`), 256 )) 257 258 Expect(string(session.Err.Contents())).To(BeEmpty()) 259 }) 260 }) 261 262 Context("app does not exist", func() { 263 var serviceInstanceName string 264 265 BeforeEach(func() { 266 serviceInstanceName = helpers.NewServiceInstanceName() 267 Eventually(helpers.CF("cups", serviceInstanceName)).Should(Exit(0)) 268 }) 269 270 It("displays FAILED and app not found", func() { 271 session := helpers.CF(command, "does-not-exist", serviceInstanceName) 272 Eventually(session).Should(Exit(1)) 273 Expect(session.Out).To(Say("FAILED")) 274 Expect(session.Err).To(Say("App 'does-not-exist' not found")) 275 }) 276 }) 277 278 Context("service instance does not exist", func() { 279 var appName string 280 281 BeforeEach(func() { 282 appName = helpers.NewAppName() 283 helpers.WithHelloWorldApp(func(appDir string) { 284 Eventually(helpers.CF("push", appName, "--no-start", "-p", appDir, "-b", "staticfile_buildpack", "--no-route")).Should(Exit(0)) 285 }) 286 }) 287 288 It("displays FAILED and service not found", func() { 289 session := helpers.CF(command, appName, "does-not-exist") 290 Eventually(session).Should(Exit(1)) 291 Expect(session.Out).To(Say("FAILED")) 292 Expect(session.Err).To(Say("Service instance 'does-not-exist' not found")) 293 }) 294 }) 295 }) 296 })