github.com/Jeffail/benthos/v3@v3.65.0/lib/broker/fan_out_sequential_test.go (about) 1 package broker 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "testing" 8 "time" 9 10 "github.com/Jeffail/benthos/v3/lib/log" 11 "github.com/Jeffail/benthos/v3/lib/message" 12 "github.com/Jeffail/benthos/v3/lib/metrics" 13 "github.com/Jeffail/benthos/v3/lib/response" 14 "github.com/Jeffail/benthos/v3/lib/types" 15 ) 16 17 //------------------------------------------------------------------------------ 18 19 func TestBasicFanOutSequential(t *testing.T) { 20 nOutputs, nMsgs := 10, 1000 21 22 outputs := []types.Output{} 23 mockOutputs := []*MockOutputType{} 24 25 for i := 0; i < nOutputs; i++ { 26 mockOutputs = append(mockOutputs, &MockOutputType{}) 27 outputs = append(outputs, mockOutputs[i]) 28 } 29 30 readChan := make(chan types.Transaction) 31 resChan := make(chan types.Response) 32 33 oTM, err := NewFanOutSequential(outputs, log.Noop(), metrics.Noop()) 34 if err != nil { 35 t.Error(err) 36 return 37 } 38 if err = oTM.Consume(readChan); err != nil { 39 t.Error(err) 40 return 41 } 42 43 if !oTM.Connected() { 44 t.Error("Not connected") 45 } 46 47 for i := 0; i < nMsgs; i++ { 48 content := [][]byte{[]byte(fmt.Sprintf("hello world %v", i))} 49 select { 50 case readChan <- types.NewTransaction(message.New(content), resChan): 51 case <-time.After(time.Second): 52 t.Errorf("Timed out waiting for broker send") 53 return 54 } 55 resChanSlice := []chan<- types.Response{} 56 for j := 0; j < nOutputs; j++ { 57 var ts types.Transaction 58 select { 59 case ts = <-mockOutputs[j].TChan: 60 if !bytes.Equal(ts.Payload.Get(0).Get(), content[0]) { 61 t.Errorf("Wrong content returned %s != %s", ts.Payload.Get(0).Get(), content[0]) 62 } 63 resChanSlice = append(resChanSlice, ts.ResponseChan) 64 case <-time.After(time.Second): 65 t.Errorf("Timed out waiting for broker propagate") 66 return 67 } 68 select { 69 case resChanSlice[j] <- response.NewAck(): 70 case <-time.After(time.Second): 71 t.Errorf("Timed out responding to broker") 72 return 73 } 74 } 75 select { 76 case res := <-resChan: 77 if res.Error() != nil { 78 t.Errorf("Received unexpected errors from broker: %v", res.Error()) 79 } 80 case <-time.After(time.Second): 81 t.Errorf("Timed out responding to broker") 82 return 83 } 84 } 85 86 oTM.CloseAsync() 87 88 if err := oTM.WaitForClose(time.Second * 5); err != nil { 89 t.Error(err) 90 } 91 } 92 93 func TestFanOutSequentialAtLeastOnce(t *testing.T) { 94 mockOne := MockOutputType{} 95 mockTwo := MockOutputType{} 96 97 outputs := []types.Output{&mockOne, &mockTwo} 98 readChan := make(chan types.Transaction) 99 resChan := make(chan types.Response) 100 101 oTM, err := NewFanOutSequential(outputs, log.Noop(), metrics.Noop()) 102 if err != nil { 103 t.Error(err) 104 return 105 } 106 if err = oTM.Consume(readChan); err != nil { 107 t.Error(err) 108 return 109 } 110 111 select { 112 case readChan <- types.NewTransaction(message.New([][]byte{[]byte("hello world")}), resChan): 113 case <-time.After(time.Second): 114 t.Error("Timed out waiting for broker send") 115 return 116 } 117 var ts1, ts2 types.Transaction 118 select { 119 case ts1 = <-mockOne.TChan: 120 case <-time.After(time.Second): 121 t.Error("Timed out waiting for mockOne") 122 return 123 } 124 select { 125 case ts1.ResponseChan <- response.NewAck(): 126 case <-time.After(time.Second): 127 t.Error("Timed out responding to broker") 128 return 129 } 130 select { 131 case ts2 = <-mockTwo.TChan: 132 case <-time.After(time.Second): 133 t.Error("Timed out waiting for mockOne") 134 return 135 } 136 select { 137 case ts2.ResponseChan <- response.NewError(errors.New("this is a test")): 138 case <-time.After(time.Second): 139 t.Error("Timed out responding to broker") 140 return 141 } 142 select { 143 case <-mockOne.TChan: 144 t.Error("Received duplicate message to mockOne") 145 case ts2 = <-mockTwo.TChan: 146 case <-resChan: 147 t.Error("Received premature response from broker") 148 case <-time.After(time.Second): 149 t.Error("Timed out waiting for mockTwo") 150 return 151 } 152 select { 153 case ts2.ResponseChan <- response.NewAck(): 154 case <-time.After(time.Second): 155 t.Error("Timed out responding to broker") 156 return 157 } 158 select { 159 case res := <-resChan: 160 if res.Error() != nil { 161 t.Errorf("Fan out returned error %v", res.Error()) 162 } 163 case <-time.After(time.Second): 164 t.Errorf("Timed out responding to broker") 165 return 166 } 167 168 close(readChan) 169 170 if err := oTM.WaitForClose(time.Second * 5); err != nil { 171 t.Error(err) 172 } 173 } 174 175 func TestFanOutSequentialBlock(t *testing.T) { 176 mockOne := MockOutputType{} 177 mockTwo := MockOutputType{} 178 179 outputs := []types.Output{&mockOne, &mockTwo} 180 readChan := make(chan types.Transaction) 181 resChan := make(chan types.Response) 182 183 oTM, err := NewFanOutSequential(outputs, log.Noop(), metrics.Noop()) 184 if err != nil { 185 t.Error(err) 186 return 187 } 188 if err = oTM.Consume(readChan); err != nil { 189 t.Error(err) 190 return 191 } 192 193 select { 194 case readChan <- types.NewTransaction(message.New([][]byte{[]byte("hello world")}), resChan): 195 case <-time.After(time.Second): 196 t.Error("Timed out waiting for broker send") 197 return 198 } 199 var ts1, ts2 types.Transaction 200 select { 201 case ts1 = <-mockOne.TChan: 202 case <-time.After(time.Second): 203 t.Error("Timed out waiting for mockOne") 204 return 205 } 206 select { 207 case ts1.ResponseChan <- response.NewError(errors.New("this is a test")): 208 case <-time.After(time.Second): 209 t.Error("Timed out responding to broker") 210 return 211 } 212 select { 213 case ts1 = <-mockOne.TChan: 214 case <-mockTwo.TChan: 215 t.Error("Received premature message to mockTwo") 216 case <-resChan: 217 t.Error("Received premature response from broker") 218 case <-time.After(time.Second): 219 t.Error("Timed out waiting for mockOne") 220 return 221 } 222 select { 223 case ts1.ResponseChan <- response.NewAck(): 224 case <-time.After(time.Second): 225 t.Error("Timed out responding to broker") 226 return 227 } 228 229 select { 230 case ts2 = <-mockTwo.TChan: 231 case <-time.After(time.Second): 232 t.Error("Timed out waiting for mockOne") 233 return 234 } 235 select { 236 case ts2.ResponseChan <- response.NewAck(): 237 case <-time.After(time.Second): 238 t.Error("Timed out responding to broker") 239 return 240 } 241 select { 242 case res := <-resChan: 243 if res.Error() != nil { 244 t.Errorf("Fan out returned error %v", res.Error()) 245 } 246 case <-time.After(time.Second): 247 t.Errorf("Timed out responding to broker") 248 return 249 } 250 251 close(readChan) 252 253 if err := oTM.WaitForClose(time.Second * 5); err != nil { 254 t.Error(err) 255 } 256 } 257 258 //------------------------------------------------------------------------------