Skip to content

Commit 9d3406c

Browse files
committed
added more tests
1 parent 5f61ca1 commit 9d3406c

File tree

2 files changed

+179
-15
lines changed

2 files changed

+179
-15
lines changed

src/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace Aws
4242
static const char SSO_SESSION_SECTION[] = "sso-session";
4343
static const char SERVICES_SECTION[] = "services";
4444
static const char ENDPOINT_URL_KEY[] = "endpoint_url";
45+
static const char IGNORE_CONFIGURED_ENDPOINT_URLS_KEY[] = "ignore_configured_endpoint_urls";
4546
static const char DEFAULTS_MODE_KEY[] = "defaults_mode";
4647
static const char EQ = '=';
4748
static const char LEFT_BRACKET = '[';
@@ -182,7 +183,7 @@ namespace Aws
182183
continue;
183184
}
184185

185-
// Ignore top-level endpoint_url in [services name] section
186+
// Ignore global endpoint_url in [services name] section
186187
if (activeServiceId.empty() && StringUtils::CaselessCompare(left.c_str(), ENDPOINT_URL_KEY) == 0) {
187188
AWS_LOGSTREAM_DEBUG(PARSER_TAG, "Ignoring global endpoint_url in [services " << currentSectionName << "]");
188189
continue;

tests/aws-cpp-sdk-core-tests/aws/config/ServiceEndpointsConfigFileLoaderTest.cpp

Lines changed: 177 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,46 +74,209 @@ TEST_F(ServiceEndpointsConfigFileLoaderTest, TestServiceSpecificEndpointsOnly)
7474
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
7575
ASSERT_TRUE(configFile.good());
7676

77-
configFile << "[profile test]\n";
78-
configFile << "region = us-east-1\n";
79-
configFile << "services = testservices\n";
80-
configFile << "\n[services testservices]\n";
77+
configFile << "[services s3-minio]\n";
8178
configFile << "s3 =\n";
82-
configFile << " endpoint_url = http://localhost:9000\n";
79+
configFile << " endpoint_url = https://play.min.io:9000\n";
80+
configFile << "\n[profile dev-minio]\n";
81+
configFile << "services = s3-minio\n";
8382
configFile.flush();
8483

8584
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
8685
ASSERT_TRUE(loader.Load());
8786

8887
// Test that global endpoint is null when not set
89-
auto globalEndpoint = loader.GetGlobalEndpointUrl("test");
88+
auto globalEndpoint = loader.GetGlobalEndpointUrl("dev-minio");
9089
ASSERT_EQ(nullptr, globalEndpoint);
9190

92-
// Test service-specific endpoint still works
93-
auto s3Endpoint = loader.GetServiceEndpointUrl("test", "s3");
91+
// Test service-specific endpoint
92+
auto s3Endpoint = loader.GetServiceEndpointUrl("dev-minio", "s3");
9493
ASSERT_NE(nullptr, s3Endpoint);
95-
ASSERT_STREQ("http://localhost:9000", s3Endpoint->c_str());
94+
ASSERT_STREQ("https://play.min.io:9000", s3Endpoint->c_str());
95+
96+
// Test case insensitive lookup
97+
auto s3EndpointUpper = loader.GetServiceEndpointUrl("dev-minio", "S3");
98+
ASSERT_NE(nullptr, s3EndpointUpper);
99+
ASSERT_STREQ("https://play.min.io:9000", s3EndpointUpper->c_str());
96100
}
97101

98102
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestGlobalEndpointOnly)
99103
{
100104
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
101105
ASSERT_TRUE(configFile.good());
102106

103-
configFile << "[profile test]\n";
104-
configFile << "endpoint_url = https://global.example.com\n";
107+
configFile << "[profile dev-global]\n";
108+
configFile << "endpoint_url = https://play.min.io:9000\n";
105109
configFile.flush();
106110

107111
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
108112
ASSERT_TRUE(loader.Load());
109113

110114
// Test global endpoint
111-
auto globalEndpoint = loader.GetGlobalEndpointUrl("test");
115+
auto globalEndpoint = loader.GetGlobalEndpointUrl("dev-global");
112116
ASSERT_NE(nullptr, globalEndpoint);
113-
ASSERT_STREQ("https://global.example.com", globalEndpoint->c_str());
117+
ASSERT_STREQ("https://play.min.io:9000", globalEndpoint->c_str());
114118

115119
// Test that service-specific endpoint is null when not set
116-
auto s3Endpoint = loader.GetServiceEndpointUrl("test", "s3");
120+
auto s3Endpoint = loader.GetServiceEndpointUrl("dev-global", "s3");
117121
ASSERT_EQ(nullptr, s3Endpoint);
118122
}
119123

