github.com/Jeffail/benthos/v3@v3.65.0/internal/component/input/span_reader_test.go (about)

     1  package input
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/Jeffail/benthos/v3/lib/input/reader"
     9  	"github.com/Jeffail/benthos/v3/lib/log"
    10  	"github.com/Jeffail/benthos/v3/lib/message"
    11  	"github.com/Jeffail/benthos/v3/lib/types"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  type fnReader struct {
    17  	connectWithContext func(ctx context.Context) error
    18  	readWithContext    func(ctx context.Context) (types.Message, reader.AsyncAckFn, error)
    19  	closeAsync         func()
    20  	waitForClose       func(timeout time.Duration) error
    21  }
    22  
    23  func (f *fnReader) ConnectWithContext(ctx context.Context) error {
    24  	return f.connectWithContext(ctx)
    25  }
    26  
    27  func (f *fnReader) ReadWithContext(ctx context.Context) (types.Message, reader.AsyncAckFn, error) {
    28  	return f.readWithContext(ctx)
    29  }
    30  
    31  func (f *fnReader) CloseAsync() {
    32  	f.closeAsync()
    33  }
    34  
    35  func (f *fnReader) WaitForClose(timeout time.Duration) error {
    36  	return f.waitForClose(timeout)
    37  }
    38  
    39  func TestSpanReader(t *testing.T) {
    40  	tests := []struct {
    41  		name     string
    42  		contents string
    43  		mapping  string
    44  	}{
    45  		{
    46  			name:     "mapping fails",
    47  			contents: `{}`,
    48  			mapping:  `root.foo = this.bar.not_null()`,
    49  		},
    50  		{
    51  			name:     "result not JSON",
    52  			contents: `{}`,
    53  			mapping:  `root = "this isn't json"`,
    54  		},
    55  		{
    56  			name:     "result not an object",
    57  			contents: `{}`,
    58  			mapping:  `root = ["foo","bar"]`,
    59  		},
    60  		{
    61  			name:     "result not a span",
    62  			contents: `{}`,
    63  			mapping:  `root = {"foo":"bar"}`,
    64  		},
    65  	}
    66  
    67  	for _, test := range tests {
    68  		test := test
    69  		t.Run(test.name, func(t *testing.T) {
    70  			var connCalled, closeCalled, waitCalled bool
    71  
    72  			r, err := NewSpanReader("foo", test.mapping, &fnReader{
    73  				connectWithContext: func(ctx context.Context) error {
    74  					connCalled = true
    75  					return nil
    76  				},
    77  				readWithContext: func(ctx context.Context) (types.Message, reader.AsyncAckFn, error) {
    78  					m := message.New([][]byte{
    79  						[]byte(test.contents),
    80  					})
    81  					return m, func(context.Context, types.Response) error {
    82  						return nil
    83  					}, nil
    84  				},
    85  				closeAsync: func() {
    86  					closeCalled = true
    87  				},
    88  				waitForClose: func(tout time.Duration) error {
    89  					waitCalled = true
    90  					return nil
    91  				},
    92  			}, types.NoopMgr(), log.Noop())
    93  			require.NoError(t, err)
    94  
    95  			assert.Nil(t, r.ConnectWithContext(context.Background()))
    96  
    97  			res, _, err := r.ReadWithContext(context.Background())
    98  			require.NoError(t, err)
    99  			assert.Equal(t, 1, res.Len())
   100  			assert.Equal(t, test.contents, string(res.Get(0).Get()))
   101  
   102  			r.CloseAsync()
   103  			assert.Nil(t, r.WaitForClose(time.Second))
   104  
   105  			assert.True(t, connCalled)
   106  			assert.True(t, closeCalled)
   107  			assert.True(t, waitCalled)
   108  		})
   109  	}
   110  }