github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/update_service_command_test.go (about) 1 package v7_test 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror" 8 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action" 9 "github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes" 10 "github.com/LukasHeimann/cloudfoundrycli/v8/command/flag" 11 . "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7" 12 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes" 13 "github.com/LukasHeimann/cloudfoundrycli/v8/types" 14 "github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3" 15 "github.com/LukasHeimann/cloudfoundrycli/v8/util/ui" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/gbytes" 19 ) 20 21 var _ = Describe("update-service command", func() { 22 const ( 23 serviceInstanceName = "fake-service-instance-name" 24 spaceName = "fake-space-name" 25 spaceGUID = "fake-space-guid" 26 orgName = "fake-org-name" 27 username = "fake-username" 28 ) 29 30 var ( 31 input *Buffer 32 testUI *ui.UI 33 fakeConfig *commandfakes.FakeConfig 34 fakeSharedActor *commandfakes.FakeSharedActor 35 fakeActor *v7fakes.FakeActor 36 cmd UpdateServiceCommand 37 executeErr error 38 ) 39 40 BeforeEach(func() { 41 input = NewBuffer() 42 testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer()) 43 fakeConfig = new(commandfakes.FakeConfig) 44 fakeSharedActor = new(commandfakes.FakeSharedActor) 45 fakeActor = new(v7fakes.FakeActor) 46 47 cmd = UpdateServiceCommand{ 48 BaseCommand: BaseCommand{ 49 UI: testUI, 50 Config: fakeConfig, 51 SharedActor: fakeSharedActor, 52 Actor: fakeActor, 53 }, 54 } 55 56 setPositionalFlags(&cmd, flag.TrimmedString(serviceInstanceName)) 57 58 fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: orgName}) 59 fakeConfig.TargetedSpaceReturns(configv3.Space{ 60 Name: spaceName, 61 GUID: spaceGUID, 62 }) 63 fakeActor.GetCurrentUserReturns(configv3.User{Name: username}, nil) 64 65 fakeStream := make(chan v7action.PollJobEvent) 66 close(fakeStream) 67 fakeActor.UpdateManagedServiceInstanceReturns( 68 fakeStream, 69 v7action.Warnings{"actor warning"}, 70 nil, 71 ) 72 }) 73 74 JustBeforeEach(func() { 75 executeErr = cmd.Execute(nil) 76 }) 77 78 It("checks the user is logged in, and targeting an org and space", func() { 79 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 80 orgChecked, spaceChecked := fakeSharedActor.CheckTargetArgsForCall(0) 81 Expect(orgChecked).To(BeTrue()) 82 Expect(spaceChecked).To(BeTrue()) 83 }) 84 85 When("upgrade flag specified", func() { 86 BeforeEach(func() { 87 setFlag(&cmd, "--upgrade") 88 }) 89 90 It("prints a message and returns an error", func() { 91 Expect(executeErr).To(MatchError( 92 fmt.Sprintf( 93 `Upgrading is no longer supported via updates, please run "cf upgrade-service %s" instead.`, 94 serviceInstanceName, 95 ), 96 )) 97 }) 98 }) 99 100 When("no parameters specified", func() { 101 It("prints a message and exits 0", func() { 102 Expect(executeErr).NotTo(HaveOccurred()) 103 Expect(testUI.Out).To(Say("No flags specified. No changes were made")) 104 }) 105 }) 106 107 Describe("updates", func() { 108 BeforeEach(func() { 109 setFlag(&cmd, "-t", `foo,bar`) 110 setFlag(&cmd, "-c", `{"baz": "quz"}`) 111 setFlag(&cmd, "-p", "some-plan") 112 }) 113 114 It("does not return an error", func() { 115 Expect(executeErr).NotTo(HaveOccurred()) 116 }) 117 118 It("prints messages and warnings", func() { 119 Expect(testUI.Out).To(SatisfyAll( 120 Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username), 121 Say(`\n`), 122 Say(`Update of service instance %s complete\.`, serviceInstanceName), 123 Say(`OK\n`), 124 )) 125 126 Expect(testUI.Err).To(Say("actor warning")) 127 }) 128 129 It("delegates to the actor", func() { 130 Expect(fakeActor.UpdateManagedServiceInstanceCallCount()).To(Equal(1)) 131 actualUpdates := fakeActor.UpdateManagedServiceInstanceArgsForCall(0) 132 Expect(actualUpdates).To(Equal(v7action.UpdateManagedServiceInstanceParams{ 133 ServiceInstanceName: serviceInstanceName, 134 SpaceGUID: spaceGUID, 135 Tags: types.NewOptionalStringSlice("foo", "bar"), 136 Parameters: types.NewOptionalObject(map[string]interface{}{"baz": "quz"}), 137 ServicePlanName: "some-plan", 138 })) 139 }) 140 141 When("stream goes to polling", func() { 142 BeforeEach(func() { 143 fakeStream := make(chan v7action.PollJobEvent) 144 fakeActor.UpdateManagedServiceInstanceReturns( 145 fakeStream, 146 v7action.Warnings{"actor warning"}, 147 nil, 148 ) 149 150 go func() { 151 fakeStream <- v7action.PollJobEvent{ 152 State: v7action.JobPolling, 153 Warnings: v7action.Warnings{"poll warning"}, 154 } 155 }() 156 }) 157 158 It("prints messages and warnings", func() { 159 Expect(testUI.Out).To(SatisfyAll( 160 Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username), 161 Say(`\n`), 162 Say(`Update in progress. Use 'cf services' or 'cf service %s' to check operation status\.`, serviceInstanceName), 163 Say(`OK\n`), 164 )) 165 166 Expect(testUI.Err).To(SatisfyAll( 167 Say("actor warning"), 168 Say("poll warning"), 169 )) 170 }) 171 }) 172 173 When("error in event stream", func() { 174 BeforeEach(func() { 175 setFlag(&cmd, "--wait") 176 177 fakeStream := make(chan v7action.PollJobEvent) 178 fakeActor.UpdateManagedServiceInstanceReturns( 179 fakeStream, 180 v7action.Warnings{"a warning"}, 181 nil, 182 ) 183 184 go func() { 185 fakeStream <- v7action.PollJobEvent{ 186 State: v7action.JobPolling, 187 Warnings: v7action.Warnings{"poll warning"}, 188 } 189 fakeStream <- v7action.PollJobEvent{ 190 State: v7action.JobFailed, 191 Warnings: v7action.Warnings{"failed warning"}, 192 Err: errors.New("boom"), 193 } 194 }() 195 }) 196 197 It("returns the error and prints warnings", func() { 198 Expect(executeErr).To(MatchError("boom")) 199 Expect(testUI.Err).To(SatisfyAll( 200 Say("poll warning"), 201 Say("failed warning"), 202 )) 203 }) 204 }) 205 206 When("--wait flag specified", func() { 207 BeforeEach(func() { 208 setFlag(&cmd, "--wait") 209 210 fakeStream := make(chan v7action.PollJobEvent) 211 fakeActor.UpdateManagedServiceInstanceReturns( 212 fakeStream, 213 v7action.Warnings{"a warning"}, 214 nil, 215 ) 216 217 go func() { 218 fakeStream <- v7action.PollJobEvent{ 219 State: v7action.JobPolling, 220 Warnings: v7action.Warnings{"poll warning"}, 221 } 222 fakeStream <- v7action.PollJobEvent{ 223 State: v7action.JobComplete, 224 Warnings: v7action.Warnings{"failed warning"}, 225 } 226 close(fakeStream) 227 }() 228 }) 229 230 It("prints messages and warnings", func() { 231 Expect(testUI.Out).To(SatisfyAll( 232 Say(`Updating service instance %s in org %s / space %s as %s...\n`, serviceInstanceName, orgName, spaceName, username), 233 Say(`\n`), 234 Say(`Waiting for the operation to complete\.\.\n`), 235 Say(`\n`), 236 Say(`Update of service instance %s complete\.\n`, serviceInstanceName), 237 Say(`OK\n`), 238 )) 239 240 Expect(testUI.Err).To(SatisfyAll( 241 Say("a warning"), 242 Say("poll warning"), 243 Say("failed warning"), 244 )) 245 }) 246 }) 247 248 When("plan is current plan", func() { 249 const currentPlan = "current-plan" 250 251 BeforeEach(func() { 252 setFlag(&cmd, "-p", currentPlan) 253 fakeActor.UpdateManagedServiceInstanceReturns( 254 nil, 255 v7action.Warnings{"actor warning"}, 256 actionerror.ServiceInstanceUpdateIsNoop{}, 257 ) 258 }) 259 260 It("prints warnings and a message", func() { 261 Expect(executeErr).NotTo(HaveOccurred()) 262 Expect(testUI.Err).To(Say("actor warning")) 263 Expect(testUI.Out).To(Say("No changes were made")) 264 }) 265 }) 266 267 When("getting the user fails", func() { 268 BeforeEach(func() { 269 fakeActor.GetCurrentUserReturns(configv3.User{}, errors.New("bang")) 270 }) 271 272 It("returns the error", func() { 273 Expect(executeErr).To(MatchError("bang")) 274 }) 275 }) 276 277 When("the actor reports the service instance was not found", func() { 278 BeforeEach(func() { 279 fakeActor.UpdateManagedServiceInstanceReturns( 280 nil, 281 v7action.Warnings{"actor warning"}, 282 actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}, 283 ) 284 }) 285 286 It("prints warnings and returns an error", func() { 287 Expect(testUI.Err).To(Say("actor warning")) 288 Expect(executeErr).To(MatchError(actionerror.ServiceInstanceNotFoundError{ 289 Name: serviceInstanceName, 290 })) 291 }) 292 }) 293 294 When("plan not found", func() { 295 const ( 296 invalidPlan = "invalid-plan" 297 ) 298 299 BeforeEach(func() { 300 setFlag(&cmd, "-p", invalidPlan) 301 fakeActor.UpdateManagedServiceInstanceReturns( 302 nil, 303 v7action.Warnings{"actor warning"}, 304 actionerror.ServicePlanNotFoundError{PlanName: invalidPlan, ServiceBrokerName: "the-broker", OfferingName: "the-offering"}, 305 ) 306 }) 307 308 It("prints warnings and returns a translatable error", func() { 309 Expect(testUI.Err).To(Say("actor warning")) 310 Expect(executeErr).To(MatchError(actionerror.ServicePlanNotFoundError{ 311 PlanName: invalidPlan, 312 OfferingName: "the-offering", 313 ServiceBrokerName: "the-broker", 314 })) 315 }) 316 }) 317 318 When("the actor fails with an unexpected error", func() { 319 BeforeEach(func() { 320 fakeActor.UpdateManagedServiceInstanceReturns( 321 nil, 322 v7action.Warnings{"actor warning"}, 323 errors.New("boof"), 324 ) 325 }) 326 327 It("prints warnings and returns an error", func() { 328 Expect(testUI.Err).To(Say("actor warning")) 329 Expect(executeErr).To(MatchError("boof")) 330 }) 331 }) 332 }) 333 334 When("checking the target returns an error", func() { 335 BeforeEach(func() { 336 fakeSharedActor.CheckTargetReturns(errors.New("explode")) 337 }) 338 339 It("returns the error", func() { 340 Expect(executeErr).To(MatchError("explode")) 341 }) 342 }) 343 })