Skip to content

Commit 2ace84b

Browse files
committed
integration test with s3
1 parent c34c7b7 commit 2ace84b

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
/**
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
#include <aws/testing/AwsTestHelpers.h>
7+
#include <aws/testing/AwsCppSdkGTestSuite.h>
8+
#include <aws/core/Aws.h>
9+
#include <aws/s3/S3Client.h>
10+
#include <aws/s3/model/HeadBucketRequest.h>
11+
#include <aws/core/auth/AWSCredentials.h>
12+
#include <aws/testing/mocks/http/MockHttpClient.h>
13+
#include <aws/core/client/RetryStrategy.h>
14+
#include <aws/core/utils/FileSystemUtils.h>
15+
#include <aws/core/config/ConfigAndCredentialsCacheManager.h>
16+
#include <aws/core/platform/Environment.h>
17+
#include <aws/testing/platform/PlatformTesting.h>
18+
19+
using namespace Aws;
20+
using namespace Aws::S3;
21+
using namespace Aws::S3::Model;
22+
using namespace Aws::Auth;
23+
using namespace Aws::Client;
24+
using namespace Aws::Http;
25+
using namespace Aws::Utils;
26+
using namespace Aws::Config;
27+
using namespace Aws::Environment;
28+
29+
const char* ALLOCATION_TAG = "EndpointResolverIntegrationTest";
30+
31+
class S3TestClient : public S3Client
32+
{
33+
public:
34+
template <typename ...Args>
35+
S3TestClient(Args&& ...args): S3Client(std::forward<Args>(args)...){}
36+
37+
XmlOutcome MakeRequest(const Aws::Http::URI& uri,
38+
const Aws::AmazonWebServiceRequest& request,
39+
Aws::Http::HttpMethod method = Aws::Http::HttpMethod::HTTP_POST,
40+
const char* signerName = Aws::Auth::SIGV4_SIGNER,
41+
const char* signerRegionOverride = nullptr,
42+
const char* signerServiceNameOverride = nullptr) const
43+
{
44+
return S3Client::MakeRequest(uri, request, method, signerName, signerRegionOverride, signerServiceNameOverride);
45+
}
46+
47+
XmlOutcome MakeRequest(const Aws::Http::URI& uri,
48+
Http::HttpMethod method = Http::HttpMethod::HTTP_POST,
49+
const char* signerName = Aws::Auth::SIGV4_SIGNER,
50+
const char* requestName = "",
51+
const char* signerRegionOverride = nullptr,
52+
const char* signerServiceNameOverride = nullptr) const
53+
{
54+
return S3Client::MakeRequest(uri, method, signerName, requestName, signerRegionOverride, signerServiceNameOverride);
55+
}
56+
57+
private:
58+
S3TestClient() = default;
59+
};
60+
61+
class NoRetry: public RetryStrategy
62+
{
63+
public:
64+
bool ShouldRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const override
65+
{
66+
AWS_UNREFERENCED_PARAM(error);
67+
AWS_UNREFERENCED_PARAM(attemptedRetries);
68+
return false;
69+
}
70+
71+
long CalculateDelayBeforeNextRetry(const AWSError<CoreErrors>& error, long attemptedRetries) const override
72+
{
73+
AWS_UNREFERENCED_PARAM(error);
74+
AWS_UNREFERENCED_PARAM(attemptedRetries);
75+
return 0;
76+
}
77+
78+
const char* GetStrategyName() const override {
79+
return "standard";
80+
}
81+
};
82+
83+
class EndpointResolverIntegrationTest : public Aws::Testing::AwsCppSdkGTestSuite
84+
{
85+
protected:
86+
void SetUp() override
87+
{
88+
// Clear environment variables
89+
Aws::Environment::EnvironmentRAII setEnv{{
90+
{"AWS_ENDPOINT_URL", ""},
91+
{"AWS_ENDPOINT_URL_S3", ""},
92+
{"AWS_IGNORE_CONFIGURED_ENDPOINT_URLS", ""},
93+
{"AWS_CONFIG_FILE", ""}
94+
}};
95+
96+
// Set up mock HTTP client
97+
_mockClientFactory = MakeShared<MockHttpClientFactory>(ALLOCATION_TAG);
98+
_mockHttpClient = MakeShared<MockHttpClient>(ALLOCATION_TAG);
99+
_mockClientFactory->SetClient(_mockHttpClient);
100+
SetHttpClientFactory(_mockClientFactory);
101+
}
102+
103+
void TearDown() override
104+
{
105+
// Clean up mock clients
106+
_mockClientFactory.reset();
107+
_mockHttpClient.reset();
108+
}
109+
110+
void SetupMockResponse()
111+
{
112+
auto mockRequest = MakeShared<Standard::StandardHttpRequest>(ALLOCATION_TAG, "mockuri", HttpMethod::HTTP_HEAD);
113+
mockRequest->SetResponseStreamFactory([]() -> IOStream* {
114+
return Aws::New<StringStream>(ALLOCATION_TAG, "response-string", std::ios_base::in | std::ios_base::binary);
115+
});
116+
auto mockResponse = MakeShared<Standard::StandardHttpResponse>(ALLOCATION_TAG, mockRequest);
117+
mockResponse->SetResponseCode(HttpResponseCode::OK);
118+
_mockHttpClient->AddResponseToReturn(mockResponse);
119+
}
120+
121+
const Aws::Http::HttpRequest& ExecuteHeadBucketRequest(const S3ClientConfiguration& config)
122+
{
123+
SetupMockResponse();
124+
125+
AWSCredentials credentials{"mock", "credentials"};
126+
const auto epProvider = MakeShared<S3EndpointProvider>(ALLOCATION_TAG);
127+
auto testClient = MakeShared<S3TestClient>(ALLOCATION_TAG, credentials, epProvider, config);
128+
129+
HeadBucketRequest request;
130+
request.SetBucket("test-bucket");
131+
132+
auto response = testClient->HeadBucket(request);
133+
return _mockHttpClient->GetMostRecentHttpRequest();
134+
}
135+
136+
std::shared_ptr<MockHttpClient> _mockHttpClient;
137+
std::shared_ptr<MockHttpClientFactory> _mockClientFactory;
138+
};
139+
140+
TEST_F(EndpointResolverIntegrationTest, DefaultResolution)
141+
{
142+
S3ClientConfiguration s3Config;
143+
s3Config.region = "us-east-1";
144+
s3Config.profileName = "test-default";
145+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
146+
147+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
148+
149+
EXPECT_EQ("https://test-bucket.s3.us-east-1.amazonaws.com", seenRequest.GetUri().GetURIString());
150+
}
151+
152+
TEST_F(EndpointResolverIntegrationTest, CodeProvidedEndpoint)
153+
{
154+
S3ClientConfiguration s3Config;
155+
s3Config.region = "us-east-1";
156+
s3Config.endpointOverride = "https://code-provided.example.com";
157+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
158+
159+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
160+
161+
EXPECT_EQ("https://test-bucket.code-provided.example.com", seenRequest.GetUri().GetURIString());
162+
}
163+
164+
TEST_F(EndpointResolverIntegrationTest, ServiceSpecificEnvironmentVariable)
165+
{
166+
Aws::Environment::EnvironmentRAII setEnv{{
167+
{"AWS_ENDPOINT_URL_S3", "https://custom-s3.example.com"}
168+
}};
169+
170+
S3ClientConfiguration s3Config;
171+
s3Config.region = "us-east-1";
172+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
173+
174+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
175+
176+
EXPECT_EQ("https://test-bucket.custom-s3.example.com", seenRequest.GetUri().GetURIString());
177+
}
178+
179+
TEST_F(EndpointResolverIntegrationTest, GlobalEnvironmentVariable)
180+
{
181+
Aws::Environment::EnvironmentRAII setEnv{{
182+
{"AWS_ENDPOINT_URL", "https://global-env.example.com"}
183+
}};
184+
185+
S3ClientConfiguration s3Config;
186+
s3Config.region = "us-east-1";
187+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
188+
189+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
190+
191+
EXPECT_EQ("https://test-bucket.global-env.example.com", seenRequest.GetUri().GetURIString());
192+
}
193+
194+
TEST_F(EndpointResolverIntegrationTest, ServiceSpecificProfile)
195+
{
196+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
197+
ASSERT_TRUE(configFile.good());
198+
199+
configFile << "[profile test-profile-service]\n";
200+
configFile << "services = test-services\n";
201+
configFile << "\n[services test-services]\n";
202+
configFile << "s3 =\n";
203+
configFile << " endpoint_url = https://s3-profile.example.com\n";
204+
configFile.flush();
205+
206+
Aws::Environment::EnvironmentRAII setEnv{{
207+
{"AWS_CONFIG_FILE", configFile.GetFileName()}
208+
}};
209+
ReloadCachedConfigFile();
210+
211+
S3ClientConfiguration s3Config;
212+
s3Config.region = "us-east-1";
213+
s3Config.profileName = "test-profile-service";
214+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
215+
216+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
217+
218+
EXPECT_EQ("https://test-bucket.s3-profile.example.com", seenRequest.GetUri().GetURIString());
219+
ReloadCachedConfigFile();
220+
}
221+
222+
TEST_F(EndpointResolverIntegrationTest, GlobalProfile)
223+
{
224+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
225+
ASSERT_TRUE(configFile.good());
226+
227+
configFile << "[profile test-profile-global]\n";
228+
configFile << "endpoint_url = https://global-profile.example.com\n";
229+
configFile.flush();
230+
231+
Aws::Environment::EnvironmentRAII envGuard{{
232+
{"AWS_CONFIG_FILE", configFile.GetFileName()}
233+
}};
234+
ReloadCachedConfigFile();
235+
236+
S3ClientConfiguration s3Config;
237+
s3Config.region = "us-east-1";
238+
s3Config.profileName = "test-profile-global";
239+
s3Config.retryStrategy = MakeShared<NoRetry>(ALLOCATION_TAG);
240+
241+
const auto& seenRequest = ExecuteHeadBucketRequest(s3Config);
242+
243+
EXPECT_EQ("https://test-bucket.global-profile.example.com", seenRequest.GetUri().GetURIString());
244+
245+
ReloadCachedConfigFile();
246+
}

0 commit comments

Comments
 (0)