github.com/Jeffail/benthos/v3@v3.65.0/lib/test/integration/aws_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/aws/aws-sdk-go/aws"
    11  	"github.com/aws/aws-sdk-go/aws/credentials"
    12  	"github.com/aws/aws-sdk-go/aws/session"
    13  	"github.com/aws/aws-sdk-go/service/s3"
    14  	"github.com/aws/aws-sdk-go/service/sqs"
    15  	"github.com/gofrs/uuid"
    16  	"github.com/ory/dockertest/v3"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func createBucketQueue(s3Port, sqsPort, id string) error {
    22  	endpoint := fmt.Sprintf("http://localhost:%v", s3Port)
    23  	bucket := "bucket-" + id
    24  	sqsQueue := "queue-" + id
    25  	sqsEndpoint := fmt.Sprintf("http://localhost:%v", sqsPort)
    26  	sqsQueueURL := fmt.Sprintf("%v/queue/%v", sqsEndpoint, sqsQueue)
    27  
    28  	var s3Client *s3.S3
    29  	if s3Port != "" {
    30  		s3Client = s3.New(session.Must(session.NewSession(&aws.Config{
    31  			S3ForcePathStyle: aws.Bool(true),
    32  			Credentials:      credentials.NewStaticCredentials("xxxxx", "xxxxx", "xxxxx"),
    33  			Endpoint:         aws.String(endpoint),
    34  			Region:           aws.String("eu-west-1"),
    35  		})))
    36  	}
    37  
    38  	var sqsClient *sqs.SQS
    39  	if sqsPort != "" {
    40  		sqsClient = sqs.New(session.Must(session.NewSession(&aws.Config{
    41  			Credentials: credentials.NewStaticCredentials("xxxxx", "xxxxx", "xxxxx"),
    42  			Endpoint:    aws.String(sqsEndpoint),
    43  			Region:      aws.String("eu-west-1"),
    44  		})))
    45  	}
    46  
    47  	if s3Client != nil {
    48  		if _, err := s3Client.CreateBucket(&s3.CreateBucketInput{
    49  			Bucket: &bucket,
    50  		}); err != nil {
    51  			return err
    52  		}
    53  	}
    54  
    55  	if sqsClient != nil {
    56  		if _, err := sqsClient.CreateQueue(&sqs.CreateQueueInput{
    57  			QueueName: aws.String(sqsQueue),
    58  		}); err != nil {
    59  			return err
    60  		}
    61  	}
    62  
    63  	if s3Client != nil {
    64  		if err := s3Client.WaitUntilBucketExists(&s3.HeadBucketInput{
    65  			Bucket: &bucket,
    66  		}); err != nil {
    67  			return err
    68  		}
    69  	}
    70  
    71  	var sqsQueueArn *string
    72  	if sqsPort != "" {
    73  		res, err := sqsClient.GetQueueAttributes(&sqs.GetQueueAttributesInput{
    74  			QueueUrl:       &sqsQueueURL,
    75  			AttributeNames: []*string{aws.String("All")},
    76  		})
    77  		if err != nil {
    78  			return err
    79  		}
    80  		sqsQueueArn = res.Attributes["QueueArn"]
    81  	}
    82  
    83  	if s3Port != "" && sqsPort != "" {
    84  		if _, err := s3Client.PutBucketNotificationConfiguration(&s3.PutBucketNotificationConfigurationInput{
    85  			Bucket: &bucket,
    86  			NotificationConfiguration: &s3.NotificationConfiguration{
    87  				QueueConfigurations: []*s3.QueueConfiguration{
    88  					{
    89  						Events: []*string{
    90  							aws.String("s3:ObjectCreated:*"),
    91  						},
    92  						QueueArn: sqsQueueArn,
    93  					},
    94  				},
    95  			},
    96  		}); err != nil {
    97  			return err
    98  		}
    99  	}
   100  	return nil
   101  }
   102  
   103  var _ = registerIntegrationTest("aws", func(t *testing.T) {
   104  	t.Parallel()
   105  
   106  	pool, err := dockertest.NewPool("")
   107  	require.NoError(t, err)
   108  
   109  	pool.MaxWait = time.Second * 30
   110  
   111  	resource, err := pool.RunWithOptions(&dockertest.RunOptions{
   112  		Repository:   "localstack/localstack",
   113  		ExposedPorts: []string{"4566/tcp"},
   114  		Env:          []string{"SERVICES=s3,sqs"},
   115  	})
   116  	require.NoError(t, err)
   117  	t.Cleanup(func() {
   118  		assert.NoError(t, pool.Purge(resource))
   119  	})
   120  
   121  	resource.Expire(900)
   122  
   123  	servicePort := resource.GetPort("4566/tcp")
   124  
   125  	require.NoError(t, pool.Retry(func() error {
   126  		u4, err := uuid.NewV4()
   127  		require.NoError(t, err)
   128  
   129  		return createBucketQueue(servicePort, servicePort, u4.String())
   130  	}))
   131  
   132  	t.Run("s3_to_sqs", func(t *testing.T) {
   133  		template := `
   134  output:
   135    aws_s3:
   136      bucket: bucket-$ID
   137      endpoint: http://localhost:$PORT
   138      force_path_style_urls: true
   139      region: eu-west-1
   140      path: ${!count("$ID")}.txt
   141      credentials:
   142        id: xxxxx
   143        secret: xxxxx
   144        token: xxxxx
   145      batching:
   146        count: $OUTPUT_BATCH_COUNT
   147  
   148  input:
   149    aws_s3:
   150      bucket: bucket-$ID
   151      endpoint: http://localhost:$PORT
   152      force_path_style_urls: true
   153      region: eu-west-1
   154      delete_objects: true
   155      sqs:
   156        url: http://localhost:$PORT/queue/queue-$ID
   157        key_path: Records.*.s3.object.key
   158        endpoint: http://localhost:$PORT
   159      credentials:
   160        id: xxxxx
   161        secret: xxxxx
   162        token: xxxxx
   163  `
   164  		integration.StreamTests(
   165  			integration.StreamTestOpenClose(),
   166  			// integration.StreamTestMetadata(), Does dumb stuff with rewriting keys.
   167  			// integration.StreamTestSendBatch(10),
   168  			integration.StreamTestSendBatchCount(10),
   169  			integration.StreamTestStreamSequential(10),
   170  			// integration.StreamTestStreamParallel(10),
   171  			// integration.StreamTestStreamParallelLossy(10),
   172  			integration.StreamTestStreamParallelLossyThroughReconnect(10),
   173  		).Run(
   174  			t, template,
   175  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   176  				require.NoError(t, createBucketQueue(servicePort, servicePort, testID))
   177  			}),
   178  			integration.StreamTestOptPort(servicePort),
   179  			integration.StreamTestOptAllowDupes(),
   180  		)
   181  	})
   182  
   183  	t.Run("s3_to_sqs_lines", func(t *testing.T) {
   184  		template := `
   185  output:
   186    aws_s3:
   187      bucket: bucket-$ID
   188      endpoint: http://localhost:$PORT
   189      force_path_style_urls: true
   190      region: eu-west-1
   191      path: ${!count("$ID")}.txt
   192      credentials:
   193        id: xxxxx
   194        secret: xxxxx
   195        token: xxxxx
   196      batching:
   197        count: $OUTPUT_BATCH_COUNT
   198        processors:
   199          - archive:
   200              format: lines
   201  
   202  input:
   203    aws_s3:
   204      bucket: bucket-$ID
   205      endpoint: http://localhost:$PORT
   206      force_path_style_urls: true
   207      region: eu-west-1
   208      delete_objects: true
   209      codec: lines
   210      sqs:
   211        url: http://localhost:$PORT/queue/queue-$ID
   212        key_path: Records.*.s3.object.key
   213        endpoint: http://localhost:$PORT
   214        delay_period: 1s
   215      credentials:
   216        id: xxxxx
   217        secret: xxxxx
   218        token: xxxxx
   219  `
   220  		integration.StreamTests(
   221  			integration.StreamTestOpenClose(),
   222  			integration.StreamTestStreamSequential(20),
   223  			integration.StreamTestSendBatchCount(10),
   224  			integration.StreamTestStreamParallelLossyThroughReconnect(20),
   225  		).Run(
   226  			t, template,
   227  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   228  				if vars.OutputBatchCount == 0 {
   229  					vars.OutputBatchCount = 1
   230  				}
   231  				require.NoError(t, createBucketQueue(servicePort, servicePort, testID))
   232  			}),
   233  			integration.StreamTestOptPort(servicePort),
   234  			integration.StreamTestOptAllowDupes(),
   235  		)
   236  	})
   237  
   238  	t.Run("s3", func(t *testing.T) {
   239  		template := `
   240  output:
   241    aws_s3:
   242      bucket: bucket-$ID
   243      endpoint: http://localhost:$PORT
   244      force_path_style_urls: true
   245      region: eu-west-1
   246      path: ${!count("$ID")}.txt
   247      credentials:
   248        id: xxxxx
   249        secret: xxxxx
   250        token: xxxxx
   251      batching:
   252        count: $OUTPUT_BATCH_COUNT
   253  
   254  input:
   255    aws_s3:
   256      bucket: bucket-$ID
   257      endpoint: http://localhost:$PORT
   258      force_path_style_urls: true
   259      region: eu-west-1
   260      delete_objects: true
   261      credentials:
   262        id: xxxxx
   263        secret: xxxxx
   264        token: xxxxx
   265  `
   266  		integration.StreamTests(
   267  			integration.StreamTestOpenCloseIsolated(),
   268  			integration.StreamTestStreamIsolated(10),
   269  		).Run(
   270  			t, template,
   271  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   272  				require.NoError(t, createBucketQueue(servicePort, "", testID))
   273  			}),
   274  			integration.StreamTestOptPort(servicePort),
   275  			integration.StreamTestOptVarOne("false"),
   276  		)
   277  	})
   278  
   279  	t.Run("sqs", func(t *testing.T) {
   280  		template := `
   281  output:
   282    aws_sqs:
   283      url: http://localhost:$PORT/queue/queue-$ID
   284      endpoint: http://localhost:$PORT
   285      region: eu-west-1
   286      credentials:
   287        id: xxxxx
   288        secret: xxxxx
   289        token: xxxxx
   290      max_in_flight: $MAX_IN_FLIGHT
   291      batching:
   292        count: $OUTPUT_BATCH_COUNT
   293  
   294  input:
   295    aws_sqs:
   296      url: http://localhost:$PORT/queue/queue-$ID
   297      endpoint: http://localhost:$PORT
   298      region: eu-west-1
   299      credentials:
   300        id: xxxxx
   301        secret: xxxxx
   302        token: xxxxx
   303  `
   304  		integration.StreamTests(
   305  			integration.StreamTestOpenClose(),
   306  			integration.StreamTestSendBatch(10),
   307  			integration.StreamTestStreamSequential(50),
   308  			integration.StreamTestStreamParallel(50),
   309  			integration.StreamTestStreamParallelLossy(50),
   310  			integration.StreamTestStreamParallelLossyThroughReconnect(50),
   311  		).Run(
   312  			t, template,
   313  			integration.StreamTestOptPreTest(func(t testing.TB, ctx context.Context, testID string, vars *integration.StreamTestConfigVars) {
   314  				require.NoError(t, createBucketQueue("", servicePort, testID))
   315  			}),
   316  			integration.StreamTestOptPort(servicePort),
   317  		)
   318  	})
   319  })