@@ -207,3 +207,76 @@ TEST_F(ServiceEndpointsConfigFileLoaderTest, TestIgnoreGlobalEndpointInServicesS
207207 auto s3Endpoint = loader.GetServiceEndpointUrl (" testing" , " s3" );
208208 ASSERT_EQ (nullptr , s3Endpoint);
209209}
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