Skip to content

adds query compatible tests to SQS #3445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/sdksCommon.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ list(APPEND SDK_TEST_PROJECT_LIST "s3-crt:tests/aws-cpp-sdk-s3-crt-integration-t
list(APPEND SDK_TEST_PROJECT_LIST "s3-encryption:tests/aws-cpp-sdk-s3-encryption-tests,tests/aws-cpp-sdk-s3-encryption-integration-tests")
list(APPEND SDK_TEST_PROJECT_LIST "s3control:tests/aws-cpp-sdk-s3control-integration-tests")
list(APPEND SDK_TEST_PROJECT_LIST "sqs:tests/aws-cpp-sdk-sqs-integration-tests")
list(APPEND SDK_TEST_PROJECT_LIST "sqs:tests/aws-cpp-sdk-sqs-unit-tests")
list(APPEND SDK_TEST_PROJECT_LIST "transfer:tests/aws-cpp-sdk-transfer-tests")
list(APPEND SDK_TEST_PROJECT_LIST "text-to-speech:tests/aws-cpp-sdk-text-to-speech-tests,tests/aws-cpp-sdk-polly-sample")
list(APPEND SDK_TEST_PROJECT_LIST "transcribestreaming:tests/aws-cpp-sdk-transcribestreaming-integ-tests")
Expand Down
33 changes: 33 additions & 0 deletions tests/aws-cpp-sdk-sqs-unit-tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
add_project(aws-cpp-sdk-sqs-unit-tests
"Unit Tests for the SQS SDK Client"
aws-cpp-sdk-sqs
testing-resources
aws_test_main
aws-cpp-sdk-core)

add_definitions(-DRESOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources")

if(MSVC AND BUILD_SHARED_LIBS)
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
endif()

enable_testing()

if(PLATFORM_ANDROID AND BUILD_SHARED_LIBS)
add_library(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/SQSUnitTests.cpp)
else()
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/SQSUnitTests.cpp)
endif()

set_compiler_flags(${PROJECT_NAME})
set_compiler_warnings(${PROJECT_NAME})

target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})

if(MSVC AND BUILD_SHARED_LIBS)
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/DELAYLOAD:aws-cpp-sdk-sqs.dll /DELAYLOAD:aws-cpp-sdk-core.dll")
target_link_libraries(${PROJECT_NAME} delayimp.lib)
endif()

include(GoogleTest)
gtest_add_tests(TARGET ${PROJECT_NAME})
122 changes: 122 additions & 0 deletions tests/aws-cpp-sdk-sqs-unit-tests/SQSUnitTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/monitoring/MonitoringInterface.h>
#include <aws/sqs/SQSClient.h>
#include <aws/sqs/model/GetQueueUrlRequest.h>
#include <aws/testing/MemoryTesting.h>
#include <aws/testing/mocks/aws/auth/MockAWSHttpResourceClient.h>
#include <aws/testing/mocks/http/MockHttpClient.h>
#include <gtest/gtest.h>

#include <memory>

using namespace Aws;
using namespace Aws::Client;
using namespace Aws::Auth;
using namespace Aws::Monitoring;
using namespace Aws::Http;
using namespace Aws::Http::Standard;
using namespace Aws::SQS;
using namespace Aws::SQS::Model;

namespace {
const char* LOG_TAG = "SQSDUnitTest";
} // namespace

