- Standalone SQS-service repository - Multi-tenant message queue service, AWS SQS compatible - Based on GoAws, with mutable tenants, auth, WebUI, Redis persistence - Ready for independent development and deployment - See doc/ and README.md for architecture and usage
669 lines
17 KiB
Go
669 lines
17 KiB
Go
package gosqs
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"shared-sqs/app/conf"
|
|
|
|
"shared-sqs/app/fixtures"
|
|
|
|
"shared-sqs/app/models"
|
|
"shared-sqs/app/utils"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// TODO - Admiral-Piett these are better but still screwy. It's easy to have race conditions in here, so
|
|
// we have to name all the queues uniquely and leave them around so we're not resetting ourselves.
|
|
// Stupid. Handle the global memory issues and this can be easily resolved.
|
|
func Test_PeriodicTasks_deletes_deduplication_period_upon_expiration(t *testing.T) {
|
|
models.DeduplicationPeriod = 20 * time.Millisecond
|
|
quit := make(chan bool)
|
|
defer func() {
|
|
models.ResetApp()
|
|
quit <- true
|
|
models.DeduplicationPeriod = 5 * time.Minute
|
|
}()
|
|
|
|
qName := "gosqs-dedupe-queue1"
|
|
mainQueue := &models.Queue{
|
|
Name: qName,
|
|
URL: fmt.Sprintf("%s/%s", fixtures.BASE_URL, qName),
|
|
Arn: fmt.Sprintf("%s:%s", fixtures.BASE_SQS_ARN, qName),
|
|
Duplicates: map[string]time.Time{
|
|
"12345": time.Now(),
|
|
},
|
|
}
|
|
models.SyncQueues.Lock()
|
|
models.SyncQueues.Queues[qName] = mainQueue
|
|
models.SyncQueues.Unlock()
|
|
|
|
go PeriodicTasks(10*time.Millisecond, quit)
|
|
|
|
assertions := func() bool {
|
|
models.SyncQueues.Lock()
|
|
defer models.SyncQueues.Unlock()
|
|
|
|
ok := 0 == len(mainQueue.Duplicates)
|
|
if !ok {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
assert.Eventually(t, assertions, 10*time.Second, 10*time.Millisecond)
|
|
}
|
|
|
|
func Test_PeriodicTasks_VisibilityTimeout_expires(t *testing.T) {
|
|
quit := make(chan bool)
|
|
defer func() {
|
|
models.ResetApp()
|
|
quit <- true
|
|
}()
|
|
qName := "gosqs-visibility-queue1"
|
|
mainQueue := &models.Queue{
|
|
Name: qName,
|
|
URL: fmt.Sprintf("%s/%s", fixtures.BASE_URL, qName),
|
|
Arn: fmt.Sprintf("%s:%s", fixtures.BASE_SQS_ARN, qName),
|
|
}
|
|
mainQueue.Messages = append(mainQueue.Messages, models.SqsMessage{
|
|
MessageBody: "1",
|
|
ReceiptHandle: "12345",
|
|
VisibilityTimeout: time.Now().Add(30 * time.Millisecond),
|
|
})
|
|
|
|
models.SyncQueues.Lock()
|
|
models.SyncQueues.Queues[qName] = mainQueue
|
|
models.SyncQueues.Unlock()
|
|
|
|
go PeriodicTasks(10*time.Millisecond, quit)
|
|
|
|
assertions := func() bool {
|
|
models.SyncQueues.Lock()
|
|
defer models.SyncQueues.Unlock()
|
|
|
|
ok := !mainQueue.Messages[0].ReceiptTime.IsZero()
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = "1" == mainQueue.Messages[0].MessageBody
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = "" == mainQueue.Messages[0].ReceiptHandle
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = 1 == mainQueue.Messages[0].Retry
|
|
if !ok {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
assert.Eventually(t, assertions, 10*time.Second, 10*time.Millisecond)
|
|
}
|
|
|
|
func Test_PeriodicTasks_moves_single_message_to_dead_letter_queue_upon_passing_receive_count(t *testing.T) {
|
|
quit := make(chan bool)
|
|
defer func() {
|
|
models.ResetApp()
|
|
quit <- true
|
|
}()
|
|
|
|
qName := "gosqs-main-queue1"
|
|
dlqName := "gosqs-dead-letter-queue1"
|
|
dlqQueue := &models.Queue{
|
|
Arn: fmt.Sprintf("%s/%s", fixtures.BASE_SQS_ARN, dlqName),
|
|
Name: dlqName,
|
|
URL: fmt.Sprintf("%s/%s", fixtures.BASE_URL, dlqName),
|
|
}
|
|
mainQueue := &models.Queue{
|
|
Arn: fmt.Sprintf("%s/%s", fixtures.BASE_SQS_ARN, qName),
|
|
DeadLetterQueue: dlqQueue,
|
|
MaxReceiveCount: 1,
|
|
Name: qName,
|
|
URL: fmt.Sprintf("%s/%s", fixtures.BASE_URL, qName),
|
|
}
|
|
|
|
go PeriodicTasks(10*time.Millisecond, quit)
|
|
|
|
models.SyncQueues.Lock()
|
|
mainQueue.Messages = append(mainQueue.Messages, models.SqsMessage{
|
|
MessageBody: "1",
|
|
Retry: 100,
|
|
ReceiptHandle: "12345",
|
|
VisibilityTimeout: time.Now().Add(10 * time.Millisecond),
|
|
})
|
|
models.SyncQueues.Queues[qName] = mainQueue
|
|
models.SyncQueues.Queues[dlqName] = dlqQueue
|
|
models.SyncQueues.Unlock()
|
|
|
|
assertions := func() bool {
|
|
models.SyncQueues.Lock()
|
|
defer models.SyncQueues.Unlock()
|
|
|
|
ok := len(dlqQueue.Messages) == 1
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = "1" == dlqQueue.Messages[0].MessageBody
|
|
if !ok {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
assert.Eventually(t, assertions, 10*time.Second, 10*time.Millisecond)
|
|
}
|
|
|
|
func Test_PeriodicTasks_moves_multiple_messages_to_dead_letter_queue_upon_passing_receive_count(t *testing.T) {
|
|
quit := make(chan bool)
|
|
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
|
|
defer func() {
|
|
models.ResetApp()
|
|
quit <- true
|
|
}()
|
|
|
|
mainQueue := models.SyncQueues.Queues["unit-queue2"]
|
|
dlqQueue := models.SyncQueues.Queues["dead-letter-queue1"]
|
|
|
|
assert.Len(t, dlqQueue.Messages, 0)
|
|
|
|
go PeriodicTasks(10*time.Millisecond, quit)
|
|
|
|
models.SyncQueues.Lock()
|
|
mainQueue.Messages = append(mainQueue.Messages, models.SqsMessage{
|
|
MessageBody: "1",
|
|
Retry: 100,
|
|
ReceiptHandle: "12345",
|
|
})
|
|
mainQueue.Messages = append(mainQueue.Messages, models.SqsMessage{
|
|
MessageBody: "2",
|
|
Retry: 100,
|
|
ReceiptHandle: "23456",
|
|
})
|
|
models.SyncQueues.Unlock()
|
|
|
|
assertions := func() bool {
|
|
models.SyncQueues.Lock()
|
|
defer models.SyncQueues.Unlock()
|
|
|
|
ok := len(dlqQueue.Messages) == 2
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = "1" == dlqQueue.Messages[0].MessageBody
|
|
if !ok {
|
|
return false
|
|
}
|
|
ok = "2" == dlqQueue.Messages[1].MessageBody
|
|
if !ok {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
assert.Eventually(t, assertions, 10*time.Second, 10*time.Millisecond)
|
|
}
|
|
|
|
// TODO - I think all these below belong in handler tests, not in here. Double check the relevant
|
|
// handlers for coverage and delete.
|
|
func TestSendingAndReceivingFromFIFOQueueReturnsSameMessageOnError(t *testing.T) {
|
|
done := make(chan bool)
|
|
go PeriodicTasks(1*time.Second, done)
|
|
|
|
// create a queue
|
|
req, err := http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := url.Values{}
|
|
form.Add("Action", "CreateQueue")
|
|
form.Add("QueueName", "requeue-reset.fifo")
|
|
form.Add("Attribute.1.Name", "VisibilityTimeout")
|
|
form.Add("Attribute.1.Value", "2")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ := CreateQueueV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
// send a message
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("MessageBody", "1")
|
|
form.Add("MessageGroupId", "GROUP-X")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
|
|
// send a message
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("MessageBody", "2")
|
|
form.Add("MessageGroupId", "GROUP-X")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
|
|
// receive message
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "ReceiveMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, resp := ReceiveMessageV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
result := resp.GetResult().(models.ReceiveMessageResult)
|
|
receiptHandleFirst := result.Messages[0].ReceiptHandle
|
|
if string(result.Messages[0].Body) != "1" {
|
|
t.Fatalf("should have received body 1: %s", err)
|
|
}
|
|
|
|
// try to receive another message and we should get none
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "ReceiveMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = ReceiveMessageV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
if len(models.SyncQueues.Queues["requeue-reset.fifo"].FIFOMessages) != 1 {
|
|
t.Fatal("there should be only 1 group locked")
|
|
}
|
|
|
|
if models.SyncQueues.Queues["requeue-reset.fifo"].FIFOMessages["GROUP-X"] != 0 {
|
|
t.Fatal("there should be GROUP-X locked")
|
|
}
|
|
|
|
// remove message
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "DeleteMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("ReceiptHandle", receiptHandleFirst)
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = DeleteMessageV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
if len(models.SyncQueues.Queues["requeue-reset.fifo"].Messages) != 1 {
|
|
t.Fatal("there should be only 1 message in queue")
|
|
}
|
|
|
|
// receive message - loop until visibility timeouts
|
|
for {
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "ReceiveMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/requeue-reset.fifo")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, resp := ReceiveMessageV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
result := resp.GetResult().(models.ReceiveMessageResult)
|
|
if len(result.Messages) == 0 {
|
|
continue
|
|
}
|
|
|
|
if string(result.Messages[0].Body) != "2" {
|
|
t.Fatalf("should have received body 2: %s", err)
|
|
}
|
|
break
|
|
}
|
|
|
|
done <- true
|
|
}
|
|
|
|
func TestSendMessage_POST_DuplicatationNotAppliedToStandardQueue(t *testing.T) {
|
|
done := make(chan bool)
|
|
go PeriodicTasks(1*time.Second, done)
|
|
|
|
// create a queue
|
|
req, err := http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := url.Values{}
|
|
form.Add("Action", "CreateQueue")
|
|
form.Add("QueueName", "stantdard-testing")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ := CreateQueueV1(req)
|
|
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/stantdard-testing")
|
|
form.Add("MessageBody", "Test1")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["stantdard-testing"].Messages) == 0 {
|
|
t.Fatal("there should be 1 message in queue")
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/stantdard-testing")
|
|
form.Add("MessageBody", "Test2")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["stantdard-testing"].Messages) == 1 {
|
|
t.Fatal("there should be 2 messages in queue")
|
|
}
|
|
done <- true
|
|
}
|
|
|
|
func TestSendMessage_POST_DuplicatationDisabledOnFifoQueue(t *testing.T) {
|
|
done := make(chan bool)
|
|
go PeriodicTasks(1*time.Second, done)
|
|
|
|
// create a queue
|
|
req, err := http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := url.Values{}
|
|
form.Add("Action", "CreateQueue")
|
|
form.Add("QueueName", "no-dup-testing.fifo")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ := CreateQueueV1(req)
|
|
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/no-dup-testing.fifo")
|
|
form.Add("MessageBody", "Test1")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["no-dup-testing.fifo"].Messages) == 0 {
|
|
t.Fatal("there should be 1 message in queue")
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/no-dup-testing.fifo")
|
|
form.Add("MessageBody", "Test2")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["no-dup-testing.fifo"].Messages) != 2 {
|
|
t.Fatal("there should be 2 message in queue")
|
|
}
|
|
done <- true
|
|
}
|
|
|
|
func TestSendMessage_POST_DuplicatationEnabledOnFifoQueue(t *testing.T) {
|
|
done := make(chan bool)
|
|
go PeriodicTasks(1*time.Second, done)
|
|
|
|
// create a queue
|
|
req, err := http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
form := url.Values{}
|
|
form.Add("Action", "CreateQueue")
|
|
form.Add("QueueName", "dup-testing.fifo")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ := CreateQueueV1(req)
|
|
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
models.SyncQueues.Queues["dup-testing.fifo"].EnableDuplicates = true
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/dup-testing.fifo")
|
|
form.Add("MessageBody", "Test1")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["dup-testing.fifo"].Messages) == 0 {
|
|
t.Fatal("there should be 1 message in queue")
|
|
}
|
|
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/dup-testing.fifo")
|
|
form.Add("MessageBody", "Test2")
|
|
form.Add("MessageDeduplicationId", "123")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
|
|
// Check the status code is what we expect.
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
if len(models.SyncQueues.Queues["dup-testing.fifo"].Messages) != 1 {
|
|
t.Fatal("there should be 1 message in queue")
|
|
}
|
|
if body := models.SyncQueues.Queues["dup-testing.fifo"].Messages[0].MessageBody; string(body) == "Test2" {
|
|
t.Fatal("duplicate message should not be added to queue")
|
|
}
|
|
done <- true
|
|
}
|
|
|
|
func TestSendMessage_POST_DelaySeconds(t *testing.T) {
|
|
// create a queue
|
|
req, err := http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
form := url.Values{}
|
|
form.Add("Action", "CreateQueue")
|
|
form.Add("QueueName", "sendmessage-delay")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ := CreateQueueV1(req)
|
|
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
// send a message
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
form = url.Values{}
|
|
form.Add("Action", "SendMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/sendmessage-delay")
|
|
form.Add("MessageBody", "1")
|
|
form.Add("DelaySeconds", "2")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
|
|
status, _ = SendMessageV1(req)
|
|
if status != http.StatusOK {
|
|
t.Errorf("handler returned wrong status code: got \n%v want %v",
|
|
status, http.StatusOK)
|
|
}
|
|
|
|
// receive message before delay is up
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
form = url.Values{}
|
|
form.Add("Action", "ReceiveMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/sendmessage-delay")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
status, _ = ReceiveMessageV1(req)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
|
|
// receive message with wait should return after delay
|
|
req, err = http.NewRequest("POST", "/", nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
form = url.Values{}
|
|
form.Add("Action", "ReceiveMessage")
|
|
form.Add("QueueUrl", "http://localhost:4100/queue/sendmessage-delay")
|
|
form.Add("WaitTimeSeconds", "10")
|
|
form.Add("Version", "2012-11-05")
|
|
req.PostForm = form
|
|
start := time.Now()
|
|
status, _ = ReceiveMessageV1(req)
|
|
elapsed := time.Since(start)
|
|
assert.Equal(t, status, http.StatusOK)
|
|
if elapsed < 1*time.Second {
|
|
t.Errorf("handler didn't wait at all")
|
|
}
|
|
if elapsed > 4*time.Second {
|
|
t.Errorf("handler didn't need to wait all WaitTimeSeconds=10, only DelaySeconds=2")
|
|
}
|
|
}
|
|
|
|
func TestCreateErrorResponseV1(t *testing.T) {
|
|
expectedResponse := models.ErrorResponse{
|
|
Result: models.ErrorResult{
|
|
Type: "Not Found",
|
|
Code: "AWS.SimpleQueueService.NonExistentQueue",
|
|
Message: "The specified queue does not exist for this wsdl version.",
|
|
},
|
|
RequestId: "00000000-0000-0000-0000-000000000000",
|
|
}
|
|
status, response := utils.CreateErrorResponseV1("QueueNotFound", true)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, status)
|
|
assert.Equal(t, expectedResponse, response)
|
|
}
|
|
|
|
// waitTimeout waits for the waitgroup for the specified max timeout.
|
|
// Returns true if waiting timed out.
|
|
// credits: https://stackoverflow.com/questions/32840687/timeout-for-waitgroup-wait
|
|
func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
|
|
c := make(chan struct{})
|
|
go func() {
|
|
defer close(c)
|
|
wg.Wait()
|
|
}()
|
|
select {
|
|
case <-c:
|
|
return false // completed normally
|
|
case <-time.After(timeout):
|
|
return true // timed out
|
|
}
|
|
}
|