124+
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestServiceSpecificAndGlobalEndpoints)
125+
{
126+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
127+
ASSERT_TRUE(configFile.good());
128+
129+
configFile << "[services s3-specific-and-global]\n";
130+
configFile << "s3 =\n";
131+
configFile << " endpoint_url = https://play.min.io:9000\n";
132+
configFile << "\n[profile dev-s3-specific-and-global]\n";
133+
configFile << "endpoint_url = http://localhost:1234\n";
134+
configFile << "services = s3-specific-and-global\n";
135+
configFile.flush();
136+
137+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
138+
ASSERT_TRUE(loader.Load());
139+
140+
// Test service-specific S3 endpoint
141+
auto s3Endpoint = loader.GetServiceEndpointUrl("dev-s3-specific-and-global", "s3");
142+
ASSERT_NE(nullptr, s3Endpoint);
143+
ASSERT_STREQ("https://play.min.io:9000", s3Endpoint->c_str());
144+
145+
// Test global endpoint for other services
146+
auto globalEndpoint = loader.GetGlobalEndpointUrl("dev-s3-specific-and-global");
147+
ASSERT_NE(nullptr, globalEndpoint);
148+
ASSERT_STREQ("http://localhost:1234", globalEndpoint->c_str());
149+
150+
// Test that non-configured service returns null (would fall back to global)
151+
auto dynamoEndpoint = loader.GetServiceEndpointUrl("dev-s3-specific-and-global", "dynamodb");
152+
ASSERT_EQ(nullptr, dynamoEndpoint);
153+
}
154+
155+
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestMultipleServicesInDefinition)
156+
{
157+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
158+
ASSERT_TRUE(configFile.good());
159+
160+
configFile << "[services testing-s3-and-eb]\n";
161+
configFile << "s3 =\n";
162+
configFile << " endpoint_url = http://localhost:4567\n";
163+
configFile << "elastic_beanstalk =\n";
164+
configFile << " endpoint_url = http://localhost:8000\n";
165+
configFile << "\n[profile dev]\n";
166+
configFile << "services = testing-s3-and-eb\n";
167+
configFile.flush();
168+
169+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
170+
ASSERT_TRUE(loader.Load());
171+
172+
// Test S3 endpoint
173+
auto s3Endpoint = loader.GetServiceEndpointUrl("dev", "s3");
174+
ASSERT_NE(nullptr, s3Endpoint);
175+
ASSERT_STREQ("http://localhost:4567", s3Endpoint->c_str());
176+
177+
// Test Elastic Beanstalk endpoint with normalized service ID
178+
auto ebEndpoint = loader.GetServiceEndpointUrl("dev", "Elastic Beanstalk");
179+
ASSERT_NE(nullptr, ebEndpoint);
180+
ASSERT_STREQ("http://localhost:8000", ebEndpoint->c_str());
181+
182+
// Test direct normalized lookup
183+
auto ebEndpointDirect = loader.GetServiceEndpointUrl("dev", "elastic_beanstalk");
184+
ASSERT_NE(nullptr, ebEndpointDirect);
185+
ASSERT_STREQ("http://localhost:8000", ebEndpointDirect->c_str());
186+
}
187+
188+
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestIgnoreGlobalEndpointInServicesSection)
189+
{
190+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
191+
ASSERT_TRUE(configFile.good());
192+
193+
configFile << "[profile testing]\n";
194+
configFile << "services = bad-service-definition\n";
195+
configFile << "\n[services bad-service-definition]\n";
196+
configFile << "endpoint_url = http://do-not-use.aws/\n";
197+
configFile.flush();
198+
199+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
200+
ASSERT_TRUE(loader.Load());
201+
202+
// Test that global endpoint in services section is ignored
203+
auto globalEndpoint = loader.GetGlobalEndpointUrl("testing");
204+
ASSERT_EQ(nullptr, globalEndpoint);
205+
206+
// Test that service-specific endpoints return null (no services configured)
207+
auto s3Endpoint = loader.GetServiceEndpointUrl("testing", "s3");
208+
ASSERT_EQ(nullptr, s3Endpoint);
209+
}
210+
211+
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestSourceProfileEndpointIsolation)
212+
{
213+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
214+
ASSERT_TRUE(configFile.good());
215+
216+
configFile << "[profile A]\n";
217+
configFile << "credential_source = Ec2InstanceMetadata\n";
218+
configFile << "endpoint_url = https://profile-a-endpoint.aws/\n";
219+
configFile << "\n[profile B]\n";
220+
configFile << "source_profile = A\n";
221+
configFile << "role_arn = arn:aws:iam::123456789012:role/roleB\n";
222+
configFile << "services = profileB\n";
223+
configFile << "\n[services profileB]\n";
224+
configFile << "ec2 =\n";
225+
configFile << " endpoint_url = https://profile-b-ec2-endpoint.aws\n";
226+
configFile.flush();
227+
228+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
229+
ASSERT_TRUE(loader.Load());
230+
231+
// Test that profile B gets EC2 endpoint from its own services definition
232+
auto ec2Endpoint = loader.GetServiceEndpointUrl("B", "ec2");
233+
ASSERT_NE(nullptr, ec2Endpoint);
234+
ASSERT_STREQ("https://profile-b-ec2-endpoint.aws", ec2Endpoint->c_str());
235+
236+
// Test that profile B has no global endpoint (doesn't inherit from profile A)
237+
auto globalEndpointB = loader.GetGlobalEndpointUrl("B");
238+
ASSERT_EQ(nullptr, globalEndpointB);
239+
240+
// Test that profile A still has its own global endpoint
241+
auto globalEndpointA = loader.GetGlobalEndpointUrl("A");
242+
ASSERT_NE(nullptr, globalEndpointA);
243+
ASSERT_STREQ("https://profile-a-endpoint.aws/", globalEndpointA->c_str());
244+
245+
// Test that other services in profile B return null (no chaining to profile A)
246+
auto s3Endpoint = loader.GetServiceEndpointUrl("B", "s3");
247+
ASSERT_EQ(nullptr, s3Endpoint);
248+
}
249+
TEST_F(ServiceEndpointsConfigFileLoaderTest, TestIgnoreConfiguredEndpointUrls)
250+
{
251+
TempFile configFile(std::ios_base::out | std::ios_base::trunc);
252+
ASSERT_TRUE(configFile.good());
253+
254+
configFile << "[profile default]\n";
255+
configFile << "ignore_configured_endpoint_urls = true\n";
256+
configFile << "endpoint_url = https://should-be-ignored.com\n";
257+
configFile << "\n[profile test]\n";
258+
configFile << "ignore_configured_endpoint_urls = TRUE\n";
259+
configFile << "\n[profile empty]\n";
260+
configFile << "ignore_configured_endpoint_urls =\n";
261+
configFile.flush();
262+
263+
AWSConfigFileProfileConfigLoader loader(configFile.GetFileName(), true);
264+
ASSERT_TRUE(loader.Load());
265+
auto profiles = loader.GetProfiles();
266+
267+
// Test flag is parsed and stored
268+
ASSERT_STREQ("true", profiles["default"].GetValue("ignore_configured_endpoint_urls").c_str());
269+
ASSERT_STREQ("TRUE", profiles["test"].GetValue("ignore_configured_endpoint_urls").c_str());
270+
ASSERT_STREQ("", profiles["empty"].GetValue("ignore_configured_endpoint_urls").c_str());
271+
272+
// Test absent key returns empty string
273+
TempFile configFile2(std::ios_base::out | std::ios_base::trunc);
274+
configFile2 << "[profile absent]\n";
275+
configFile2 << "region = us-east-1\n";
276+
configFile2.flush();
277+
278+
AWSConfigFileProfileConfigLoader loader2(configFile2.GetFileName(), true);
279+
ASSERT_TRUE(loader2.Load());
280+
auto profiles2 = loader2.GetProfiles();
281+
ASSERT_STREQ("", profiles2["absent"].GetValue("ignore_configured_endpoint_urls").c_str());
282+
}

0 commit comments

Comments
 (0)