class SQSUnitTest : public testing::Test {
protected:
static void SetUpTestSuite() {
#ifdef USE_AWS_MEMORY_MANAGEMENT
test_memory_system.reset(new ExactTestMemorySystem(1024, 128));
options_.memoryManagementOptions.memoryManager = test_memory_system.get();
#endif
InitAPI(options_);
mock_client_factory_ = Aws::MakeShared<MockHttpClientFactory>(LOG_TAG);
mock_http_client_ = Aws::MakeShared<MockHttpClient>(LOG_TAG);
mock_client_factory_->SetClient(mock_http_client_);
SetHttpClientFactory(mock_client_factory_);
AWSCredentials credentials{"mock", "credentials"};
client_ = Aws::MakeShared<SQSClient>("ALLOCATION_TAG", credentials);
}

static void TearDownTestSuite() {
mock_client_factory_.reset();
mock_http_client_.reset();
client_.reset();
ShutdownAPI(options_);
#ifdef USE_AWS_MEMORY_MANAGEMENT
EXPECT_EQ(test_memory_system->GetCurrentOutstandingAllocations(), 0ULL);
EXPECT_EQ(test_memory_system->GetCurrentBytesAllocated(), 0ULL);
EXPECT_TRUE(test_memory_system->IsClean());
if (test_memory_system->GetCurrentOutstandingAllocations() != 0ULL) FAIL();
if (test_memory_system->GetCurrentBytesAllocated() != 0ULL) FAIL();
if (!test_memory_system->IsClean()) FAIL();
test_memory_system.reset();
#endif
}

static SDKOptions options_;
static std::shared_ptr<MockHttpClient> mock_http_client_;
static std::shared_ptr<MockHttpClientFactory> mock_client_factory_;
static std::shared_ptr<SQSClient> client_;
#ifdef USE_AWS_MEMORY_MANAGEMENT
static std::unique_ptr<ExactTestMemorySystem> test_memory_system;
#endif
};

SDKOptions SQSUnitTest::options_;
std::shared_ptr<MockHttpClient> SQSUnitTest::mock_http_client_ = nullptr;
std::shared_ptr<MockHttpClientFactory> SQSUnitTest::mock_client_factory_ = nullptr;
std::shared_ptr<SQSClient> SQSUnitTest::client_ = nullptr;
#ifdef USE_AWS_MEMORY_MANAGEMENT
std::unique_ptr<ExactTestMemorySystem> SQSUnitTest::test_memory_system = nullptr;
#endif

