From f1de347ef538f5d9059cbf046b15a00433ccba2d Mon Sep 17 00:00:00 2001 From: ksaiki Date: Mon, 20 May 2024 18:27:09 +0900 Subject: [PATCH] Add tests --- app/gosqs/send_message_test.go | 126 ++++++++++++++++++++------ app/sqs_messages.go | 14 --- smoke_tests/sqs_send_message_test.go | 127 +++++++++++++++++++++------ 3 files changed, 199 insertions(+), 68 deletions(-) diff --git a/app/gosqs/send_message_test.go b/app/gosqs/send_message_test.go index 142312b3..a0fc1431 100644 --- a/app/gosqs/send_message_test.go +++ b/app/gosqs/send_message_test.go @@ -3,6 +3,7 @@ package gosqs import ( "net/http" "testing" + "time" "github.com/Admiral-Piett/goaws/app" "github.com/Admiral-Piett/goaws/app/fixtures" @@ -38,19 +39,102 @@ func TestSendMessageV1_Success(t *testing.T) { _, r := utils.GenerateRequestInfo("POST", "/", nil, true) status, response := SendMessageV1(r) - // Check the status code is what we expect. - if status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) + // Check the queue + assert.Equal(t, 1, len(q.Messages)) + msg := q.Messages[0] + assert.Equal(t, "Test Message", string(msg.MessageBody)) + + // Check the response + assert.Equal(t, http.StatusOK, status) + sendMessageResponse, ok := response.(models.SendMessageResponse) + assert.True(t, ok) + assert.NotEmpty(t, sendMessageResponse.Result.MD5OfMessageBody) + // No FIFO Sequence + assert.Empty(t, sendMessageResponse.Result.SequenceNumber) +} + +func TestSendMessageV1_Success_FIFOQueue(t *testing.T) { + app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT + defer func() { + utils.ResetApp() + utils.REQUEST_TRANSFORMER = utils.TransformRequest + }() + + sendMessageRequest_success := models.SendMessageRequest{ + QueueUrl: "http://localhost:4200/new-queue-1", + MessageBody: "Test Message", + } + utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) { + v := resultingStruct.(*models.SendMessageRequest) + *v = sendMessageRequest_success + return true } - // Check the response body is what we expect. + q := &app.Queue{ + Name: "new-queue-1", + MaximumMessageSize: 1024, + IsFIFO: true, + } + app.SyncQueues.Queues["new-queue-1"] = q + + _, r := utils.GenerateRequestInfo("POST", "/", nil, true) + status, response := SendMessageV1(r) + + // Check the queue + assert.Equal(t, 1, len(q.Messages)) + msg := q.Messages[0] + assert.Equal(t, "Test Message", string(msg.MessageBody)) + + // Check the response + assert.Equal(t, http.StatusOK, status) sendMessageResponse, ok := response.(models.SendMessageResponse) assert.True(t, ok) - if len(sendMessageResponse.Result.MD5OfMessageBody) == 0 { - t.Errorf("handler returned unexpected body: got %v", - sendMessageResponse.Result) + assert.NotEmpty(t, sendMessageResponse.Result.MD5OfMessageBody) + // Should have FIFO Sequence + assert.NotEmpty(t, sendMessageResponse.Result.SequenceNumber) +} + +func TestSendMessageV1_Success_Deduplication(t *testing.T) { + app.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT + defer func() { + utils.ResetApp() + utils.REQUEST_TRANSFORMER = utils.TransformRequest + }() + + sendMessageRequest_success := models.SendMessageRequest{ + QueueUrl: "http://localhost:4200/new-queue-1", + MessageBody: "Test Message", + MessageDeduplicationId: "1", + } + utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request) (success bool) { + v := resultingStruct.(*models.SendMessageRequest) + *v = sendMessageRequest_success + return true } + + q := &app.Queue{ + Name: "new-queue-1", + MaximumMessageSize: 1024, + IsFIFO: true, + EnableDuplicates: true, + Duplicates: make(map[string]time.Time), + } + app.SyncQueues.Queues["new-queue-1"] = q + + _, r := utils.GenerateRequestInfo("POST", "/", nil, true) + status, _ := SendMessageV1(r) + + // Check the queue + assert.Equal(t, 1, len(q.Messages)) + // Check the response + assert.Equal(t, http.StatusOK, status) + + // Send the same message (have DeduplicationId) + status, _ = SendMessageV1(r) + // Response is "success" + assert.Equal(t, http.StatusOK, status) + // Only 1 message should be in the queue + assert.Equal(t, 1, len(q.Messages)) } func TestSendMessageV1_request_transformer_error(t *testing.T) { @@ -96,20 +180,11 @@ func TestSendMessageV1_MaximumMessageSize_MessageTooBig(t *testing.T) { _, r := utils.GenerateRequestInfo("POST", "/", nil, true) status, response := SendMessageV1(r) - // Check the status code is what we expect. - if status != http.StatusBadRequest { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusBadRequest) - } - - // Check the response body is what we expect. + // Check the response + assert.Equal(t, http.StatusBadRequest, status) errorResponse, ok := response.(models.ErrorResponse) assert.True(t, ok) - expected := "MessageTooBig" - if errorResponse.Result.Type != expected { - t.Errorf("handler returned unexpected body: got %v want %v", - errorResponse.Result.Type, expected) - } + assert.Equal(t, "MessageTooBig", errorResponse.Result.Type) } func TestSendMessageV1_POST_QueueNonExistant(t *testing.T) { @@ -135,17 +210,10 @@ func TestSendMessageV1_POST_QueueNonExistant(t *testing.T) { status, response := SendMessageV1(r) // Check the status code is what we expect. - if status != http.StatusBadRequest { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusBadRequest) - } + assert.Equal(t, http.StatusBadRequest, status) // Check the response body is what we expect. errorResponse, ok := response.(models.ErrorResponse) assert.True(t, ok) - expected := "Not Found" - if errorResponse.Result.Type != expected { - t.Errorf("handler returned unexpected body: got %v want %v", - errorResponse.Result.Type, expected) - } + assert.Equal(t, "Not Found", errorResponse.Result.Type) } diff --git a/app/sqs_messages.go b/app/sqs_messages.go index e384bc22..5885a54c 100644 --- a/app/sqs_messages.go +++ b/app/sqs_messages.go @@ -1,19 +1,5 @@ package app -/*** Send Message Response */ -type SendMessageResult struct { - MD5OfMessageAttributes string `xml:"MD5OfMessageAttributes"` - MD5OfMessageBody string `xml:"MD5OfMessageBody"` - MessageId string `xml:"MessageId"` - SequenceNumber string `xml:"SequenceNumber"` -} - -type SendMessageResponse struct { - Xmlns string `xml:"xmlns,attr"` - Result SendMessageResult `xml:"SendMessageResult"` - Metadata ResponseMetadata `xml:"ResponseMetadata"` -} - /*** List Queues Response */ type ListQueuesResult struct { QueueUrl []string `xml:"QueueUrl"` diff --git a/smoke_tests/sqs_send_message_test.go b/smoke_tests/sqs_send_message_test.go index 7e56379d..23e713b3 100644 --- a/smoke_tests/sqs_send_message_test.go +++ b/smoke_tests/sqs_send_message_test.go @@ -5,6 +5,7 @@ import ( "encoding/xml" "net/http" "testing" + "time" "github.com/Admiral-Piett/goaws/app" af "github.com/Admiral-Piett/goaws/app/fixtures" @@ -52,6 +53,28 @@ func Test_SendMessageV1_json_no_attributes(t *testing.T) { QueueUrl: targetQueueUrl, }) assert.Equal(t, "1", getQueueAttributeOutput.Attributes["ApproximateNumberOfMessages"]) + + // Receive message and check attribute + receiveMessageBodyXML := struct { + Action string `xml:"Action"` + Version string `xml:"Version"` + QueueUrl string `xml:"QueueUrl"` + }{ + Action: "ReceiveMessage", + Version: "2012-11-05", + QueueUrl: *targetQueueUrl, + } + e := httpexpect.Default(t, server.URL) + r := e.POST("/"). + WithForm(receiveMessageBodyXML). + Expect(). + Status(http.StatusOK). + Body().Raw() + r3 := app.ReceiveMessageResponse{} + xml.Unmarshal([]byte(r), &r3) + message := r3.Result.Message[0] + assert.Equal(t, targetMessageBody, string(message.Body)) + assert.Equal(t, 0, len(message.MessageAttributes)) } func Test_SendMessageV1_json_with_attributes(t *testing.T) { @@ -73,11 +96,14 @@ func Test_SendMessageV1_json_with_attributes(t *testing.T) { targetMessageBody := "Test_SendMessageV1_json_with_attributes" attr1_dataType := "String" attr1_value := "attr1_value" - attr2_dataType := "String" - attr2_value := "attr1_value" + attr2_dataType := "Number" + attr2_value := "2" + attr3_dataType := "Binary" + attr3_value := []byte("attr3_value") sendMessageOutput, _ := sqsClient.SendMessage(context.TODO(), &sqs.SendMessageInput{ - QueueUrl: targetQueueUrl, - MessageBody: &targetMessageBody, + QueueUrl: targetQueueUrl, + MessageBody: &targetMessageBody, + DelaySeconds: 1, MessageAttributes: map[string]sqstypes.MessageAttributeValue{ "attr1": { DataType: &attr1_dataType, @@ -87,10 +113,17 @@ func Test_SendMessageV1_json_with_attributes(t *testing.T) { DataType: &attr2_dataType, StringValue: &attr2_value, }, + "attr3": { + DataType: &attr3_dataType, + BinaryValue: attr3_value, + }, }, }) assert.NotNil(t, sendMessageOutput.MessageId) + // Wait for DelaySecond + time.Sleep(1 * time.Second) + // Assert 1 message in the queue getQueueAttributeOutput, _ := sqsClient.GetQueueAttributes(context.TODO(), &sqs.GetQueueAttributesInput{ QueueUrl: targetQueueUrl, @@ -99,10 +132,9 @@ func Test_SendMessageV1_json_with_attributes(t *testing.T) { // Receive message and check attribute receiveMessageBodyXML := struct { - Action string `xml:"Action"` - Version string `xml:"Version"` - Attribute1 string `xml:"AttributeName.1"` - QueueUrl string `xml:"QueueUrl"` + Action string `xml:"Action"` + Version string `xml:"Version"` + QueueUrl string `xml:"QueueUrl"` }{ Action: "ReceiveMessage", Version: "2012-11-05", @@ -118,7 +150,26 @@ func Test_SendMessageV1_json_with_attributes(t *testing.T) { xml.Unmarshal([]byte(r), &r3) message := r3.Result.Message[0] assert.Equal(t, targetMessageBody, string(message.Body)) - assert.Equal(t, 2, len(message.MessageAttributes)) + assert.Equal(t, 3, len(message.MessageAttributes)) + var attr1, attr2, attr3 app.ResultMessageAttribute + for _, attr := range message.MessageAttributes { + if attr.Name == "attr1" { + attr1 = *attr + } else if attr.Name == "attr2" { + attr2 = *attr + } else if attr.Name == "attr3" { + attr3 = *attr + } + } + assert.Equal(t, "attr1", attr1.Name) + assert.Equal(t, "String", attr1.Value.DataType) + assert.Equal(t, "attr1_value", attr1.Value.StringValue) + assert.Equal(t, "attr2", attr2.Name) + assert.Equal(t, "Number", attr2.Value.DataType) + assert.Equal(t, "2", attr2.Value.StringValue) + assert.Equal(t, "attr3", attr3.Name) + assert.Equal(t, "Binary", attr3.Value.DataType) + assert.Equal(t, "YXR0cjNfdmFsdWU=", attr3.Value.BinaryValue) // base64 encoded "attr3_value" } func Test_SendMessageV1_json_MaximumMessageSize_TooBig(t *testing.T) { @@ -246,25 +297,30 @@ func Test_SendMessageV1_xml_with_attributes(t *testing.T) { // Target test: send a message sendMessageXML := struct { - Action string `xml:"Action"` - Version string `xml:"Version"` - QueueUrl string `xml:"QueueUrl"` - MessageBody string `xml:"MessageBody"` + Action string `xml:"Action"` + Version string `xml:"Version"` + QueueUrl string `xml:"QueueUrl"` + MessageBody string `xml:"MessageBody"` + DelaySeconds string `xml:"DelaySeconds"` }{ - Action: "SendMessage", - Version: "2012-11-05", - QueueUrl: *targetQueueUrl, - MessageBody: "Test Message", + Action: "SendMessage", + Version: "2012-11-05", + QueueUrl: *targetQueueUrl, + MessageBody: "Test Message", + DelaySeconds: "1", } e := httpexpect.Default(t, server.URL) r := e.POST("/"). WithForm(sendMessageXML). - WithFormField("MessageAttribute.1.Name", "Attr1"). + WithFormField("MessageAttribute.1.Name", "attr1"). WithFormField("MessageAttribute.1.Value.DataType", "String"). - WithFormField("MessageAttribute.1.Value.StringValue", "Value1"). - WithFormField("MessageAttribute.2.Name", "Attr2"). + WithFormField("MessageAttribute.1.Value.StringValue", "attr1_value"). + WithFormField("MessageAttribute.2.Name", "attr2"). WithFormField("MessageAttribute.2.Value.DataType", "Number"). WithFormField("MessageAttribute.2.Value.StringValue", "2"). + WithFormField("MessageAttribute.3.Name", "attr3"). + WithFormField("MessageAttribute.3.Value.DataType", "Binary"). + WithFormField("MessageAttribute.3.Value.BinaryValue", "YXR0cjNfdmFsdWU="). Expect(). Status(http.StatusOK). Body().Raw() @@ -272,12 +328,14 @@ func Test_SendMessageV1_xml_with_attributes(t *testing.T) { xml.Unmarshal([]byte(r), &r3) assert.NotNil(t, r3.MessageId) + // Wait for DelaySecond + time.Sleep(1 * time.Second) + // Receive message and check attribute receiveMessageBodyXML := struct { - Action string `xml:"Action"` - Version string `xml:"Version"` - Attribute1 string `xml:"AttributeName.1"` - QueueUrl string `xml:"QueueUrl"` + Action string `xml:"Action"` + Version string `xml:"Version"` + QueueUrl string `xml:"QueueUrl"` }{ Action: "ReceiveMessage", Version: "2012-11-05", @@ -292,5 +350,24 @@ func Test_SendMessageV1_xml_with_attributes(t *testing.T) { xml.Unmarshal([]byte(r), &r4) message := r4.Result.Message[0] assert.Equal(t, "Test Message", string(message.Body)) - assert.Equal(t, 2, len(message.MessageAttributes)) + assert.Equal(t, 3, len(message.MessageAttributes)) + var attr1, attr2, attr3 app.ResultMessageAttribute + for _, attr := range message.MessageAttributes { + if attr.Name == "attr1" { + attr1 = *attr + } else if attr.Name == "attr2" { + attr2 = *attr + } else if attr.Name == "attr3" { + attr3 = *attr + } + } + assert.Equal(t, "attr1", attr1.Name) + assert.Equal(t, "String", attr1.Value.DataType) + assert.Equal(t, "attr1_value", attr1.Value.StringValue) + assert.Equal(t, "attr2", attr2.Name) + assert.Equal(t, "Number", attr2.Value.DataType) + assert.Equal(t, "2", attr2.Value.StringValue) + assert.Equal(t, "attr3", attr3.Name) + assert.Equal(t, "Binary", attr3.Value.DataType) + assert.Equal(t, "YXR0cjNfdmFsdWU=", attr3.Value.BinaryValue) // base64 encoded "attr3_value" }