github.com/aavshr/aws-sdk-go@v1.41.3/aws/session/session_test.go (about)

     1  //go:build go1.7
     2  // +build go1.7
     3  
     4  package session
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"net/http"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/aavshr/aws-sdk-go/aws"
    16  	"github.com/aavshr/aws-sdk-go/aws/credentials"
    17  	"github.com/aavshr/aws-sdk-go/aws/defaults"
    18  	"github.com/aavshr/aws-sdk-go/aws/endpoints"
    19  	"github.com/aavshr/aws-sdk-go/aws/request"
    20  	"github.com/aavshr/aws-sdk-go/service/s3"
    21  )
    22  
    23  func TestNewDefaultSession(t *testing.T) {
    24  	restoreEnvFn := initSessionTestEnv()
    25  	defer restoreEnvFn()
    26  
    27  	s := New(&aws.Config{Region: aws.String("region")})
    28  
    29  	if e, a := "region", *s.Config.Region; e != a {
    30  		t.Errorf("expect %v, got %v", e, a)
    31  	}
    32  	if e, a := http.DefaultClient, s.Config.HTTPClient; e != a {
    33  		t.Errorf("expect %v, got %v", e, a)
    34  	}
    35  	if s.Config.Logger == nil {
    36  		t.Errorf("expect not nil")
    37  	}
    38  	if e, a := aws.LogOff, *s.Config.LogLevel; e != a {
    39  		t.Errorf("expect %v, got %v", e, a)
    40  	}
    41  }
    42  
    43  func TestNew_WithCustomCreds(t *testing.T) {
    44  	restoreEnvFn := initSessionTestEnv()
    45  	defer restoreEnvFn()
    46  
    47  	customCreds := credentials.NewStaticCredentials("AKID", "SECRET", "TOKEN")
    48  	s := New(&aws.Config{Credentials: customCreds})
    49  
    50  	if e, a := customCreds, s.Config.Credentials; e != a {
    51  		t.Errorf("expect %v, got %v", e, a)
    52  	}
    53  }
    54  
    55  type mockLogger struct {
    56  	*bytes.Buffer
    57  }
    58  
    59  func (w mockLogger) Log(args ...interface{}) {
    60  	fmt.Fprintln(w, args...)
    61  }
    62  
    63  func TestNew_WithSessionLoadError(t *testing.T) {
    64  	restoreEnvFn := initSessionTestEnv()
    65  	defer restoreEnvFn()
    66  
    67  	os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
    68  	os.Setenv("AWS_CONFIG_FILE", testConfigFilename)
    69  	os.Setenv("AWS_PROFILE", "assume_role_invalid_source_profile")
    70  
    71  	logger := bytes.Buffer{}
    72  	s := New(&aws.Config{
    73  		Region: aws.String("us-west-2"),
    74  		Logger: &mockLogger{&logger},
    75  	})
    76  
    77  	if s == nil {
    78  		t.Errorf("expect not nil")
    79  	}
    80  
    81  	svc := s3.New(s)
    82  	_, err := svc.ListBuckets(&s3.ListBucketsInput{})
    83  
    84  	if err == nil {
    85  		t.Errorf("expect not nil")
    86  	}
    87  	if e, a := "ERROR: failed to create session with AWS_SDK_LOAD_CONFIG enabled", logger.String(); !strings.Contains(a, e) {
    88  		t.Errorf("expect %v, to be in %v", e, a)
    89  	}
    90  
    91  	expectErr := SharedConfigAssumeRoleError{
    92  		RoleARN:       "assume_role_invalid_source_profile_role_arn",
    93  		SourceProfile: "profile_not_exists",
    94  	}
    95  	if e, a := expectErr.Error(), err.Error(); !strings.Contains(a, e) {
    96  		t.Errorf("expect %v, to be in %v", e, a)
    97  	}
    98  }
    99  
   100  func TestSessionCopy(t *testing.T) {
   101  	restoreEnvFn := initSessionTestEnv()
   102  	defer restoreEnvFn()
   103  
   104  	os.Setenv("AWS_REGION", "orig_region")
   105  
   106  	s := Session{
   107  		Config:   defaults.Config(),
   108  		Handlers: defaults.Handlers(),
   109  	}
   110  
   111  	newSess := s.Copy(&aws.Config{Region: aws.String("new_region")})
   112  
   113  	if e, a := "orig_region", *s.Config.Region; e != a {
   114  		t.Errorf("expect %v, got %v", e, a)
   115  	}
   116  	if e, a := "new_region", *newSess.Config.Region; e != a {
   117  		t.Errorf("expect %v, got %v", e, a)
   118  	}
   119  }
   120  
   121  func TestSessionClientConfig(t *testing.T) {
   122  	s, err := NewSession(&aws.Config{
   123  		Credentials: credentials.AnonymousCredentials,
   124  		Region:      aws.String("orig_region"),
   125  		EndpointResolver: endpoints.ResolverFunc(
   126  			func(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
   127  				if e, a := "mock-service", service; e != a {
   128  					t.Errorf("expect %q service, got %q", e, a)
   129  				}
   130  				if e, a := "other-region", region; e != a {
   131  					t.Errorf("expect %q region, got %q", e, a)
   132  				}
   133  				return endpoints.ResolvedEndpoint{
   134  					URL:           "https://" + service + "." + region + ".amazonaws.com",
   135  					SigningRegion: region,
   136  				}, nil
   137  			},
   138  		),
   139  	})
   140  	if err != nil {
   141  		t.Errorf("expect nil, %v", err)
   142  	}
   143  
   144  	cfg := s.ClientConfig("mock-service", &aws.Config{Region: aws.String("other-region")})
   145  
   146  	if e, a := "https://mock-service.other-region.amazonaws.com", cfg.Endpoint; e != a {
   147  		t.Errorf("expect %v, got %v", e, a)
   148  	}
   149  	if e, a := "other-region", cfg.SigningRegion; e != a {
   150  		t.Errorf("expect %v, got %v", e, a)
   151  	}
   152  	if e, a := "other-region", *cfg.Config.Region; e != a {
   153  		t.Errorf("expect %v, got %v", e, a)
   154  	}
   155  }
   156  
   157  func TestNewSession_ResolveEndpointError(t *testing.T) {
   158  	logger := mockLogger{Buffer: bytes.NewBuffer(nil)}
   159  	sess, err := NewSession(defaults.Config(), &aws.Config{
   160  		Region: aws.String(""),
   161  		Logger: logger,
   162  		EndpointResolver: endpoints.ResolverFunc(
   163  			func(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
   164  				return endpoints.ResolvedEndpoint{}, fmt.Errorf("mock error")
   165  			},
   166  		),
   167  	})
   168  	if err != nil {
   169  		t.Fatalf("expect no error got %v", err)
   170  	}
   171  
   172  	cfg := sess.ClientConfig("mock service")
   173  
   174  	var r request.Request
   175  	cfg.Handlers.Validate.Run(&r)
   176  
   177  	if r.Error == nil {
   178  		t.Fatalf("expect validation error, got none")
   179  	}
   180  
   181  	if e, a := aws.ErrMissingRegion.Error(), r.Error.Error(); !strings.Contains(a, e) {
   182  		t.Errorf("expect %v validation error, got %v", e, a)
   183  	}
   184  
   185  	if v := logger.Buffer.String(); len(v) != 0 {
   186  		t.Errorf("expect nothing logged, got %s", v)
   187  	}
   188  }
   189  
   190  func TestNewSession_NoCredentials(t *testing.T) {
   191  	restoreEnvFn := initSessionTestEnv()
   192  	defer restoreEnvFn()
   193  
   194  	s, err := NewSession()
   195  	if err != nil {
   196  		t.Errorf("expect nil, %v", err)
   197  	}
   198  
   199  	if s.Config.Credentials == nil {
   200  		t.Errorf("expect not nil")
   201  	}
   202  	if e, a := credentials.AnonymousCredentials, s.Config.Credentials; e == a {
   203  		t.Errorf("expect different credentials, %v", e)
   204  	}
   205  }
   206  
   207  func TestNewSessionWithOptions_OverrideProfile(t *testing.T) {
   208  	restoreEnvFn := initSessionTestEnv()
   209  	defer restoreEnvFn()
   210  
   211  	os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
   212  	os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
   213  	os.Setenv("AWS_PROFILE", "other_profile")
   214  
   215  	s, err := NewSessionWithOptions(Options{
   216  		Profile: "full_profile",
   217  	})
   218  	if err != nil {
   219  		t.Errorf("expect nil, %v", err)
   220  	}
   221  
   222  	if e, a := "full_profile_region", *s.Config.Region; e != a {
   223  		t.Errorf("expect %v, got %v", e, a)
   224  	}
   225  
   226  	creds, err := s.Config.Credentials.Get()
   227  	if err != nil {
   228  		t.Errorf("expect nil, %v", err)
   229  	}
   230  	if e, a := "full_profile_akid", creds.AccessKeyID; e != a {
   231  		t.Errorf("expect %v, got %v", e, a)
   232  	}
   233  	if e, a := "full_profile_secret", creds.SecretAccessKey; e != a {
   234  		t.Errorf("expect %v, got %v", e, a)
   235  	}
   236  	if v := creds.SessionToken; len(v) != 0 {
   237  		t.Errorf("expect empty, got %v", v)
   238  	}
   239  	if e, a := "SharedConfigCredentials", creds.ProviderName; !strings.Contains(a, e) {
   240  		t.Errorf("expect %v, to be in %v", e, a)
   241  	}
   242  }
   243  
   244  func TestNewSessionWithOptions_OverrideSharedConfigEnable(t *testing.T) {
   245  	restoreEnvFn := initSessionTestEnv()
   246  	defer restoreEnvFn()
   247  
   248  	os.Setenv("AWS_SDK_LOAD_CONFIG", "0")
   249  	os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
   250  	os.Setenv("AWS_PROFILE", "full_profile")
   251  
   252  	s, err := NewSessionWithOptions(Options{
   253  		SharedConfigState: SharedConfigEnable,
   254  	})
   255  	if err != nil {
   256  		t.Errorf("expect nil, %v", err)
   257  	}
   258  
   259  	if e, a := "full_profile_region", *s.Config.Region; e != a {
   260  		t.Errorf("expect %v, got %v", e, a)
   261  	}
   262  
   263  	creds, err := s.Config.Credentials.Get()
   264  	if err != nil {
   265  		t.Errorf("expect nil, %v", err)
   266  	}
   267  	if e, a := "full_profile_akid", creds.AccessKeyID; e != a {
   268  		t.Errorf("expect %v, got %v", e, a)
   269  	}
   270  	if e, a := "full_profile_secret", creds.SecretAccessKey; e != a {
   271  		t.Errorf("expect %v, got %v", e, a)
   272  	}
   273  	if v := creds.SessionToken; len(v) != 0 {
   274  		t.Errorf("expect empty, got %v", v)
   275  	}
   276  	if e, a := "SharedConfigCredentials", creds.ProviderName; !strings.Contains(a, e) {
   277  		t.Errorf("expect %v, to be in %v", e, a)
   278  	}
   279  }
   280  
   281  func TestNewSessionWithOptions_OverrideSharedConfigDisable(t *testing.T) {
   282  	restoreEnvFn := initSessionTestEnv()
   283  	defer restoreEnvFn()
   284  
   285  	os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
   286  	os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
   287  	os.Setenv("AWS_PROFILE", "full_profile")
   288  
   289  	s, err := NewSessionWithOptions(Options{
   290  		SharedConfigState: SharedConfigDisable,
   291  	})
   292  	if err != nil {
   293  		t.Errorf("expect nil, %v", err)
   294  	}
   295  
   296  	if v := *s.Config.Region; len(v) != 0 {
   297  		t.Errorf("expect empty, got %v", v)
   298  	}
   299  
   300  	creds, err := s.Config.Credentials.Get()
   301  	if err != nil {
   302  		t.Errorf("expect nil, %v", err)
   303  	}
   304  	if e, a := "full_profile_akid", creds.AccessKeyID; e != a {
   305  		t.Errorf("expect %v, got %v", e, a)
   306  	}
   307  	if e, a := "full_profile_secret", creds.SecretAccessKey; e != a {
   308  		t.Errorf("expect %v, got %v", e, a)
   309  	}
   310  	if v := creds.SessionToken; len(v) != 0 {
   311  		t.Errorf("expect empty, got %v", v)
   312  	}
   313  	if e, a := "SharedConfigCredentials", creds.ProviderName; !strings.Contains(a, e) {
   314  		t.Errorf("expect %v, to be in %v", e, a)
   315  	}
   316  }
   317  
   318  func TestNewSessionWithOptions_OverrideSharedConfigFiles(t *testing.T) {
   319  	restoreEnvFn := initSessionTestEnv()
   320  	defer restoreEnvFn()
   321  
   322  	os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
   323  	os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
   324  	os.Setenv("AWS_PROFILE", "config_file_load_order")
   325  
   326  	s, err := NewSessionWithOptions(Options{
   327  		SharedConfigFiles: []string{testConfigOtherFilename},
   328  	})
   329  	if err != nil {
   330  		t.Errorf("expect nil, %v", err)
   331  	}
   332  
   333  	if e, a := "shared_config_other_region", *s.Config.Region; e != a {
   334  		t.Errorf("expect %v, got %v", e, a)
   335  	}
   336  
   337  	creds, err := s.Config.Credentials.Get()
   338  	if err != nil {
   339  		t.Errorf("expect nil, %v", err)
   340  	}
   341  	if e, a := "shared_config_other_akid", creds.AccessKeyID; e != a {
   342  		t.Errorf("expect %v, got %v", e, a)
   343  	}
   344  	if e, a := "shared_config_other_secret", creds.SecretAccessKey; e != a {
   345  		t.Errorf("expect %v, got %v", e, a)
   346  	}
   347  	if v := creds.SessionToken; len(v) != 0 {
   348  		t.Errorf("expect empty, got %v", v)
   349  	}
   350  	if e, a := "SharedConfigCredentials", creds.ProviderName; !strings.Contains(a, e) {
   351  		t.Errorf("expect %v, to be in %v", e, a)
   352  	}
   353  }
   354  
   355  func TestNewSessionWithOptions_Overrides(t *testing.T) {
   356  	cases := map[string]struct {
   357  		InEnvs    map[string]string
   358  		InProfile string
   359  		OutRegion string
   360  		OutCreds  credentials.Value
   361  	}{
   362  		"env profile with opt profile": {
   363  			InEnvs: map[string]string{
   364  				"AWS_SDK_LOAD_CONFIG":         "0",
   365  				"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
   366  				"AWS_PROFILE":                 "other_profile",
   367  			},
   368  			InProfile: "full_profile",
   369  			OutRegion: "full_profile_region",
   370  			OutCreds: credentials.Value{
   371  				AccessKeyID:     "full_profile_akid",
   372  				SecretAccessKey: "full_profile_secret",
   373  				ProviderName:    "SharedConfigCredentials",
   374  			},
   375  		},
   376  		"env creds with env profile": {
   377  			InEnvs: map[string]string{
   378  				"AWS_SDK_LOAD_CONFIG":         "0",
   379  				"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
   380  				"AWS_REGION":                  "env_region",
   381  				"AWS_ACCESS_KEY":              "env_akid",
   382  				"AWS_SECRET_ACCESS_KEY":       "env_secret",
   383  				"AWS_PROFILE":                 "other_profile",
   384  			},
   385  			OutRegion: "env_region",
   386  			OutCreds: credentials.Value{
   387  				AccessKeyID:     "env_akid",
   388  				SecretAccessKey: "env_secret",
   389  				ProviderName:    "EnvConfigCredentials",
   390  			},
   391  		},
   392  		"env creds with opt profile": {
   393  			InEnvs: map[string]string{
   394  				"AWS_SDK_LOAD_CONFIG":         "0",
   395  				"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
   396  				"AWS_REGION":                  "env_region",
   397  				"AWS_ACCESS_KEY":              "env_akid",
   398  				"AWS_SECRET_ACCESS_KEY":       "env_secret",
   399  				"AWS_PROFILE":                 "other_profile",
   400  			},
   401  			InProfile: "full_profile",
   402  			OutRegion: "env_region",
   403  			OutCreds: credentials.Value{
   404  				AccessKeyID:     "full_profile_akid",
   405  				SecretAccessKey: "full_profile_secret",
   406  				ProviderName:    "SharedConfigCredentials",
   407  			},
   408  		},
   409  		"cfg and cred file with opt profile": {
   410  			InEnvs: map[string]string{
   411  				"AWS_SDK_LOAD_CONFIG":         "0",
   412  				"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
   413  				"AWS_CONFIG_FILE":             testConfigOtherFilename,
   414  				"AWS_PROFILE":                 "other_profile",
   415  			},
   416  			InProfile: "config_file_load_order",
   417  			OutRegion: "shared_config_region",
   418  			OutCreds: credentials.Value{
   419  				AccessKeyID:     "shared_config_akid",
   420  				SecretAccessKey: "shared_config_secret",
   421  				ProviderName:    "SharedConfigCredentials",
   422  			},
   423  		},
   424  	}
   425  
   426  	for name, c := range cases {
   427  		t.Run(name, func(t *testing.T) {
   428  			restoreEnvFn := initSessionTestEnv()
   429  			defer restoreEnvFn()
   430  
   431  			for k, v := range c.InEnvs {
   432  				os.Setenv(k, v)
   433  			}
   434  
   435  			s, err := NewSessionWithOptions(Options{
   436  				Profile:           c.InProfile,
   437  				SharedConfigState: SharedConfigEnable,
   438  			})
   439  			if err != nil {
   440  				t.Fatalf("expect no error, got %v", err)
   441  			}
   442  
   443  			creds, err := s.Config.Credentials.Get()
   444  			if err != nil {
   445  				t.Fatalf("expect no error, got %v", err)
   446  			}
   447  			if e, a := c.OutRegion, *s.Config.Region; e != a {
   448  				t.Errorf("expect %v, got %v", e, a)
   449  			}
   450  			if e, a := c.OutCreds.AccessKeyID, creds.AccessKeyID; e != a {
   451  				t.Errorf("expect %v, got %v", e, a)
   452  			}
   453  			if e, a := c.OutCreds.SecretAccessKey, creds.SecretAccessKey; e != a {
   454  				t.Errorf("expect %v, got %v", e, a)
   455  			}
   456  			if e, a := c.OutCreds.SessionToken, creds.SessionToken; e != a {
   457  				t.Errorf("expect %v, got %v", e, a)
   458  			}
   459  			if e, a := c.OutCreds.ProviderName, creds.ProviderName; !strings.Contains(a, e) {
   460  				t.Errorf("expect %v, to be in %v", e, a)
   461  			}
   462  		})
   463  	}
   464  }
   465  
   466  func TestNewSession_EnvCredsWithInvalidConfigFile(t *testing.T) {
   467  	cases := map[string]struct {
   468  		AccessKey, SecretKey string
   469  		Profile              string
   470  		Options              Options
   471  		ExpectCreds          credentials.Value
   472  		Err                  string
   473  	}{
   474  		"no options": {
   475  			Err: "SharedConfigLoadError",
   476  		},
   477  		"env only": {
   478  			AccessKey: "env_akid",
   479  			SecretKey: "env_secret",
   480  			ExpectCreds: credentials.Value{
   481  				AccessKeyID:     "env_akid",
   482  				SecretAccessKey: "env_secret",
   483  				ProviderName:    "EnvConfigCredentials",
   484  			},
   485  		},
   486  		"static credentials only": {
   487  			Options: Options{
   488  				Config: aws.Config{
   489  					Credentials: credentials.NewStaticCredentials(
   490  						"AKID", "SECRET", ""),
   491  				},
   492  			},
   493  			ExpectCreds: credentials.Value{
   494  				AccessKeyID:     "AKID",
   495  				SecretAccessKey: "SECRET",
   496  				ProviderName:    "StaticProvider",
   497  			},
   498  		},
   499  		"env profile and env": {
   500  			AccessKey: "env_akid",
   501  			SecretKey: "env_secret",
   502  			Profile:   "env_profile",
   503  			Err:       "SharedConfigLoadError",
   504  		},
   505  		"opt profile and env": {
   506  			AccessKey: "env_akid",
   507  			SecretKey: "env_secret",
   508  			Options: Options{
   509  				Profile: "someProfile",
   510  			},
   511  			Err: "SharedConfigLoadError",
   512  		},
   513  		"cfg enabled": {
   514  			AccessKey: "env_akid",
   515  			SecretKey: "env_secret",
   516  			Options: Options{
   517  				SharedConfigState: SharedConfigEnable,
   518  			},
   519  			Err: "SharedConfigLoadError",
   520  		},
   521  	}
   522  
   523  	var cfgFile = filepath.Join("testdata", "shared_config_invalid_ini")
   524  
   525  	for name, c := range cases {
   526  		t.Run(name, func(t *testing.T) {
   527  			restoreEnvFn := initSessionTestEnv()
   528  			defer restoreEnvFn()
   529  
   530  			if v := c.AccessKey; len(v) != 0 {
   531  				os.Setenv("AWS_ACCESS_KEY", v)
   532  			}
   533  			if v := c.SecretKey; len(v) != 0 {
   534  				os.Setenv("AWS_SECRET_ACCESS_KEY", v)
   535  			}
   536  			if v := c.Profile; len(v) != 0 {
   537  				os.Setenv("AWS_PROFILE", v)
   538  			}
   539  
   540  			opts := c.Options
   541  			opts.SharedConfigFiles = []string{cfgFile}
   542  			s, err := NewSessionWithOptions(opts)
   543  			if len(c.Err) != 0 {
   544  				if err == nil {
   545  					t.Fatalf("expect session error, got none")
   546  				}
   547  				if e, a := c.Err, err.Error(); !strings.Contains(a, e) {
   548  					t.Fatalf("expect session error to contain %q, got %v", e, a)
   549  				}
   550  				return
   551  			}
   552  
   553  			if err != nil {
   554  				t.Fatalf("expect no error, got %v", err)
   555  			}
   556  
   557  			creds, err := s.Config.Credentials.Get()
   558  			if err != nil {
   559  				t.Fatalf("expect no error, got %v", err)
   560  			}
   561  			if e, a := c.ExpectCreds.AccessKeyID, creds.AccessKeyID; e != a {
   562  				t.Errorf("expect %v, got %v", e, a)
   563  			}
   564  			if e, a := c.ExpectCreds.SecretAccessKey, creds.SecretAccessKey; e != a {
   565  				t.Errorf("expect %v, got %v", e, a)
   566  			}
   567  			if e, a := c.ExpectCreds.ProviderName, creds.ProviderName; !strings.Contains(a, e) {
   568  				t.Errorf("expect %v, to be in %v", e, a)
   569  			}
   570  		})
   571  	}
   572  }
   573  
   574  func TestSession_RegionalEndpoints(t *testing.T) {
   575  	cases := map[string]struct {
   576  		Env    map[string]string
   577  		Config aws.Config
   578  
   579  		ExpectErr       string
   580  		ExpectSTS       endpoints.STSRegionalEndpoint
   581  		ExpectS3UsEast1 endpoints.S3UsEast1RegionalEndpoint
   582  	}{
   583  		"default": {
   584  			ExpectSTS:       endpoints.LegacySTSEndpoint,
   585  			ExpectS3UsEast1: endpoints.LegacyS3UsEast1Endpoint,
   586  		},
   587  		"enable regional": {
   588  			Config: aws.Config{
   589  				STSRegionalEndpoint:       endpoints.RegionalSTSEndpoint,
   590  				S3UsEast1RegionalEndpoint: endpoints.RegionalS3UsEast1Endpoint,
   591  			},
   592  			ExpectSTS:       endpoints.RegionalSTSEndpoint,
   593  			ExpectS3UsEast1: endpoints.RegionalS3UsEast1Endpoint,
   594  		},
   595  		"sts env enable": {
   596  			Env: map[string]string{
   597  				"AWS_STS_REGIONAL_ENDPOINTS": "regional",
   598  			},
   599  			ExpectSTS:       endpoints.RegionalSTSEndpoint,
   600  			ExpectS3UsEast1: endpoints.LegacyS3UsEast1Endpoint,
   601  		},
   602  		"sts us-east-1 env merge enable": {
   603  			Env: map[string]string{
   604  				"AWS_STS_REGIONAL_ENDPOINTS": "legacy",
   605  			},
   606  			Config: aws.Config{
   607  				STSRegionalEndpoint: endpoints.RegionalSTSEndpoint,
   608  			},
   609  			ExpectSTS:       endpoints.RegionalSTSEndpoint,
   610  			ExpectS3UsEast1: endpoints.LegacyS3UsEast1Endpoint,
   611  		},
   612  		"s3 us-east-1 env enable": {
   613  			Env: map[string]string{
   614  				"AWS_S3_US_EAST_1_REGIONAL_ENDPOINT": "regional",
   615  			},
   616  			ExpectSTS:       endpoints.LegacySTSEndpoint,
   617  			ExpectS3UsEast1: endpoints.RegionalS3UsEast1Endpoint,
   618  		},
   619  		"s3 us-east-1 env merge enable": {
   620  			Env: map[string]string{
   621  				"AWS_S3_US_EAST_1_REGIONAL_ENDPOINT": "legacy",
   622  			},
   623  			Config: aws.Config{
   624  				S3UsEast1RegionalEndpoint: endpoints.RegionalS3UsEast1Endpoint,
   625  			},
   626  			ExpectSTS:       endpoints.LegacySTSEndpoint,
   627  			ExpectS3UsEast1: endpoints.RegionalS3UsEast1Endpoint,
   628  		},
   629  	}
   630  
   631  	for name, c := range cases {
   632  		t.Run(name, func(t *testing.T) {
   633  			restoreEnvFn := initSessionTestEnv()
   634  			defer restoreEnvFn()
   635  
   636  			for k, v := range c.Env {
   637  				os.Setenv(k, v)
   638  			}
   639  
   640  			s, err := NewSession(&c.Config)
   641  			if len(c.ExpectErr) != 0 {
   642  				if err == nil {
   643  					t.Fatalf("expect session error, got none")
   644  				}
   645  				if e, a := c.ExpectErr, err.Error(); !strings.Contains(a, e) {
   646  					t.Fatalf("expect session error to contain %q, got %v", e, a)
   647  				}
   648  				return
   649  			}
   650  
   651  			if err != nil {
   652  				t.Fatalf("expect no error, got %v", err)
   653  			}
   654  
   655  			if e, a := c.ExpectSTS, s.Config.STSRegionalEndpoint; e != a {
   656  				t.Errorf("expect %v STSRegionalEndpoint, got %v", e, a)
   657  			}
   658  
   659  			if e, a := c.ExpectS3UsEast1, s.Config.S3UsEast1RegionalEndpoint; e != a {
   660  				t.Errorf("expect %v S3UsEast1RegionalEndpoint, got %v", e, a)
   661  			}
   662  
   663  			// Asserts
   664  		})
   665  	}
   666  }
   667  
   668  func TestSession_ClientConfig_ResolveEndpoint(t *testing.T) {
   669  	cases := map[string]struct {
   670  		Service        string
   671  		Region         string
   672  		Env            map[string]string
   673  		Options        Options
   674  		ExpectEndpoint string
   675  	}{
   676  		"IMDS custom endpoint from env": {
   677  			Service: ec2MetadataServiceID,
   678  			Region:  "ignored",
   679  			Env: map[string]string{
   680  				"AWS_EC2_METADATA_SERVICE_ENDPOINT": "http://example.aws",
   681  			},
   682  			ExpectEndpoint: "http://example.aws",
   683  		},
   684  		"IMDS custom endpoint from aws.Config": {
   685  			Service: ec2MetadataServiceID,
   686  			Region:  "ignored",
   687  			Options: Options{
   688  				EC2IMDSEndpoint: "http://example.aws",
   689  			},
   690  			ExpectEndpoint: "http://example.aws",
   691  		},
   692  		"IMDS custom endpoint from aws.Config and env": {
   693  			Service: ec2MetadataServiceID,
   694  			Region:  "ignored",
   695  			Env: map[string]string{
   696  				"AWS_EC2_METADATA_SERVICE_ENDPOINT": "http://wrong.example.aws",
   697  			},
   698  			Options: Options{
   699  				EC2IMDSEndpoint: "http://correct.example.aws",
   700  			},
   701  			ExpectEndpoint: "http://correct.example.aws",
   702  		},
   703  		"IMDS custom endpoint from profile": {
   704  			Service: ec2MetadataServiceID,
   705  			Options: Options{
   706  				SharedConfigState: SharedConfigEnable,
   707  				SharedConfigFiles: []string{testConfigFilename},
   708  				Profile:           "EC2MetadataServiceEndpoint",
   709  			},
   710  			Region:         "ignored",
   711  			ExpectEndpoint: "http://endpoint.localhost",
   712  		},
   713  		"IMDS custom endpoint from profile and env": {
   714  			Service: ec2MetadataServiceID,
   715  			Options: Options{
   716  				SharedConfigFiles: []string{testConfigFilename},
   717  				Profile:           "EC2MetadataServiceEndpoint",
   718  			},
   719  			Env: map[string]string{
   720  				"AWS_EC2_METADATA_SERVICE_ENDPOINT": "http://endpoint-env.localhost",
   721  			},
   722  			Region:         "ignored",
   723  			ExpectEndpoint: "http://endpoint-env.localhost",
   724  		},
   725  		"IMDS IPv6 mode from profile": {
   726  			Service: ec2MetadataServiceID,
   727  			Options: Options{
   728  				SharedConfigState: SharedConfigEnable,
   729  				SharedConfigFiles: []string{testConfigFilename},
   730  				Profile:           "EC2MetadataServiceEndpointModeIPv6",
   731  			},
   732  			Region:         "ignored",
   733  			ExpectEndpoint: "http://[fd00:ec2::254]/latest",
   734  		},
   735  		"IMDS IPv4 mode from profile": {
   736  			Service: ec2MetadataServiceID,
   737  			Options: Options{
   738  				SharedConfigFiles: []string{testConfigFilename},
   739  				Profile:           "EC2MetadataServiceEndpointModeIPv4",
   740  			},
   741  			Region:         "ignored",
   742  			ExpectEndpoint: "http://169.254.169.254/latest",
   743  		},
   744  		"IMDS IPv6 mode in env": {
   745  			Service: ec2MetadataServiceID,
   746  			Env: map[string]string{
   747  				"AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE": "IPv6",
   748  			},
   749  			Region:         "ignored",
   750  			ExpectEndpoint: "http://[fd00:ec2::254]/latest",
   751  		},
   752  		"IMDS IPv4 mode in env": {
   753  			Service: ec2MetadataServiceID,
   754  			Env: map[string]string{
   755  				"AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE": "IPv4",
   756  			},
   757  			Region:         "ignored",
   758  			ExpectEndpoint: "http://169.254.169.254/latest",
   759  		},
   760  		"IMDS mode in env and profile": {
   761  			Service: ec2MetadataServiceID,
   762  			Options: Options{
   763  				SharedConfigFiles: []string{testConfigFilename},
   764  				Profile:           "EC2MetadataServiceEndpointModeIPv4",
   765  			},
   766  			Env: map[string]string{
   767  				"AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE": "IPv6",
   768  			},
   769  			Region:         "ignored",
   770  			ExpectEndpoint: "http://[fd00:ec2::254]/latest",
   771  		},
   772  		"IMDS mode and endpoint profile": {
   773  			Service: ec2MetadataServiceID,
   774  			Options: Options{
   775  				SharedConfigState: SharedConfigEnable,
   776  				SharedConfigFiles: []string{testConfigFilename},
   777  				Profile:           "EC2MetadataServiceEndpointAndModeMixed",
   778  			},
   779  			Region:         "ignored",
   780  			ExpectEndpoint: "http://endpoint.localhost",
   781  		},
   782  		"IMDS mode session option and env": {
   783  			Service: ec2MetadataServiceID,
   784  			Options: Options{
   785  				EC2IMDSEndpointMode: endpoints.EC2IMDSEndpointModeStateIPv6,
   786  			},
   787  			Env: map[string]string{
   788  				"AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE": "IPv4",
   789  			},
   790  			Region:         "ignored",
   791  			ExpectEndpoint: "http://[fd00:ec2::254]/latest",
   792  		},
   793  		"IMDS endpoint session option and env": {
   794  			Service: ec2MetadataServiceID,
   795  			Options: Options{
   796  				EC2IMDSEndpoint: "http://endpoint.localhost",
   797  			},
   798  			Env: map[string]string{
   799  				"AWS_EC2_METADATA_SERVICE_ENDPOINT": "http://endpoint-env.localhost",
   800  			},
   801  			Region:         "ignored",
   802  			ExpectEndpoint: "http://endpoint.localhost",
   803  		},
   804  	}
   805  
   806  	for name, c := range cases {
   807  		t.Run(name, func(t *testing.T) {
   808  			restoreEnvFn := initSessionTestEnv()
   809  			defer restoreEnvFn()
   810  
   811  			for k, v := range c.Env {
   812  				os.Setenv(k, v)
   813  			}
   814  
   815  			s, err := NewSessionWithOptions(c.Options)
   816  			if err != nil {
   817  				t.Fatalf("expect no error, got %v", err)
   818  			}
   819  
   820  			clientCfg := s.ClientConfig(c.Service, &aws.Config{
   821  				Region: aws.String(c.Region),
   822  			})
   823  
   824  			if e, a := c.ExpectEndpoint, clientCfg.Endpoint; e != a {
   825  				t.Errorf("expect %v, got %v", e, a)
   826  			}
   827  		})
   828  	}
   829  }