Skip to content

Commit 6caa146

Browse files
committed
Add URI S3 Client unit tests
1 parent a5b43db commit 6caa146

File tree

7 files changed

+171
-2
lines changed

7 files changed

+171
-2
lines changed

cmake/sdksCommon.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ list(APPEND SDK_TEST_PROJECT_LIST "monitoring:tests/aws-cpp-sdk-monitoring-integ
167167
list(APPEND SDK_TEST_PROJECT_LIST "rds:tests/aws-cpp-sdk-rds-integration-tests")
168168
list(APPEND SDK_TEST_PROJECT_LIST "redshift:tests/aws-cpp-sdk-redshift-integration-tests")
169169
list(APPEND SDK_TEST_PROJECT_LIST "s3:tests/aws-cpp-sdk-s3-integration-tests")
170+
list(APPEND SDK_TEST_PROJECT_LIST "s3:tests/aws-cpp-sdk-s3-unit-tests")
170171
list(APPEND SDK_TEST_PROJECT_LIST "s3-crt:tests/aws-cpp-sdk-s3-crt-integration-tests")
171172
list(APPEND SDK_TEST_PROJECT_LIST "s3-encryption:tests/aws-cpp-sdk-s3-encryption-tests,tests/aws-cpp-sdk-s3-encryption-integration-tests")
172173
list(APPEND SDK_TEST_PROJECT_LIST "s3control:tests/aws-cpp-sdk-s3control-integration-tests")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
add_project(aws-cpp-sdk-s3-unit-tests
2+
"Unit Tests for the S3 SDK Client"
3+
aws-cpp-sdk-s3
4+
testing-resources
5+
aws_test_main
6+
aws-cpp-sdk-core)
7+
8+
add_definitions(-DRESOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/resources")
9+
10+
if(MSVC AND BUILD_SHARED_LIBS)
11+
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1)
12+
endif()
13+
14+
enable_testing()
15+
16+
if(PLATFORM_ANDROID AND BUILD_SHARED_LIBS)
17+
add_library(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/S3UnitTests.cpp)
18+
else()
19+
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/S3UnitTests.cpp)
20+
endif()
21+
22+
set_compiler_flags(${PROJECT_NAME})
23+
set_compiler_warnings(${PROJECT_NAME})
24+
25+
target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})
26+
27+
if(MSVC AND BUILD_SHARED_LIBS)
28+
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/DELAYLOAD:aws-cpp-sdk-s3.dll /DELAYLOAD:aws-cpp-sdk-core.dll")
29+
endif()
30+
31+
include(GoogleTest)
32+
gtest_discover_tests(${PROJECT_NAME})
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include <gtest/gtest.h>
2+
#include <aws/core/Aws.h>
3+
#include <aws/core/auth/AWSCredentials.h>
4+
#include <aws/s3/S3Client.h>
5+
#include <aws/s3/model/PutObjectRequest.h>
6+
#include <aws/testing/mocks/http/MockHttpClient.h>
7+
#include <aws/testing/AwsTestHelpers.h>
8+
#include <aws/testing/MemoryTesting.h>
9+
10+
using namespace Aws;
11+
using namespace Aws::Auth;
12+
using namespace Aws::Http;
13+
using namespace Aws::S3;
14+
using namespace Aws::S3::Model;
15+
16+
const char* ALLOCATION_TAG = "S3UnitTest";
17+
18+
class S3UnitTest : public testing::Test {
19+
protected:
20+
static void SetUpTestSuite() {
21+
#ifdef USE_AWS_MEMORY_MANAGEMENT
22+
_testMemorySystem = Aws::MakeShared<ExactTestMemorySystem>(ALLOCATION_TAG, 1024, 128);
23+
_options.memoryManagementOptions.memoryManager = _testMemorySystem.get();
24+
#endif
25+
_mockClientFactory = Aws::MakeShared<MockHttpClientFactory>(ALLOCATION_TAG);
26+
_mockHttpClient = Aws::MakeShared<MockHttpClient>(ALLOCATION_TAG);
27+
_mockClientFactory->SetClient(_mockHttpClient);
28+
HttpOptions httpOptions;
29+
httpOptions.httpClientFactory_create_fn = []() -> std::shared_ptr<HttpClientFactory> {
30+
return _mockClientFactory;
31+
};
32+
_options.httpOptions = httpOptions;
33+
InitAPI(_options);
34+
AWSCredentials credentials{"mock", "credentials"};
35+
const auto epProvider = Aws::MakeShared<S3EndpointProvider>(ALLOCATION_TAG);
36+
S3ClientConfiguration s3Config;
37+
s3Config.region = "us-east-1";
38+
_s3Client = Aws::MakeShared<S3Client>("ALLOCATION_TAG", credentials, epProvider, s3Config);
39+
}
40+
41+
static void TearDownTestSuite() {
42+
_mockClientFactory.reset();
43+
_mockHttpClient.reset();
44+
_s3Client.reset();
45+
ShutdownAPI(_options);
46+
#ifdef USE_AWS_MEMORY_MANAGEMENT
47+
EXPECT_EQ(_testMemorySystem->GetCurrentOutstandingAllocations(), 0ULL);
48+
EXPECT_EQ(_testMemorySystem->GetCurrentBytesAllocated(), 0ULL);
49+
EXPECT_TRUE(_testMemorySystem->IsClean());
50+
if (_testMemorySystem->GetCurrentOutstandingAllocations() != 0ULL)
51+
FAIL();
52+
if (_testMemorySystem->GetCurrentBytesAllocated() != 0ULL)
53+
FAIL();
54+
if (!_testMemorySystem->IsClean())
55+
FAIL();
56+
_testMemorySystem.reset();
57+
#endif
58+
}
59+
60+
static SDKOptions _options;
61+
static std::shared_ptr<MockHttpClient> _mockHttpClient;
62+
static std::shared_ptr<MockHttpClientFactory> _mockClientFactory;
63+
static std::shared_ptr<S3Client> _s3Client;
64+
#ifdef USE_AWS_MEMORY_MANAGEMENT
65+
static std::shared_ptr<ExactTestMemorySystem> _testMemorySystem;
66+
#endif
67+
};
68+
69+
SDKOptions S3UnitTest::_options;
70+
std::shared_ptr<MockHttpClient> S3UnitTest::_mockHttpClient = nullptr;
71+
std::shared_ptr<MockHttpClientFactory> S3UnitTest::_mockClientFactory = nullptr;
72+
std::shared_ptr<S3Client> S3UnitTest::_s3Client = nullptr;
73+
#ifdef USE_AWS_MEMORY_MANAGEMENT
74+
std::shared_ptr<ExactTestMemorySystem> S3UnitTest::_testMemorySystem = nullptr;
75+
#endif
76+
77+
78+
TEST_F(S3UnitTest, S3UriLeadingDots) {
79+
auto putObjectRequest = PutObjectRequest()
80+
.WithBucket("bluerev")
81+
.WithKey("../BoredInBristol");
82+
83+
std::shared_ptr<IOStream> body = Aws::MakeShared<StringStream>(ALLOCATION_TAG,
84+
"Bored in Bristol, always waiting",
85+
std::ios_base::in | std::ios_base::binary);
86+
87+
putObjectRequest.SetBody(body);
88+
89+
//We have to mock requset because it is used to create the return body, it actually isnt used.
90+
auto mockRequest = Aws::MakeShared<Standard::StandardHttpRequest>(ALLOCATION_TAG, "mockuri", HttpMethod::HTTP_GET);
91+
mockRequest->SetResponseStreamFactory([]() -> IOStream* {
92+
return Aws::New<StringStream>(ALLOCATION_TAG, "response-string", std::ios_base::in | std::ios_base::binary);
93+
});
94+
auto mockResponse = Aws::MakeShared<Standard::StandardHttpResponse>(ALLOCATION_TAG, mockRequest);
95+
mockResponse->SetResponseCode(HttpResponseCode::OK);
96+
_mockHttpClient->AddResponseToReturn(mockResponse);
97+
const auto response = _s3Client->PutObject(putObjectRequest);
98+
AWS_EXPECT_SUCCESS(response);
99+
const auto seenRequest = _mockHttpClient->GetMostRecentHttpRequest();
100+
EXPECT_EQ("https://bluerev.s3.us-east-1.amazonaws.com/../BoredInBristol", seenRequest.GetUri().GetURIString());
101+
}
102+
103+
TEST_F(S3UnitTest, S3UriMiddleDots) {
104+
auto putObjectRequest = PutObjectRequest()
105+
.WithBucket("bluerev")
106+
.WithKey("belinda/../says");
107+
108+
std::shared_ptr<IOStream> body = Aws::MakeShared<StringStream>(ALLOCATION_TAG,
109+
"Blue Rev behind the rink I didn't really need it",
110+
std::ios_base::in | std::ios_base::binary);
111+
112+
putObjectRequest.SetBody(body);
113+
114+
//We have to mock requset because it is used to create the return body, it actually isnt used.
115+
auto mockRequest = Aws::MakeShared<Standard::StandardHttpRequest>(ALLOCATION_TAG, "mockuri", HttpMethod::HTTP_GET);
116+
mockRequest->SetResponseStreamFactory([]() -> IOStream* {
117+
return Aws::New<StringStream>(ALLOCATION_TAG, "response-string", std::ios_base::in | std::ios_base::binary);
118+
});
119+
auto mockResponse = Aws::MakeShared<Standard::StandardHttpResponse>(ALLOCATION_TAG, mockRequest);
120+
mockResponse->SetResponseCode(HttpResponseCode::OK);
121+
_mockHttpClient->AddResponseToReturn(mockResponse);
122+
const auto response = _s3Client->PutObject(putObjectRequest);
123+
AWS_EXPECT_SUCCESS(response);
124+
const auto seenRequest = _mockHttpClient->GetMostRecentHttpRequest();
125+
EXPECT_EQ("https://bluerev.s3.us-east-1.amazonaws.com/belinda/../says", seenRequest.GetUri().GetURIString());
126+
}

