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 }