TEST_F(SQSUnitTest, CanParseCodeField) {
// Mock query compatible response
const auto error_response_stream = Aws::MakeShared<StandardHttpRequest>(LOG_TAG, "mockuri", HttpMethod::HTTP_GET);
error_response_stream->SetResponseStreamFactory(Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
auto error_response = Aws::MakeShared<StandardHttpResponse>(LOG_TAG, error_response_stream);
error_response->SetResponseCode(HttpResponseCode::BAD_REQUEST);
error_response->AddHeader("Content-Type", "application/x-amz-json-1.0");
error_response->AddHeader("x-amzn-query-error", "AWS.SimpleQueueService.NonExistentQueue;Sender");
error_response->AddHeader("x-amzn-RequestId", "a918fbf2-457a-4fe1-99ba-5685ce220fc1");

// Add mocked response to client
mock_http_client_->Reset();
mock_http_client_->AddResponseToReturn(error_response, [](IOStream& bodyStream) -> void {
bodyStream << R"({"__type": "com.amazonaws.sqs#QueueDoesNotExist","message": "For those who come after"})";
});
const GetQueueUrlRequest request{};
const auto response = client_->GetQueueUrl(request);
EXPECT_TRUE(!response.IsSuccess());
EXPECT_TRUE(!response.GetError().GetExceptionName().empty());
EXPECT_EQ("AWS.SimpleQueueService.NonExistentQueue", response.GetError().GetExceptionName());
EXPECT_EQ(SQSErrors::QUEUE_DOES_NOT_EXIST, response.GetError().GetErrorType());
}

TEST_F(SQSUnitTest, CanHandleMissingCodeField) {
// Mock query compatible response
const auto error_response_stream = Aws::MakeShared<StandardHttpRequest>(LOG_TAG, "mockuri", HttpMethod::HTTP_GET);
error_response_stream->SetResponseStreamFactory(Aws::Utils::Stream::DefaultResponseStreamFactoryMethod);
auto error_response = Aws::MakeShared<StandardHttpResponse>(LOG_TAG, error_response_stream);
error_response->SetResponseCode(HttpResponseCode::BAD_REQUEST);
error_response->AddHeader("Content-Type", "application/x-amz-json-1.0");
error_response->AddHeader("x-amzn-RequestId", "a918fbf2-457a-4fe1-99ba-5685ce220fc1");

// Add mocked response to client
mock_http_client_->Reset();
mock_http_client_->AddResponseToReturn(error_response, [](IOStream& bodyStream) -> void {
bodyStream << R"({"__type": "com.amazonaws.sqs#QueueDoesNotExist","message": "For those who come after"})";
});
const GetQueueUrlRequest request{};
const auto response = client_->GetQueueUrl(request);
EXPECT_TRUE(!response.IsSuccess());
EXPECT_TRUE(!response.GetError().GetExceptionName().empty());
EXPECT_EQ("QueueDoesNotExist", response.GetError().GetExceptionName());
EXPECT_EQ(SQSErrors::QUEUE_DOES_NOT_EXIST, response.GetError().GetErrorType());
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@

static const char MockHttpAllocationTag[] = "MockHttp";


class MockHttpClient : public Aws::Http::HttpClient
{
public:
using ResponseCallbackTuple = std::pair<std::shared_ptr<Aws::Http::HttpResponse>, std::function<void (Aws::IOStream&)>>;

std::shared_ptr<Aws::Http::HttpResponse> MakeRequest(const std::shared_ptr<Aws::Http::HttpRequest>& request,
Aws::Utils::RateLimits::RateLimiterInterface* readLimiter = nullptr,
Aws::Utils::RateLimits::RateLimiterInterface* writeLimiter = nullptr) const override
Expand All @@ -34,13 +37,14 @@ class MockHttpClient : public Aws::Http::HttpClient

if (m_responsesToUse.size() > 0)
{
std::shared_ptr<Aws::Http::HttpResponse> responseToUse = m_responsesToUse.front();
ResponseCallbackTuple responseToUse = m_responsesToUse.front();
m_responsesToUse.pop();
if (responseToUse)
if (responseToUse.first)
{
responseToUse->SetOriginatingRequest(request);
responseToUse.first->SetOriginatingRequest(request);
responseToUse.second(responseToUse.first->GetResponseBody());
}
return responseToUse;
return responseToUse.first;
}
return Aws::MakeShared<Aws::Http::Standard::StandardHttpResponse>(MockHttpAllocationTag, request);
}
Expand All @@ -54,18 +58,19 @@ class MockHttpClient : public Aws::Http::HttpClient

//these will be cleaned up by the aws client, so if you are testing an aws client, don't worry about freeing the memory
//when you are finished.
void AddResponseToReturn(const std::shared_ptr<Aws::Http::HttpResponse>& response) { m_responsesToUse.push(response); }
void AddResponseToReturn(const std::shared_ptr<Aws::Http::HttpResponse>& response) { m_responsesToUse.emplace(response, [](Aws::IOStream&) -> void {}); }
void AddResponseToReturn(const std::shared_ptr<Aws::Http::HttpResponse>& response, const std::function<void (Aws::IOStream&)>& callbackFucntion) { m_responsesToUse.emplace(response, callbackFucntion); }

void Reset()
{
m_requestsMade.clear();
Aws::Queue<std::shared_ptr<Aws::Http::HttpResponse> > empty;
Aws::Queue<ResponseCallbackTuple> empty;
std::swap(m_responsesToUse, empty);
}

private:
mutable Aws::Vector<Aws::Http::Standard::StandardHttpRequest> m_requestsMade;
mutable Aws::Queue< std::shared_ptr<Aws::Http::HttpResponse> > m_responsesToUse;
mutable Aws::Queue<ResponseCallbackTuple> m_responsesToUse;
};

class MockHttpClientFactory : public Aws::Http::HttpClientFactory
Expand Down
1 change: 1 addition & 0 deletions tools/scripts/run_integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def main():
"aws-cpp-sdk-dynamodb-unit-tests",
"aws-cpp-sdk-dynamodb-integration-tests",
"aws-cpp-sdk-sqs-integration-tests",
"aws-cpp-sdk-sqs-unit-tests",
"aws-cpp-sdk-s3-integration-tests",
"aws-cpp-sdk-s3-unit-tests",
"aws-cpp-sdk-s3-crt-integration-tests",
Expand Down
Loading