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  //------------------------------------------------------------------------------