github.com/Jeffail/benthos/v3@v3.65.0/lib/test/integration/redis_test.go (about) 1 package integration 2 3 import ( 4 "context" 5 "fmt" 6 "testing" 7 "time" 8 9 "github.com/Jeffail/benthos/v3/internal/integration" 10 "github.com/Jeffail/benthos/v3/lib/log" 11 "github.com/Jeffail/benthos/v3/lib/metrics" 12 "github.com/Jeffail/benthos/v3/lib/output/writer" 13 "github.com/go-redis/redis/v7" 14 "github.com/ory/dockertest/v3" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 var _ = registerIntegrationTest("redis", func(t *testing.T) { 20 t.Parallel() 21 22 pool, err := dockertest.NewPool("") 23 require.NoError(t, err) 24 25 pool.MaxWait = time.Second * 30 26 resource, err := pool.Run("redis", "latest", nil) 27 require.NoError(t, err) 28 t.Cleanup(func() { 29 assert.NoError(t, pool.Purge(resource)) 30 }) 31 32 resource.Expire(900) 33 require.NoError(t, pool.Retry(func() error { 34 conf := writer.NewRedisStreamsConfig() 35 conf.URL = fmt.Sprintf("tcp://localhost:%v", resource.GetPort("6379/tcp")) 36 37 r, cErr := writer.NewRedisStreams(conf, log.Noop(), metrics.Noop()) 38 if cErr != nil { 39 return cErr 40 } 41 cErr = r.Connect() 42 43 r.CloseAsync() 44 return cErr 45 })) 46 47 // STREAMS 48 t.Run("streams", func(t *testing.T) { 49 t.Parallel() 50 template := ` 51 output: 52 redis_streams: 53 url: tcp://localhost:$PORT 54 stream: stream-$ID 55 body_key: body 56 max_length: 0 57 max_in_flight: $MAX_IN_FLIGHT 58 metadata: 59 exclude_prefixes: [ $OUTPUT_META_EXCLUDE_PREFIX ] 60 batching: 61 count: $OUTPUT_BATCH_COUNT 62 63 input: 64 redis_streams: 65 url: tcp://localhost:$PORT 66 body_key: body 67 streams: [ stream-$ID ] 68 limit: 10 69 client_id: client-input-$ID 70 consumer_group: group-$ID 71 ` 72 suite := integration.StreamTests( 73 integration.StreamTestOpenClose(), 74 integration.StreamTestMetadata(), 75 integration.StreamTestMetadataFilter(), 76 integration.StreamTestSendBatch(10), 77 integration.StreamTestSendBatches(20, 100, 1), 78 integration.StreamTestStreamSequential(1000), 79 integration.StreamTestStreamParallel(1000), 80 integration.StreamTestStreamParallelLossy(1000), 81 integration.StreamTestStreamParallelLossyThroughReconnect(100), 82 integration.StreamTestSendBatchCount(10), 83 ) 84 suite.Run( 85 t, template, 86 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 87 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 88 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 89 ) 90 t.Run("with max in flight", func(t *testing.T) { 91 t.Parallel() 92 suite.Run( 93 t, template, 94 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 95 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 96 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 97 integration.StreamTestOptMaxInFlight(10), 98 ) 99 }) 100 }) 101 102 t.Run("pubsub", func(t *testing.T) { 103 t.Parallel() 104 template := ` 105 output: 106 redis_pubsub: 107 url: tcp://localhost:$PORT 108 channel: channel-$ID 109 max_in_flight: $MAX_IN_FLIGHT 110 batching: 111 count: $OUTPUT_BATCH_COUNT 112 113 input: 114 redis_pubsub: 115 url: tcp://localhost:$PORT 116 channels: [ channel-$ID ] 117 ` 118 suite := integration.StreamTests( 119 integration.StreamTestOpenClose(), 120 integration.StreamTestSendBatch(10), 121 integration.StreamTestSendBatches(20, 100, 1), 122 integration.StreamTestStreamSequential(100), 123 integration.StreamTestStreamParallel(100), 124 integration.StreamTestStreamParallelLossy(100), 125 integration.StreamTestSendBatchCount(10), 126 ) 127 suite.Run( 128 t, template, 129 integration.StreamTestOptSleepAfterInput(500*time.Millisecond), 130 integration.StreamTestOptSleepAfterOutput(500*time.Millisecond), 131 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 132 ) 133 t.Run("with max in flight", func(t *testing.T) { 134 t.Parallel() 135 suite.Run( 136 t, template, 137 integration.StreamTestOptSleepAfterInput(500*time.Millisecond), 138 integration.StreamTestOptSleepAfterOutput(500*time.Millisecond), 139 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 140 integration.StreamTestOptMaxInFlight(10), 141 ) 142 }) 143 }) 144 145 t.Run("list", func(t *testing.T) { 146 t.Parallel() 147 template := ` 148 output: 149 redis_list: 150 url: tcp://localhost:$PORT 151 key: key-$ID 152 max_in_flight: $MAX_IN_FLIGHT 153 batching: 154 count: $OUTPUT_BATCH_COUNT 155 156 input: 157 redis_list: 158 url: tcp://localhost:$PORT 159 key: key-$ID 160 ` 161 suite := integration.StreamTests( 162 integration.StreamTestOpenClose(), 163 integration.StreamTestSendBatch(10), 164 integration.StreamTestSendBatches(20, 100, 1), 165 integration.StreamTestStreamSequential(1000), 166 integration.StreamTestStreamParallel(1000), 167 integration.StreamTestStreamParallelLossy(1000), 168 integration.StreamTestSendBatchCount(10), 169 ) 170 suite.Run( 171 t, template, 172 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 173 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 174 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 175 ) 176 t.Run("with max in flight", func(t *testing.T) { 177 t.Parallel() 178 suite.Run( 179 t, template, 180 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 181 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 182 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 183 integration.StreamTestOptMaxInFlight(10), 184 ) 185 }) 186 }) 187 188 // HASH 189 t.Run("hash", func(t *testing.T) { 190 t.Parallel() 191 template := ` 192 output: 193 redis_hash: 194 url: tcp://localhost:$PORT 195 key: $ID-${! json("id") } 196 fields: 197 content: ${! content() } 198 ` 199 hashGetFn := func(ctx context.Context, testID string, id string) (string, []string, error) { 200 client := redis.NewClient(&redis.Options{ 201 Addr: fmt.Sprintf("localhost:%v", resource.GetPort("6379/tcp")), 202 Network: "tcp", 203 }) 204 key := testID + "-" + id 205 res, err := client.HGet(key, "content").Result() 206 if err != nil { 207 return "", nil, err 208 } 209 return res, nil, nil 210 } 211 suite := integration.StreamTests( 212 integration.StreamTestOutputOnlySendSequential(10, hashGetFn), 213 integration.StreamTestOutputOnlySendBatch(10, hashGetFn), 214 integration.StreamTestOutputOnlyOverride(hashGetFn), 215 ) 216 suite.Run( 217 t, template, 218 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 219 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 220 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 221 ) 222 }) 223 }) 224 225 var _ = registerIntegrationBench("redis", func(b *testing.B) { 226 pool, err := dockertest.NewPool("") 227 require.NoError(b, err) 228 229 pool.MaxWait = time.Second * 30 230 resource, err := pool.Run("redis", "latest", nil) 231 require.NoError(b, err) 232 b.Cleanup(func() { 233 assert.NoError(b, pool.Purge(resource)) 234 }) 235 236 resource.Expire(900) 237 require.NoError(b, pool.Retry(func() error { 238 conf := writer.NewRedisStreamsConfig() 239 conf.URL = fmt.Sprintf("tcp://localhost:%v", resource.GetPort("6379/tcp")) 240 241 r, cErr := writer.NewRedisStreams(conf, log.Noop(), metrics.Noop()) 242 if cErr != nil { 243 return cErr 244 } 245 cErr = r.Connect() 246 247 r.CloseAsync() 248 return cErr 249 })) 250 251 // STREAMS 252 b.Run("streams", func(b *testing.B) { 253 template := ` 254 output: 255 redis_streams: 256 url: tcp://localhost:$PORT 257 stream: stream-$ID 258 body_key: body 259 max_length: 0 260 max_in_flight: $MAX_IN_FLIGHT 261 metadata: 262 exclude_prefixes: [ $OUTPUT_META_EXCLUDE_PREFIX ] 263 264 input: 265 redis_streams: 266 url: tcp://localhost:$PORT 267 body_key: body 268 streams: [ stream-$ID ] 269 limit: 10 270 client_id: client-input-$ID 271 consumer_group: group-$ID 272 ` 273 suite := integration.StreamBenchs( 274 integration.StreamBenchSend(20, 1), 275 integration.StreamBenchSend(10, 1), 276 integration.StreamBenchSend(1, 1), 277 integration.StreamBenchWrite(20), 278 integration.StreamBenchWrite(10), 279 integration.StreamBenchWrite(1), 280 ) 281 suite.Run( 282 b, template, 283 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 284 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 285 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 286 ) 287 }) 288 289 b.Run("pubsub", func(b *testing.B) { 290 template := ` 291 output: 292 redis_pubsub: 293 url: tcp://localhost:$PORT 294 channel: channel-$ID 295 max_in_flight: $MAX_IN_FLIGHT 296 297 input: 298 redis_pubsub: 299 url: tcp://localhost:$PORT 300 channels: [ channel-$ID ] 301 ` 302 suite := integration.StreamBenchs( 303 integration.StreamBenchSend(20, 1), 304 integration.StreamBenchSend(10, 1), 305 integration.StreamBenchSend(1, 1), 306 integration.StreamBenchWrite(20), 307 integration.StreamBenchWrite(10), 308 integration.StreamBenchWrite(1), 309 ) 310 suite.Run( 311 b, template, 312 integration.StreamTestOptSleepAfterInput(500*time.Millisecond), 313 integration.StreamTestOptSleepAfterOutput(500*time.Millisecond), 314 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 315 ) 316 }) 317 318 b.Run("list", func(b *testing.B) { 319 template := ` 320 output: 321 redis_list: 322 url: tcp://localhost:$PORT 323 key: key-$ID 324 max_in_flight: $MAX_IN_FLIGHT 325 326 input: 327 redis_list: 328 url: tcp://localhost:$PORT 329 key: key-$ID 330 ` 331 suite := integration.StreamBenchs( 332 integration.StreamBenchSend(20, 1), 333 integration.StreamBenchSend(10, 1), 334 integration.StreamBenchSend(1, 1), 335 integration.StreamBenchWrite(20), 336 integration.StreamBenchWrite(10), 337 integration.StreamBenchWrite(1), 338 ) 339 suite.Run( 340 b, template, 341 integration.StreamTestOptSleepAfterInput(100*time.Millisecond), 342 integration.StreamTestOptSleepAfterOutput(100*time.Millisecond), 343 integration.StreamTestOptPort(resource.GetPort("6379/tcp")), 344 ) 345 }) 346 })