github.com/Jeffail/benthos/v3@v3.65.0/lib/input/file_test.go (about)

     1  package input
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"strconv"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/Jeffail/benthos/v3/lib/log"
    13  	"github.com/Jeffail/benthos/v3/lib/metrics"
    14  	"github.com/Jeffail/benthos/v3/lib/response"
    15  	"github.com/Jeffail/benthos/v3/lib/types"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestFileSinglePartDeprecated(t *testing.T) {
    21  	tmpfile, err := os.CreateTemp("", "benthos_file_test")
    22  	require.NoError(t, err)
    23  
    24  	t.Cleanup(func() {
    25  		os.Remove(tmpfile.Name())
    26  	})
    27  
    28  	messages := []string{
    29  		"first message",
    30  		"second message",
    31  		"third message",
    32  	}
    33  
    34  	for _, msg := range messages {
    35  		_, _ = tmpfile.WriteString(msg)
    36  		_, _ = tmpfile.WriteString("\n")
    37  		_, _ = tmpfile.WriteString("\n") // Try some empty messages
    38  	}
    39  
    40  	conf := NewConfig()
    41  	conf.File.Path = tmpfile.Name()
    42  
    43  	f, err := NewFile(conf, nil, log.Noop(), metrics.Noop())
    44  	require.NoError(t, err)
    45  
    46  	defer func() {
    47  		f.CloseAsync()
    48  		assert.NoError(t, f.WaitForClose(time.Second))
    49  	}()
    50  
    51  	for _, exp := range messages {
    52  		var ts types.Transaction
    53  		var open bool
    54  		select {
    55  		case ts, open = <-f.TransactionChan():
    56  			require.True(t, open)
    57  			assert.Equal(t, exp, string(ts.Payload.Get(0).Get()))
    58  			assert.Equal(t, tmpfile.Name(), ts.Payload.Get(0).Metadata().Get("path"))
    59  		case <-time.After(time.Second):
    60  			t.Error("Timed out waiting for message")
    61  		}
    62  		select {
    63  		case ts.ResponseChan <- response.NewAck():
    64  		case <-time.After(time.Second):
    65  			t.Error("Timed out waiting for response")
    66  		}
    67  	}
    68  
    69  	select {
    70  	case _, open := <-f.TransactionChan():
    71  		require.False(t, open)
    72  	case <-time.After(time.Second):
    73  		t.Error("Timed out waiting for channel close")
    74  	}
    75  }
    76  
    77  func TestFileMultiPartDeprecated(t *testing.T) {
    78  	tmpfile, err := os.CreateTemp("", "benthos_file_test")
    79  	require.NoError(t, err)
    80  
    81  	t.Cleanup(func() {
    82  		os.Remove(tmpfile.Name())
    83  	})
    84  
    85  	messages := [][]string{
    86  		{
    87  			"first message",
    88  			"1",
    89  			"2",
    90  		},
    91  		{
    92  			"second message",
    93  			"1",
    94  			"2",
    95  		},
    96  		{
    97  			"third message",
    98  			"1",
    99  			"2",
   100  		},
   101  	}
   102  
   103  	for _, msg := range messages {
   104  		for _, part := range msg {
   105  			_, _ = tmpfile.WriteString(part)
   106  			_, _ = tmpfile.WriteString("\n")
   107  		}
   108  		_, _ = tmpfile.WriteString("\n")
   109  	}
   110  
   111  	conf := NewConfig()
   112  	conf.File.Path = tmpfile.Name()
   113  	conf.File.Multipart = true
   114  
   115  	f, err := NewFile(conf, nil, log.Noop(), metrics.Noop())
   116  	require.NoError(t, err)
   117  
   118  	defer func() {
   119  		f.CloseAsync()
   120  		assert.NoError(t, f.WaitForClose(time.Second))
   121  	}()
   122  
   123  	for _, msg := range messages {
   124  		var ts types.Transaction
   125  		var open bool
   126  		select {
   127  		case ts, open = <-f.TransactionChan():
   128  			require.True(t, open)
   129  			for i, exp := range msg {
   130  				assert.Equal(t, exp, string(ts.Payload.Get(i).Get()), strconv.Itoa(i))
   131  			}
   132  		case <-time.After(time.Second):
   133  			t.Error("Timed out waiting for message")
   134  		}
   135  		select {
   136  		case ts.ResponseChan <- response.NewAck():
   137  		case <-time.After(time.Second):
   138  			t.Error("Timed out waiting for response")
   139  		}
   140  	}
   141  
   142  	select {
   143  	case _, open := <-f.TransactionChan():
   144  		require.False(t, open)
   145  	case <-time.After(time.Second):
   146  		t.Error("Timed out waiting for channel close")
   147  	}
   148  }
   149  
   150  func TestFileDirectory(t *testing.T) {
   151  	tmpDir := t.TempDir()
   152  
   153  	tmpInnerDir, err := os.MkdirTemp(tmpDir, "benthos_inner")
   154  	require.NoError(t, err)
   155  
   156  	tmpFile, err := os.CreateTemp(tmpDir, "f1*.txt")
   157  	require.NoError(t, err)
   158  
   159  	_, err = tmpFile.WriteString("foo")
   160  	require.NoError(t, err)
   161  
   162  	err = tmpFile.Close()
   163  	require.NoError(t, err)
   164  
   165  	tmpFileTwo, err := os.CreateTemp(tmpInnerDir, "f2*.txt")
   166  	require.NoError(t, err)
   167  
   168  	_, err = tmpFileTwo.WriteString("bar")
   169  	require.NoError(t, err)
   170  
   171  	err = tmpFileTwo.Close()
   172  	require.NoError(t, err)
   173  
   174  	exp := map[string]struct{}{
   175  		"foo": {},
   176  		"bar": {},
   177  	}
   178  	act := map[string]struct{}{}
   179  
   180  	conf := NewFileConfig()
   181  	conf.Paths = []string{
   182  		fmt.Sprintf("%v/*.txt", tmpDir),
   183  		fmt.Sprintf("%v/**/*.txt", tmpDir),
   184  	}
   185  	conf.Codec = "all-bytes"
   186  
   187  	f, err := newFileConsumer(conf, log.Noop())
   188  	require.NoError(t, err)
   189  
   190  	err = f.ConnectWithContext(context.Background())
   191  	require.NoError(t, err)
   192  
   193  	msg, aFn, err := f.ReadWithContext(context.Background())
   194  	require.NoError(t, err)
   195  
   196  	resStr := string(msg.Get(0).Get())
   197  	if _, exists := act[resStr]; exists {
   198  		t.Errorf("Received duplicate message: %v", resStr)
   199  	}
   200  	act[resStr] = struct{}{}
   201  	require.NoError(t, aFn(context.Background(), response.NewAck()))
   202  
   203  	msg, aFn, err = f.ReadWithContext(context.Background())
   204  	require.NoError(t, err)
   205  
   206  	resStr = string(msg.Get(0).Get())
   207  	if _, exists := act[resStr]; exists {
   208  		t.Errorf("Received duplicate message: %v", resStr)
   209  	}
   210  	act[resStr] = struct{}{}
   211  	require.NoError(t, aFn(context.Background(), response.NewAck()))
   212  
   213  	_, _, err = f.ReadWithContext(context.Background())
   214  	assert.Equal(t, types.ErrTypeClosed, err)
   215  
   216  	if !reflect.DeepEqual(exp, act) {
   217  		t.Errorf("Wrong result: %v != %v", act, exp)
   218  	}
   219  }