snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
126
internal/consuming/aws_sqs_test.go
Normal file
126
internal/consuming/aws_sqs_test.go
Normal file
@@ -0,0 +1,126 @@
|
||||
//go:build integration
|
||||
|
||||
package consuming
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/url"
|
||||
"os"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/centrifugal/centrifugo/v6/internal/configtypes"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs"
|
||||
"github.com/aws/aws-sdk-go-v2/service/sqs/types"
|
||||
endpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/google/uuid"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAWSConsumerWithLocalStack(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Set dummy credentials for LocalStack.
|
||||
_ = os.Setenv("AWS_ACCESS_KEY_ID", "test")
|
||||
_ = os.Setenv("AWS_SECRET_ACCESS_KEY", "test")
|
||||
_ = os.Setenv("AWS_DEFAULT_REGION", "us-east-1")
|
||||
defer func() {
|
||||
_ = os.Unsetenv("AWS_ACCESS_KEY_ID")
|
||||
_ = os.Unsetenv("AWS_SECRET_ACCESS_KEY")
|
||||
_ = os.Unsetenv("AWS_DEFAULT_REGION")
|
||||
}()
|
||||
|
||||
awsCfg, err := config.LoadDefaultConfig(ctx,
|
||||
config.WithRegion("us-east-1"),
|
||||
config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider("test", "test", "")),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
parsedURL, _ := url.Parse("http://localhost:4566")
|
||||
|
||||
sqsOpts := []func(*sqs.Options){
|
||||
sqs.WithEndpointResolverV2(overrideEndpointResolver{
|
||||
Endpoint: endpoints.Endpoint{
|
||||
URI: *parsedURL,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
sqsClient := sqs.NewFromConfig(awsCfg, sqsOpts...)
|
||||
|
||||
queueName := "test-queue-" + uuid.NewString()
|
||||
createQueueOutput, err := sqsClient.CreateQueue(ctx, &sqs.CreateQueueInput{
|
||||
QueueName: &queueName,
|
||||
Attributes: map[string]string{},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
queueURL := *createQueueOutput.QueueUrl
|
||||
|
||||
cfg := AwsSqsConsumerConfig{
|
||||
Region: "us-east-1",
|
||||
Queues: []string{queueURL},
|
||||
MaxNumberOfMessages: 10,
|
||||
PollWaitTime: configtypes.Duration(2 * time.Second),
|
||||
MethodAttribute: "Method",
|
||||
LocalStackEndpoint: "http://localhost:4566",
|
||||
}
|
||||
|
||||
var processedCount atomic.Int64
|
||||
|
||||
done1 := make(chan struct{})
|
||||
done2 := make(chan struct{})
|
||||
|
||||
createConsumer := func(doneCh chan struct{}) *AwsSqsConsumer {
|
||||
dispatcher := &MockDispatcher{
|
||||
onDispatchCommand: func(ctx context.Context, method string, data []byte) error {
|
||||
close(doneCh)
|
||||
processedCount.Add(1)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
consumer, err := NewAwsSqsConsumer(cfg, dispatcher, testCommon(prometheus.NewRegistry()))
|
||||
require.NoError(t, err)
|
||||
return consumer
|
||||
}
|
||||
|
||||
ctx1, cancel1 := context.WithCancel(context.Background())
|
||||
defer cancel1()
|
||||
go func() {
|
||||
if err := createConsumer(done1).Run(ctx1); err != nil && !errors.Is(err, context.Canceled) {
|
||||
t.Errorf("consumer1 error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
ctx2, cancel2 := context.WithCancel(context.Background())
|
||||
defer cancel2()
|
||||
go func() {
|
||||
if err := createConsumer(done2).Run(ctx2); err != nil && !errors.Is(err, context.Canceled) {
|
||||
t.Errorf("consumer2 error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = sqsClient.SendMessage(ctx, &sqs.SendMessageInput{
|
||||
QueueUrl: &queueURL,
|
||||
MessageBody: aws.String("Test message body"),
|
||||
MessageAttributes: map[string]types.MessageAttributeValue{
|
||||
"Method": {
|
||||
DataType: aws.String("String"),
|
||||
StringValue: aws.String("testMethod"),
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
waitAnyCh(t, []chan struct{}{done1, done2}, 5*time.Second, "timeout waiting for message processing")
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
require.Equal(t, int64(1), processedCount.Load(), "only one consumer must receive the message")
|
||||
}
|
||||
Reference in New Issue
Block a user