tests/testing-resources/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,12 @@ endif()
109109

110110
add_library(${PROJECT_NAME} ${TestingResources_SRC})
111111
add_library(AWS::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
112+
add_library(aws_test_main source/external/gtest/src/gtest_main.cc)
112113

113114
set_compiler_flags(${PROJECT_NAME})
114115
set_compiler_warnings(${PROJECT_NAME})
116+
set_compiler_flags(aws_test_main)
117+
set_compiler_warnings(aws_test_main)
115118

116119
if(PLATFORM_CUSTOM)
117120
add_custom_testing_target_compile_definitions()
@@ -123,6 +126,12 @@ target_include_directories(${PROJECT_NAME} PUBLIC
123126
$<INSTALL_INTERFACE:include>)
124127
target_link_libraries(${PROJECT_NAME} ${PLATFORM_DEP_LIBS} ${PROJECT_LIBS})
125128

129+
target_include_directories(aws_test_main PUBLIC
130+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/aws/external>
131+
$<INSTALL_INTERFACE:include>)
132+
133+
target_link_libraries(aws_test_main ${PROJECT_NAME})
134+
126135
if(COMMAND add_custom_testing_link_libraries)
127136
add_custom_testing_link_libraries()
128137
endif()

tools/scripts/build-tests/run-al2-integ-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ aws configure set aws_secret_access_key $(echo "$sts" | jq -r '.[1]') --profile
2929
aws configure set aws_session_token $(echo "$sts" | jq -r '.[2]') --profile "$profile"
3030
aws configure list --profile "$profile"
3131
export AWS_PROFILE=$profile
32-
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${PREFIX_DIR}/al2-install/lib64/"
32+
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${PREFIX_DIR}/al2-install/lib64/:${PREFIX_DIR}/al2-build/tests/testing-resources/"
3333
cd "${PREFIX_DIR}/al2-build"
3434
if [ -f "${PREFIX_DIR}/aws-sdk-cpp/tools/scripts/suppressions.txt" ]; then export LSAN_OPTIONS=suppressions="${PREFIX_DIR}/aws-sdk-cpp/tools/scripts/suppressions.txt"; fi
3535
python3 ../aws-sdk-cpp/tools/scripts/run_integration_tests.py --testDir ./tests

tools/scripts/build-tests/run-mac-integ-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ aws configure set aws_secret_access_key $(echo "$sts" | jq -r '.[1]') --profile
2929
aws configure set aws_session_token $(echo "$sts" | jq -r '.[2]') --profile "$profile"
3030
aws configure list --profile "$profile"
3131
export AWS_PROFILE=$profile
32-
export DYLD_LIBRARY_PATH=$CATAPULT_WORKSPACE_DIR/mac-install/lib
32+
export DYLD_LIBRARY_PATH="${CATAPULT_WORKSPACE_DIR}/mac-install/lib:${CATAPULT_WORKSPACE_DIR}/mac-build/tests/testing-resources/"
3333
cd "${PREFIX_DIR}/mac-build"
3434
if [ -f "${PREFIX_DIR}/aws-sdk-cpp/tools/scripts/suppressions.txt" ]; then export LSAN_OPTIONS=suppressions="${PREFIX_DIR}/aws-sdk-cpp/tools/scripts/suppressions.txt"; fi
3535
python3 ../aws-sdk-cpp/tools/scripts/run_integration_tests.py --testDir ./tests

tools/scripts/run_integration_tests.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def main():
4040
"aws-cpp-sdk-dynamodb-integration-tests",
4141
"aws-cpp-sdk-sqs-integration-tests",
4242
"aws-cpp-sdk-s3-integration-tests",
43+
"aws-cpp-sdk-s3-unit-tests",
4344
#"aws-cpp-sdk-s3-crt-integration-tests",
4445
#"aws-cpp-sdk-s3control-integration-tests",
4546
# "aws-cpp-sdk-lambda-integration-tests",

0 commit comments

Comments
 (0)