github.com/lukasheimann/cloudfoundrycli@v7.1.0+incompatible/command/v6/shared/v3_poll_stage_test.go (about) 1 package shared_test 2 3 import ( 4 "errors" 5 "time" 6 7 "code.cloudfoundry.org/cli/actor/actionerror" 8 "code.cloudfoundry.org/cli/actor/v3action" 9 . "code.cloudfoundry.org/cli/command/v6/shared" 10 "code.cloudfoundry.org/cli/util/ui" 11 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 . "github.com/onsi/gomega/gbytes" 15 ) 16 17 var _ = Describe("V3PollStage", func() { 18 var ( 19 returnedDroplet v3action.Droplet 20 executeErr error 21 testUI *ui.UI 22 dropletStream chan v3action.Droplet 23 warningsStream chan v3action.Warnings 24 errStream chan error 25 logStream chan *v3action.LogMessage 26 logErrStream chan error 27 closeStreams func() 28 writeEventsAsync func(func()) 29 executePollStage func(func()) 30 finishedWritingEvents chan bool 31 finishedClosing chan bool 32 ) 33 34 closeStreams = func() { 35 close(errStream) 36 close(warningsStream) 37 close(dropletStream) 38 finishedClosing <- true 39 } 40 41 writeEventsAsync = func(writeEvents func()) { 42 go func() { 43 defer GinkgoRecover() 44 writeEvents() 45 finishedWritingEvents <- true 46 }() 47 } 48 49 executePollStage = func(codeAssertions func()) { 50 returnedDroplet, executeErr = PollStage( 51 dropletStream, 52 warningsStream, 53 errStream, 54 logStream, 55 logErrStream, 56 testUI) 57 codeAssertions() 58 Eventually(finishedClosing).Should(Receive(Equal(true))) 59 } 60 61 BeforeEach(func() { 62 // reset assertion variables 63 executeErr = nil 64 returnedDroplet = v3action.Droplet{} 65 66 // create new channels 67 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 68 dropletStream = make(chan v3action.Droplet) 69 warningsStream = make(chan v3action.Warnings) 70 errStream = make(chan error) 71 logStream = make(chan *v3action.LogMessage) 72 logErrStream = make(chan error) 73 74 finishedWritingEvents = make(chan bool) 75 finishedClosing = make(chan bool) 76 77 // wait for all events to be written before closing channels 78 go func() { 79 defer GinkgoRecover() 80 81 Eventually(finishedWritingEvents).Should(Receive(Equal(true))) 82 closeStreams() 83 }() 84 }) 85 86 When("the droplet stream contains a droplet GUID", func() { 87 BeforeEach(func() { 88 writeEventsAsync(func() { 89 dropletStream <- v3action.Droplet{GUID: "droplet-guid"} 90 }) 91 }) 92 93 It("returns the droplet GUID", func() { 94 executePollStage(func() { 95 Expect(executeErr).ToNot(HaveOccurred()) 96 Expect(returnedDroplet.GUID).To(Equal("droplet-guid")) 97 }) 98 }) 99 }) 100 101 When("the warnings stream contains warnings", func() { 102 BeforeEach(func() { 103 writeEventsAsync(func() { 104 warningsStream <- v3action.Warnings{"warning-1", "warning-2"} 105 }) 106 }) 107 108 It("displays the warnings", func() { 109 executePollStage(func() { 110 Expect(executeErr).ToNot(HaveOccurred()) 111 Expect(returnedDroplet).To(Equal(v3action.Droplet{})) 112 }) 113 114 Eventually(testUI.Err).Should(Say("warning-1")) 115 Eventually(testUI.Err).Should(Say("warning-2")) 116 }) 117 }) 118 119 When("the log stream contains a log message", func() { 120 Context("and the message is a staging message", func() { 121 BeforeEach(func() { 122 writeEventsAsync(func() { 123 logStream <- v3action.NewLogMessage("some-log-message", 1, time.Now(), v3action.StagingLog, "1") 124 }) 125 }) 126 127 It("prints the log message", func() { 128 executePollStage(func() { 129 Expect(executeErr).ToNot(HaveOccurred()) 130 Expect(returnedDroplet).To(Equal(v3action.Droplet{})) 131 }) 132 Eventually(testUI.Out).Should(Say("some-log-message")) 133 }) 134 }) 135 136 Context("and the message is not a staging message", func() { 137 BeforeEach(func() { 138 writeEventsAsync(func() { 139 logStream <- v3action.NewLogMessage("some-log-message", 1, time.Now(), "RUN", "1") 140 }) 141 }) 142 143 It("ignores the log message", func() { 144 executePollStage(func() { 145 Expect(executeErr).ToNot(HaveOccurred()) 146 Expect(returnedDroplet).To(Equal(v3action.Droplet{})) 147 }) 148 Consistently(testUI.Out).ShouldNot(Say("some-log-message")) 149 }) 150 }) 151 }) 152 153 When("the error stream contains an error", func() { 154 BeforeEach(func() { 155 writeEventsAsync(func() { 156 errStream <- errors.New("some error") 157 }) 158 }) 159 160 It("returns the error without waiting for streams to be closed", func() { 161 executePollStage(func() { 162 Expect(executeErr).To(MatchError("some error")) 163 Expect(returnedDroplet).To(Equal(v3action.Droplet{})) 164 }) 165 }) 166 }) 167 168 When("the log error stream contains errors", func() { 169 BeforeEach(func() { 170 writeEventsAsync(func() { 171 logErrStream <- actionerror.NOAATimeoutError{} 172 logErrStream <- errors.New("some-log-error") 173 }) 174 }) 175 176 It("displays the log errors as warnings", func() { 177 executePollStage(func() { 178 Expect(executeErr).ToNot(HaveOccurred()) 179 Expect(returnedDroplet).To(Equal(v3action.Droplet{})) 180 }) 181 Eventually(testUI.Err).Should(Say("timeout connecting to log server, no log will be shown")) 182 Eventually(testUI.Err).Should(Say("some-log-error")) 183 }) 184 }) 185 })