github.com/cloudfoundry-community/cloudfoundry-cli@v6.44.1-0.20240130060226-cda5ed8e89a5+incompatible/actor/v7pushaction/actualize_test.go (about) 1 package v7pushaction_test 2 3 import ( 4 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" 5 "errors" 6 "fmt" 7 8 "code.cloudfoundry.org/cli/actor/sharedaction" 9 "code.cloudfoundry.org/cli/actor/v7action" 10 . "code.cloudfoundry.org/cli/actor/v7pushaction" 11 "code.cloudfoundry.org/cli/actor/v7pushaction/v7pushactionfakes" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 func actualizedStreamsDrainedAndClosed( 17 configStream <-chan PushPlan, 18 eventStream <-chan Event, 19 warningsStream <-chan Warnings, 20 errorStream <-chan error, 21 ) bool { 22 var configStreamClosed, eventStreamClosed, warningsStreamClosed, errorStreamClosed bool 23 for { 24 select { 25 case _, ok := <-configStream: 26 if !ok { 27 configStreamClosed = true 28 } 29 case _, ok := <-eventStream: 30 if !ok { 31 eventStreamClosed = true 32 } 33 case _, ok := <-warningsStream: 34 if !ok { 35 warningsStreamClosed = true 36 } 37 case _, ok := <-errorStream: 38 if !ok { 39 errorStreamClosed = true 40 } 41 } 42 if configStreamClosed && eventStreamClosed && warningsStreamClosed && errorStreamClosed { 43 break 44 } 45 } 46 return true 47 } 48 49 // TODO: for refactor: We can use the following style of code to validate that 50 // each event is received in a specific order 51 52 // Expect(nextEvent()).Should(Equal(SettingUpApplication)) 53 // Expect(nextEvent()).Should(Equal(CreatingApplication)) 54 // Expect(nextEvent()).Should(Equal(...)) 55 // Expect(nextEvent()).Should(Equal(...)) 56 // Expect(nextEvent()).Should(Equal(...)) 57 58 func buildV3Resource(name string) sharedaction.V3Resource { 59 return sharedaction.V3Resource{ 60 FilePath: name, 61 Checksum: ccv3.Checksum{Value: fmt.Sprintf("checksum-%s", name)}, 62 SizeInBytes: 6, 63 } 64 } 65 66 var _ = Describe("Actualize", func() { 67 var ( 68 actor *Actor 69 70 plan PushPlan 71 fakeProgressBar *v7pushactionfakes.FakeProgressBar 72 73 successfulChangeAppFuncCallCount int 74 warningChangeAppFuncCallCount int 75 errorChangeAppFuncCallCount int 76 77 planStream <-chan PushPlan 78 eventStream <-chan Event 79 warningsStream <-chan Warnings 80 errorStream <-chan error 81 82 expectedPlan PushPlan 83 ) 84 85 successfulChangeAppFunc := func(pushPlan PushPlan, eStream chan<- Event, progressBar ProgressBar) (PushPlan, Warnings, error) { 86 defer GinkgoRecover() 87 88 Expect(pushPlan).To(Equal(plan)) 89 Expect(eStream).ToNot(BeNil()) 90 Expect(progressBar).To(Equal(fakeProgressBar)) 91 92 pushPlan.Application.GUID = "successful-app-guid" 93 successfulChangeAppFuncCallCount++ 94 return pushPlan, nil, nil 95 } 96 97 warningChangeAppFunc := func(pushPlan PushPlan, eventStream chan<- Event, progressBar ProgressBar) (PushPlan, Warnings, error) { 98 pushPlan.Application.GUID = "warning-app-guid" 99 warningChangeAppFuncCallCount++ 100 return pushPlan, Warnings{"warning-1", "warning-2"}, nil 101 } 102 103 errorChangeAppFunc := func(pushPlan PushPlan, eventStream chan<- Event, progressBar ProgressBar) (PushPlan, Warnings, error) { 104 pushPlan.Application.GUID = "error-app-guid" 105 errorChangeAppFuncCallCount++ 106 return pushPlan, nil, errors.New("some error") 107 } 108 109 BeforeEach(func() { 110 actor, _, _, _ = getTestPushActor() 111 112 successfulChangeAppFuncCallCount = 0 113 warningChangeAppFuncCallCount = 0 114 errorChangeAppFuncCallCount = 0 115 116 fakeProgressBar = new(v7pushactionfakes.FakeProgressBar) 117 plan = PushPlan{ 118 Application: v7action.Application{ 119 Name: "some-app", 120 GUID: "some-app-guid", 121 }, 122 SpaceGUID: "some-space-guid", 123 } 124 125 expectedPlan = plan 126 }) 127 128 AfterEach(func() { 129 Eventually(actualizedStreamsDrainedAndClosed(planStream, eventStream, warningsStream, errorStream)).Should(BeTrue()) 130 }) 131 132 JustBeforeEach(func() { 133 planStream, eventStream, warningsStream, errorStream = actor.Actualize(plan, fakeProgressBar) 134 }) 135 136 Describe("ChangeApplicationFuncs", func() { 137 When("none of the ChangeApplicationFuncs return errors", func() { 138 BeforeEach(func() { 139 actor.ChangeApplicationFuncs = []ChangeApplicationFunc{ 140 successfulChangeAppFunc, 141 warningChangeAppFunc, 142 } 143 actor.NoStartFuncs = nil 144 actor.StartFuncs = nil 145 }) 146 147 It("iterates over the actor's ChangeApplicationFuncs", func() { 148 Eventually(warningsStream).Should(Receive(BeNil())) 149 expectedPlan.Application.GUID = "successful-app-guid" 150 Eventually(planStream).Should(Receive(Equal(expectedPlan))) 151 152 Eventually(warningsStream).Should(Receive(ConsistOf("warning-1", "warning-2"))) 153 expectedPlan.Application.GUID = "warning-app-guid" 154 Eventually(planStream).Should(Receive(Equal(expectedPlan))) 155 156 Eventually(eventStream).Should(Receive(Equal(Complete))) 157 158 Expect(successfulChangeAppFuncCallCount).To(Equal(1)) 159 Expect(warningChangeAppFuncCallCount).To(Equal(1)) 160 Expect(errorChangeAppFuncCallCount).To(Equal(0)) 161 }) 162 }) 163 164 When("the ChangeApplicationFuncs return errors", func() { 165 BeforeEach(func() { 166 actor.ChangeApplicationFuncs = []ChangeApplicationFunc{ 167 errorChangeAppFunc, 168 successfulChangeAppFunc, 169 } 170 actor.NoStartFuncs = nil 171 actor.StartFuncs = nil 172 }) 173 174 It("iterates over the actor's ChangeApplicationFuncs", func() { 175 Eventually(warningsStream).Should(Receive(BeNil())) 176 Eventually(errorStream).Should(Receive(MatchError("some error"))) 177 178 Expect(successfulChangeAppFuncCallCount).To(Equal(0)) 179 Expect(warningChangeAppFuncCallCount).To(Equal(0)) 180 Expect(errorChangeAppFuncCallCount).To(Equal(1)) 181 182 Consistently(eventStream).ShouldNot(Receive(Equal(Complete))) 183 }) 184 }) 185 }) 186 187 Describe("no-start", func() { 188 When("it is true", func() { 189 BeforeEach(func() { 190 plan.NoStart = true 191 expectedPlan.NoStart = true 192 193 actor.ChangeApplicationFuncs = nil 194 actor.NoStartFuncs = []ChangeApplicationFunc{ 195 successfulChangeAppFunc, 196 } 197 actor.StartFuncs = []ChangeApplicationFunc{ 198 errorChangeAppFunc, 199 } 200 }) 201 202 It("runs the actor's NoStartFuncs", func() { 203 Eventually(warningsStream).Should(Receive(BeNil())) 204 expectedPlan.Application.GUID = "successful-app-guid" 205 Eventually(planStream).Should(Receive(Equal(expectedPlan))) 206 Consistently(errorStream).ShouldNot(Receive()) 207 208 Expect(successfulChangeAppFuncCallCount).To(Equal(1)) 209 Expect(warningChangeAppFuncCallCount).To(Equal(0)) 210 Expect(errorChangeAppFuncCallCount).To(Equal(0)) 211 212 Eventually(eventStream).Should(Receive(Equal(Complete))) 213 }) 214 }) 215 216 When("it is false", func() { 217 BeforeEach(func() { 218 actor.ChangeApplicationFuncs = nil 219 actor.NoStartFuncs = []ChangeApplicationFunc{ 220 errorChangeAppFunc, 221 } 222 actor.StartFuncs = []ChangeApplicationFunc{ 223 successfulChangeAppFunc, 224 } 225 }) 226 227 It("runs the actor's StartFuncs", func() { 228 Eventually(warningsStream).Should(Receive(BeNil())) 229 expectedPlan.Application.GUID = "successful-app-guid" 230 Eventually(planStream).Should(Receive(Equal(expectedPlan))) 231 Consistently(errorStream).ShouldNot(Receive()) 232 233 Expect(successfulChangeAppFuncCallCount).To(Equal(1)) 234 Expect(warningChangeAppFuncCallCount).To(Equal(0)) 235 Expect(errorChangeAppFuncCallCount).To(Equal(0)) 236 237 Eventually(eventStream).Should(Receive(Equal(Complete))) 238 }) 239 }) 240 }) 241 })