github.com/aavshr/aws-sdk-go@v1.41.3/service/s3control/endpoint_test.go (about)

     1  //go:build go1.7
     2  // +build go1.7
     3  
     4  package s3control
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/aavshr/aws-sdk-go/aws"
    15  	"github.com/aavshr/aws-sdk-go/aws/endpoints"
    16  	"github.com/aavshr/aws-sdk-go/aws/request"
    17  	"github.com/aavshr/aws-sdk-go/awstesting/unit"
    18  )
    19  
    20  type testParams struct {
    21  	bucket                     string
    22  	config                     *aws.Config
    23  	expectedEndpoint           string
    24  	expectedSigningName        string
    25  	expectedSigningRegion      string
    26  	expectedHeaderForOutpostID string
    27  	expectedHeaderForAccountID bool
    28  	expectedErr                string
    29  }
    30  
    31  // Test endpoint from outpost access point
    32  func TestEndpoint_OutpostAccessPointARN(t *testing.T) {
    33  	cases := map[string]testParams{
    34  		"Outpost AccessPoint with no S3UseARNRegion flag set": {
    35  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    36  			config: &aws.Config{
    37  				Region: aws.String("us-west-2"),
    38  			},
    39  			expectedEndpoint:           "https://s3-outposts.us-west-2.amazonaws.com",
    40  			expectedSigningName:        "s3-outposts",
    41  			expectedSigningRegion:      "us-west-2",
    42  			expectedHeaderForAccountID: true,
    43  			expectedHeaderForOutpostID: "op-01234567890123456",
    44  		},
    45  		"Outpost AccessPoint Cross-Region Enabled": {
    46  			bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    47  			config: &aws.Config{
    48  				Region:         aws.String("us-west-2"),
    49  				S3UseARNRegion: aws.Bool(true),
    50  			},
    51  			expectedEndpoint:           "https://s3-outposts.us-east-1.amazonaws.com",
    52  			expectedSigningName:        "s3-outposts",
    53  			expectedSigningRegion:      "us-east-1",
    54  			expectedHeaderForAccountID: true,
    55  			expectedHeaderForOutpostID: "op-01234567890123456",
    56  		},
    57  		"Outpost AccessPoint Cross-Region Disabled": {
    58  			bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    59  			config: &aws.Config{
    60  				Region: aws.String("us-west-2"),
    61  			},
    62  			expectedErr: "client region does not match provided ARN region",
    63  		},
    64  		"Outpost AccessPoint other partition": {
    65  			bucket: "arn:aws-cn:s3-outposts:cn-north-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    66  			config: &aws.Config{
    67  				Region:         aws.String("us-west-2"),
    68  				S3UseARNRegion: aws.Bool(true),
    69  			},
    70  			expectedErr: "ConfigurationError: client partition does not match provided ARN partition",
    71  		},
    72  		"Outpost AccessPoint us-gov region": {
    73  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    74  			config: &aws.Config{
    75  				Region:         aws.String("us-gov-east-1"),
    76  				S3UseARNRegion: aws.Bool(true),
    77  			},
    78  			expectedEndpoint:           "https://s3-outposts.us-gov-east-1.amazonaws.com",
    79  			expectedSigningName:        "s3-outposts",
    80  			expectedSigningRegion:      "us-gov-east-1",
    81  			expectedHeaderForAccountID: true,
    82  			expectedHeaderForOutpostID: "op-01234567890123456",
    83  		},
    84  		"Outpost AccessPoint with client region as FIPS": {
    85  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    86  			config: &aws.Config{
    87  				EndpointResolver: endpoints.AwsUsGovPartition(),
    88  				Region:           aws.String("us-gov-east-1-fips"),
    89  			},
    90  			expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
    91  		},
    92  		"Outpost AccessPoint with client FIPS region and cross-region ARN": {
    93  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
    94  			config: &aws.Config{
    95  				EndpointResolver: endpoints.AwsUsGovPartition(),
    96  				Region:           aws.String("us-gov-east-1-fips"),
    97  				S3UseARNRegion:   aws.Bool(true),
    98  			},
    99  			expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
   100  		},
   101  		"Outpost AccessPoint FIPS client region with matching ARN region": {
   102  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   103  			config: &aws.Config{
   104  				EndpointResolver: endpoints.AwsUsGovPartition(),
   105  				Region:           aws.String("fips-us-gov-east-1"),
   106  				S3UseARNRegion:   aws.Bool(true),
   107  			},
   108  			expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
   109  		},
   110  		"Outpost AccessPoint with DualStack": {
   111  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   112  			config: &aws.Config{
   113  				Region:       aws.String("us-west-2"),
   114  				UseDualStack: aws.Bool(true),
   115  			},
   116  			expectedErr: "ConfigurationError: client configured for S3 Dual-stack but is not supported with resource ARN",
   117  		},
   118  		"Outpost AccessPoint with Accelerate": {
   119  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   120  			config: &aws.Config{
   121  				Region:          aws.String("us-west-2"),
   122  				S3UseAccelerate: aws.Bool(true),
   123  			},
   124  			expectedErr: "ConfigurationError: client configured for S3 Accelerate but is not supported with resource ARN",
   125  		},
   126  		"Invalid outpost resource format": {
   127  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost",
   128  			config: &aws.Config{
   129  				Region: aws.String("us-west-2"),
   130  			},
   131  			expectedErr: "outpost resource-id not set",
   132  		},
   133  		"Missing access point for outpost resource": {
   134  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456",
   135  			config: &aws.Config{
   136  				Region: aws.String("us-west-2"),
   137  			},
   138  			expectedErr: "incomplete outpost resource type",
   139  		},
   140  		"access point": {
   141  			bucket: "myaccesspoint",
   142  			config: &aws.Config{
   143  				Region: aws.String("us-west-2"),
   144  			},
   145  			expectedEndpoint:           "https://123456789012.s3-control.us-west-2.amazonaws.com",
   146  			expectedHeaderForAccountID: true,
   147  			expectedSigningRegion:      "us-west-2",
   148  			expectedSigningName:        "s3",
   149  		},
   150  		"outpost access point with unsupported sub-resource": {
   151  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:mybucket:object:foo",
   152  			config: &aws.Config{
   153  				Region: aws.String("us-west-2"),
   154  			},
   155  			expectedErr: "sub resource not supported",
   156  		},
   157  		"Missing outpost identifiers in outpost access point arn": {
   158  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:accesspoint:myendpoint",
   159  			config: &aws.Config{
   160  				Region: aws.String("us-west-2"),
   161  			},
   162  			expectedErr: "invalid Amazon s3-outposts ARN",
   163  		},
   164  		"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (prefix)": {
   165  			bucket: "arn:aws-us-gov:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   166  			config: &aws.Config{
   167  				Region:         aws.String("us-west-2"),
   168  				S3UseARNRegion: aws.Bool(true),
   169  			},
   170  			expectedErr: "FIPS region not allowed in ARN",
   171  		},
   172  		"Invalid Outpost AccessPoint ARN with FIPS pseudo-region (suffix)": {
   173  			bucket: "arn:aws-us-gov:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   174  			config: &aws.Config{
   175  				Region:         aws.String("us-west-2"),
   176  				S3UseARNRegion: aws.Bool(true),
   177  			},
   178  			expectedErr: "FIPS region not allowed in ARN",
   179  		},
   180  	}
   181  
   182  	runValidations(t, cases)
   183  }
   184  
   185  // Test endpoint from outpost bucket arn
   186  func TestEndpoint_OutpostBucketARN(t *testing.T) {
   187  	cases := map[string]testParams{
   188  		"Outpost Bucket with no S3UseARNRegion flag set": {
   189  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   190  			config: &aws.Config{
   191  				Region: aws.String("us-west-2"),
   192  			},
   193  			expectedEndpoint:           "https://s3-outposts.us-west-2.amazonaws.com",
   194  			expectedSigningName:        "s3-outposts",
   195  			expectedSigningRegion:      "us-west-2",
   196  			expectedHeaderForOutpostID: "op-01234567890123456",
   197  			expectedHeaderForAccountID: true,
   198  		},
   199  		"Outpost Bucket Cross-Region Enabled": {
   200  			bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   201  			config: &aws.Config{
   202  				Region:         aws.String("us-west-2"),
   203  				S3UseARNRegion: aws.Bool(true),
   204  			},
   205  			expectedEndpoint:           "https://s3-outposts.us-east-1.amazonaws.com",
   206  			expectedSigningName:        "s3-outposts",
   207  			expectedSigningRegion:      "us-east-1",
   208  			expectedHeaderForOutpostID: "op-01234567890123456",
   209  			expectedHeaderForAccountID: true,
   210  		},
   211  		"Outpost Bucket Cross-Region Disabled": {
   212  			bucket: "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   213  			config: &aws.Config{
   214  				Region: aws.String("us-west-2"),
   215  			},
   216  			expectedErr: "client region does not match provided ARN region",
   217  		},
   218  		"Outpost Bucket other partition": {
   219  			bucket: "arn:aws-cn:s3-outposts:cn-north-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   220  			config: &aws.Config{
   221  				Region:         aws.String("us-west-2"),
   222  				S3UseARNRegion: aws.Bool(true),
   223  			},
   224  			expectedErr: "ConfigurationError: client partition does not match provided ARN partition",
   225  		},
   226  		"Outpost Bucket us-gov region": {
   227  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   228  			config: &aws.Config{
   229  				Region:         aws.String("us-gov-east-1"),
   230  				S3UseARNRegion: aws.Bool(true),
   231  			},
   232  			expectedEndpoint:           "https://s3-outposts.us-gov-east-1.amazonaws.com",
   233  			expectedSigningName:        "s3-outposts",
   234  			expectedSigningRegion:      "us-gov-east-1",
   235  			expectedHeaderForOutpostID: "op-01234567890123456",
   236  			expectedHeaderForAccountID: true,
   237  		},
   238  		"Outpost Bucket FIPS client region": {
   239  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   240  			config: &aws.Config{
   241  				EndpointResolver: endpoints.AwsUsGovPartition(),
   242  				Region:           aws.String("fips-us-gov-east-1"),
   243  			},
   244  			expectedErr: "ConfigurationError: client region does not match provided ARN region",
   245  		},
   246  		"Outpost Bucket FIPS client region with match ARN region": {
   247  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   248  			config: &aws.Config{
   249  				EndpointResolver: endpoints.AwsUsGovPartition(),
   250  				Region:           aws.String("fips-us-gov-east-1"),
   251  				S3UseARNRegion:   aws.Bool(true),
   252  			},
   253  			expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
   254  		},
   255  		"Outpost Bucket FIPS client region with cross-region ARN": {
   256  			bucket: "arn:aws-us-gov:s3-outposts:us-gov-west-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   257  			config: &aws.Config{
   258  				EndpointResolver: endpoints.AwsUsGovPartition(),
   259  				Region:           aws.String("fips-us-gov-east-1"),
   260  				S3UseARNRegion:   aws.Bool(true),
   261  			},
   262  			expectedErr: "use of ARN is not supported when client or request is configured for FIPS",
   263  		},
   264  		"Outpost Bucket with DualStack": {
   265  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   266  			config: &aws.Config{
   267  				Region:       aws.String("us-west-2"),
   268  				UseDualStack: aws.Bool(true),
   269  			},
   270  			expectedErr: "ConfigurationError: client configured for S3 Dual-stack but is not supported with resource ARN",
   271  		},
   272  		"Outpost Bucket with Accelerate": {
   273  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint",
   274  			config: &aws.Config{
   275  				Region:          aws.String("us-west-2"),
   276  				S3UseAccelerate: aws.Bool(true),
   277  			},
   278  			expectedErr: "ConfigurationError: client configured for S3 Accelerate but is not supported with resource ARN",
   279  		},
   280  		"Missing bucket id": {
   281  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket",
   282  			config: &aws.Config{
   283  				Region:          aws.String("us-west-2"),
   284  				S3UseAccelerate: aws.Bool(true),
   285  			},
   286  			expectedErr: "invalid Amazon s3-outposts ARN",
   287  		},
   288  		"Invalid ARN": {
   289  			bucket: "arn:aws:s3-outposts:us-west-2:123456789012:bucket:mybucket",
   290  			config: &aws.Config{
   291  				Region: aws.String("us-west-2"),
   292  			},
   293  			expectedErr: "invalid Amazon s3-outposts ARN, unknown resource type",
   294  		},
   295  		"Invalid Outpost Bucket ARN with FIPS pseudo-region (prefix)": {
   296  			bucket: "arn:aws:s3-outposts:fips-us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   297  			config: &aws.Config{
   298  				Region:         aws.String("us-west-2"),
   299  				S3UseARNRegion: aws.Bool(true),
   300  			},
   301  			expectedErr: "FIPS region not allowed in ARN",
   302  		},
   303  		"Invalid Outpost Bucket ARN with FIPS pseudo-region (suffix)": {
   304  			bucket: "arn:aws:s3-outposts:us-east-1-fips:123456789012:outpost:op-01234567890123456:bucket:mybucket",
   305  			config: &aws.Config{
   306  				Region:         aws.String("us-west-2"),
   307  				S3UseARNRegion: aws.Bool(true),
   308  			},
   309  			expectedErr: "FIPS region not allowed in ARN",
   310  		},
   311  	}
   312  
   313  	runValidations(t, cases)
   314  }
   315  
   316  // Runs the test validation
   317  func runValidations(t *testing.T, cases map[string]testParams) {
   318  	for name, c := range cases {
   319  		t.Run(name, func(t *testing.T) {
   320  			sess := unit.Session.Copy(c.config)
   321  
   322  			svc := New(sess)
   323  			req, _ := svc.GetBucketRequest(&GetBucketInput{
   324  				Bucket:    &c.bucket,
   325  				AccountId: aws.String("123456789012"),
   326  			})
   327  
   328  			req.Handlers.Send.Clear()
   329  			req.Handlers.Send.PushBack(func(r *request.Request) {
   330  				defer func() {
   331  					r.HTTPResponse = &http.Response{
   332  						StatusCode:    200,
   333  						ContentLength: 0,
   334  						Body:          ioutil.NopCloser(bytes.NewReader(nil)),
   335  					}
   336  				}()
   337  				if len(c.expectedErr) != 0 {
   338  					return
   339  				}
   340  
   341  				endpoint := fmt.Sprintf("%s://%s", r.HTTPRequest.URL.Scheme, r.HTTPRequest.URL.Host)
   342  				if e, a := c.expectedEndpoint, endpoint; e != a {
   343  					t.Errorf("expected %v, got %v", e, a)
   344  				}
   345  
   346  				if e, a := c.expectedSigningName, r.ClientInfo.SigningName; e != a {
   347  					t.Errorf("expected %v, got %v", e, a)
   348  				}
   349  				if e, a := c.expectedSigningRegion, r.ClientInfo.SigningRegion; e != a {
   350  					t.Errorf("expected %v, got %v", e, a)
   351  				}
   352  
   353  				if e, a := c.expectedHeaderForOutpostID, r.HTTPRequest.Header.Get("x-amz-outpost-id"); e != a {
   354  					if len(e) == 0 {
   355  						t.Errorf("expected no outpost id header set, got %v", a)
   356  					} else if len(a) == 0 {
   357  						t.Errorf("expected outpost id header set as %v, got none", e)
   358  					} else {
   359  						t.Errorf("expected %v as Outpost id header value, got %v", e, a)
   360  					}
   361  				}
   362  
   363  				if c.expectedHeaderForAccountID {
   364  					if e, a := "123456789012", r.HTTPRequest.Header.Get("x-amz-account-id"); e != a {
   365  						t.Errorf("expected x-amz-account-id header value to be %v, got %v", e, a)
   366  					}
   367  				}
   368  			})
   369  
   370  			err := req.Send()
   371  			if len(c.expectedErr) == 0 && err != nil {
   372  				t.Errorf("expected no error but got: %v", err)
   373  			} else if len(c.expectedErr) != 0 && err == nil {
   374  				t.Errorf("expected err %q, but got nil", c.expectedErr)
   375  			} else if len(c.expectedErr) != 0 && err != nil && !strings.Contains(err.Error(), c.expectedErr) {
   376  				t.Errorf("expected %v, got %v", c.expectedErr, err.Error())
   377  			}
   378  		})
   379  	}
   380  }
   381  
   382  type testParamsWithRequestFn struct {
   383  	bucket                     string
   384  	outpostID                  string
   385  	config                     *aws.Config
   386  	requestFn                  func(c *S3Control) *request.Request
   387  	expectedEndpoint           string
   388  	expectedSigningName        string
   389  	expectedSigningRegion      string
   390  	expectedHeaderForOutpostID string
   391  	expectedErr                string
   392  }
   393  
   394  func TestCustomEndpoint_SpecialOperations(t *testing.T) {
   395  	cases := map[string]testParamsWithRequestFn{
   396  		"CreateBucketOperation": {
   397  			bucket:    "mockBucket",
   398  			outpostID: "op-01234567890123456",
   399  			config: &aws.Config{
   400  				Region: aws.String("us-west-2"),
   401  			},
   402  			requestFn: func(svc *S3Control) *request.Request {
   403  				req, _ := svc.CreateBucketRequest(&CreateBucketInput{
   404  					Bucket:    aws.String("mockBucket"),
   405  					OutpostId: aws.String("op-01234567890123456"),
   406  				})
   407  				return req
   408  			},
   409  			expectedEndpoint:           "https://s3-outposts.us-west-2.amazonaws.com",
   410  			expectedSigningName:        "s3-outposts",
   411  			expectedSigningRegion:      "us-west-2",
   412  			expectedHeaderForOutpostID: "op-01234567890123456",
   413  		},
   414  		"ListRegionalBucketsOperation": {
   415  			bucket:    "mockBucket",
   416  			outpostID: "op-01234567890123456",
   417  			config: &aws.Config{
   418  				Region: aws.String("us-west-2"),
   419  			},
   420  			requestFn: func(svc *S3Control) *request.Request {
   421  				req, _ := svc.ListRegionalBucketsRequest(&ListRegionalBucketsInput{
   422  					OutpostId: aws.String("op-01234567890123456"),
   423  					AccountId: aws.String("123456789012"),
   424  				})
   425  				return req
   426  			},
   427  			expectedEndpoint:           "https://s3-outposts.us-west-2.amazonaws.com",
   428  			expectedSigningName:        "s3-outposts",
   429  			expectedSigningRegion:      "us-west-2",
   430  			expectedHeaderForOutpostID: "op-01234567890123456",
   431  		},
   432  		"CreateAccessPoint bucket arn": {
   433  			config: &aws.Config{
   434  				Region: aws.String("us-west-2"),
   435  			},
   436  			requestFn: func(svc *S3Control) *request.Request {
   437  				req, _ := svc.CreateAccessPointRequest(&CreateAccessPointInput{
   438  					AccountId: aws.String("123456789012"),
   439  					Bucket:    aws.String("arn:aws:s3:us-west-2:123456789012:bucket:mockBucket"),
   440  					Name:      aws.String("mockName"),
   441  				})
   442  				return req
   443  			},
   444  			expectedErr: "invalid Amazon s3 ARN, unknown resource type",
   445  		},
   446  		"CreateAccessPoint outpost bucket arn": {
   447  			config: &aws.Config{
   448  				Region: aws.String("us-west-2"),
   449  			},
   450  			requestFn: func(svc *S3Control) *request.Request {
   451  				req, _ := svc.CreateAccessPointRequest(&CreateAccessPointInput{
   452  					AccountId: aws.String("123456789012"),
   453  					Bucket:    aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mockBucket"),
   454  					Name:      aws.String("mockName"),
   455  				})
   456  				return req
   457  			},
   458  			expectedEndpoint:           "https://s3-outposts.us-west-2.amazonaws.com",
   459  			expectedSigningName:        "s3-outposts",
   460  			expectedSigningRegion:      "us-west-2",
   461  			expectedHeaderForOutpostID: "op-01234567890123456",
   462  		},
   463  	}
   464  
   465  	for name, c := range cases {
   466  		t.Run(name, func(t *testing.T) {
   467  			runValidationsWithRequestFn(t, c)
   468  		})
   469  	}
   470  }
   471  
   472  func TestCustomEndpointURL(t *testing.T) {
   473  	account := "123456789012"
   474  	cases := map[string]testParamsWithRequestFn{
   475  		"standard GetAccesspoint with custom endpoint url": {
   476  			config: &aws.Config{
   477  				Endpoint: aws.String("beta.example.com"),
   478  				Region:   aws.String("us-west-2"),
   479  			},
   480  			requestFn: func(c *S3Control) *request.Request {
   481  				req, _ := c.GetAccessPointRequest(&GetAccessPointInput{
   482  					AccountId: aws.String(account),
   483  					Name:      aws.String("apname"),
   484  				})
   485  				return req
   486  			},
   487  			expectedEndpoint:      "https://123456789012.beta.example.com",
   488  			expectedSigningName:   "s3",
   489  			expectedSigningRegion: "us-west-2",
   490  		},
   491  		"Outpost Accesspoint ARN with GetAccesspoint and custom endpoint url": {
   492  			config: &aws.Config{
   493  				Endpoint: aws.String("beta.example.com"),
   494  				Region:   aws.String("us-west-2"),
   495  			},
   496  			requestFn: func(c *S3Control) *request.Request {
   497  				req, _ := c.GetAccessPointRequest(&GetAccessPointInput{
   498  					AccountId: aws.String(account),
   499  					Name:      aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint"),
   500  				})
   501  				return req
   502  			},
   503  			expectedEndpoint:           "https://beta.example.com",
   504  			expectedSigningName:        "s3-outposts",
   505  			expectedSigningRegion:      "us-west-2",
   506  			expectedHeaderForOutpostID: "op-01234567890123456",
   507  		},
   508  		"standard CreateBucket with custom endpoint url": {
   509  			config: &aws.Config{
   510  				Endpoint: aws.String("beta.example.com"),
   511  				Region:   aws.String("us-west-2"),
   512  			},
   513  			requestFn: func(c *S3Control) *request.Request {
   514  				req, _ := c.CreateBucketRequest(&CreateBucketInput{
   515  					Bucket:    aws.String("bucketname"),
   516  					OutpostId: aws.String("op-123"),
   517  				})
   518  				return req
   519  			},
   520  			expectedEndpoint:           "https://beta.example.com",
   521  			expectedSigningName:        "s3-outposts",
   522  			expectedSigningRegion:      "us-west-2",
   523  			expectedHeaderForOutpostID: "op-123",
   524  		},
   525  		"Outpost Accesspoint for GetBucket with custom endpoint url": {
   526  			config: &aws.Config{
   527  				Endpoint: aws.String("beta.example.com"),
   528  				Region:   aws.String("us-west-2"),
   529  			},
   530  			requestFn: func(c *S3Control) *request.Request {
   531  				req, _ := c.GetBucketRequest(&GetBucketInput{
   532  					Bucket: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket"),
   533  				})
   534  				return req
   535  			},
   536  			expectedEndpoint:           "https://beta.example.com",
   537  			expectedSigningName:        "s3-outposts",
   538  			expectedSigningRegion:      "us-west-2",
   539  			expectedHeaderForOutpostID: "op-01234567890123456",
   540  		},
   541  		"GetAccesspoint with dualstack and custom endpoint url": {
   542  			config: &aws.Config{
   543  				Endpoint:     aws.String("beta.example.com"),
   544  				Region:       aws.String("us-west-2"),
   545  				UseDualStack: aws.Bool(true),
   546  			},
   547  			requestFn: func(c *S3Control) *request.Request {
   548  				req, _ := c.GetAccessPointRequest(&GetAccessPointInput{
   549  					AccountId: aws.String(account),
   550  					Name:      aws.String("apname"),
   551  				})
   552  				return req
   553  			},
   554  			expectedEndpoint:      "https://123456789012.beta.example.com",
   555  			expectedSigningName:   "s3",
   556  			expectedSigningRegion: "us-west-2",
   557  		},
   558  		"GetAccesspoint with Outposts accesspoint ARN and dualstack": {
   559  			config: &aws.Config{
   560  				Endpoint:     aws.String("beta.example.com"),
   561  				UseDualStack: aws.Bool(true),
   562  				Region:       aws.String("us-west-2"),
   563  			},
   564  			requestFn: func(c *S3Control) *request.Request {
   565  				req, _ := c.GetAccessPointRequest(&GetAccessPointInput{
   566  					AccountId: aws.String(account),
   567  					Name:      aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:accesspoint:myaccesspoint"),
   568  				})
   569  				return req
   570  			},
   571  			expectedErr: "client configured for S3 Dual-stack but is not supported with resource ARN",
   572  		},
   573  		"standard CreateBucket with dualstack": {
   574  			config: &aws.Config{
   575  				Endpoint:     aws.String("beta.example.com"),
   576  				UseDualStack: aws.Bool(true),
   577  				Region:       aws.String("us-west-2"),
   578  			},
   579  			requestFn: func(c *S3Control) *request.Request {
   580  				req, _ := c.CreateBucketRequest(&CreateBucketInput{
   581  					Bucket:    aws.String("bucketname"),
   582  					OutpostId: aws.String("op-1234567890123456"),
   583  				})
   584  				return req
   585  			},
   586  			expectedEndpoint:           "https://beta.example.com",
   587  			expectedSigningName:        "s3-outposts",
   588  			expectedSigningRegion:      "us-west-2",
   589  			expectedHeaderForOutpostID: "op-1234567890123456",
   590  		},
   591  		"GetBucket with Outpost bucket ARN": {
   592  			config: &aws.Config{
   593  				Endpoint:     aws.String("beta.example.com"),
   594  				Region:       aws.String("us-west-2"),
   595  				UseDualStack: aws.Bool(true),
   596  			},
   597  			requestFn: func(c *S3Control) *request.Request {
   598  				req, _ := c.GetBucketRequest(&GetBucketInput{
   599  					Bucket: aws.String("arn:aws:s3-outposts:us-west-2:123456789012:outpost:op-01234567890123456:bucket:mybucket"),
   600  				})
   601  				return req
   602  			},
   603  			expectedErr: "client configured for S3 Dual-stack but is not supported with resource ARN",
   604  		},
   605  	}
   606  
   607  	for name, c := range cases {
   608  		t.Run(name, func(t *testing.T) {
   609  			runValidationsWithRequestFn(t, c)
   610  		})
   611  	}
   612  }
   613  
   614  func runValidationsWithRequestFn(t *testing.T, c testParamsWithRequestFn) {
   615  	sess := unit.Session.Copy(c.config)
   616  	svc := New(sess)
   617  
   618  	req := c.requestFn(svc)
   619  	req.Handlers.Send.Clear()
   620  	req.Handlers.Send.PushBack(func(r *request.Request) {
   621  		defer func() {
   622  			r.HTTPResponse = &http.Response{
   623  				StatusCode:    200,
   624  				ContentLength: 0,
   625  				Body:          ioutil.NopCloser(bytes.NewReader(nil)),
   626  			}
   627  		}()
   628  		if len(c.expectedErr) != 0 {
   629  			return
   630  		}
   631  
   632  		endpoint := fmt.Sprintf("%s://%s", r.HTTPRequest.URL.Scheme, r.HTTPRequest.URL.Host)
   633  		if e, a := c.expectedEndpoint, endpoint; e != a {
   634  			t.Errorf("expected %v, got %v", e, a)
   635  		}
   636  
   637  		if e, a := c.expectedSigningName, r.ClientInfo.SigningName; e != a {
   638  			t.Errorf("expected %v, got %v", e, a)
   639  		}
   640  		if e, a := c.expectedSigningRegion, r.ClientInfo.SigningRegion; e != a {
   641  			t.Errorf("expected %v, got %v", e, a)
   642  		}
   643  
   644  		if e, a := c.expectedHeaderForOutpostID, r.HTTPRequest.Header.Get("x-amz-outpost-id"); e != a {
   645  			if len(e) == 0 {
   646  				t.Errorf("expected no outpost id header set, got %v", a)
   647  			} else if len(a) == 0 {
   648  				t.Errorf("expected outpost id header set as %v, got none", e)
   649  			} else {
   650  				t.Errorf("expected %v as Outpost id header value, got %v", e, a)
   651  			}
   652  		}
   653  	})
   654  
   655  	err := req.Send()
   656  	if len(c.expectedErr) == 0 && err != nil {
   657  		t.Errorf("expected no error but got: %v", err)
   658  	} else if len(c.expectedErr) != 0 && err == nil {
   659  		t.Errorf("expected err %q, but got nil", c.expectedErr)
   660  	} else if len(c.expectedErr) != 0 && err != nil && !strings.Contains(err.Error(), c.expectedErr) {
   661  		t.Errorf("expected %v, got %v", c.expectedErr, err.Error())
   662  	}
   663  }
   664  
   665  func TestInputIsNotModified(t *testing.T) {
   666  	inputBucket := "arn:aws:s3-outposts:us-east-1:123456789012:outpost:op-01234567890123456:bucket:mybucket"
   667  	expectedAccountID := "123456789012"
   668  	sess := unit.Session.Copy(&aws.Config{
   669  		Region:         aws.String("us-west-2"),
   670  		S3UseARNRegion: aws.Bool(true),
   671  	})
   672  
   673  	svc := New(sess)
   674  	params := &DeleteBucketInput{
   675  		Bucket: aws.String(inputBucket),
   676  	}
   677  	req, _ := svc.DeleteBucketRequest(params)
   678  
   679  	req.Handlers.Send.Clear()
   680  	req.Handlers.Send.PushBack(func(r *request.Request) {
   681  		defer func() {
   682  			r.HTTPResponse = &http.Response{
   683  				StatusCode:    200,
   684  				ContentLength: 0,
   685  				Body:          ioutil.NopCloser(bytes.NewReader(nil)),
   686  			}
   687  		}()
   688  	})
   689  
   690  	err := req.Send()
   691  	if err != nil {
   692  		t.Fatalf("expected no error, got %v", err)
   693  	}
   694  
   695  	// check if req params were modified
   696  	if e, a := *params.Bucket, inputBucket; !strings.EqualFold(e, a) {
   697  		t.Fatalf("expected no modification for operation input, "+
   698  			"expected %v, got %v as bucket input", e, a)
   699  	}
   700  
   701  	if params.AccountId != nil {
   702  		t.Fatalf("expected original input to be unmodified, but account id was backfilled")
   703  	}
   704  
   705  	modifiedInput, ok := req.Params.(*DeleteBucketInput)
   706  	if !ok {
   707  		t.Fatalf("expected modified input of type *DeleteBucketInput")
   708  	}
   709  
   710  	if modifiedInput.AccountId == nil {
   711  		t.Fatalf("expected AccountID value to be backfilled, was not")
   712  	}
   713  
   714  	if e, a := expectedAccountID, *modifiedInput.AccountId; !strings.EqualFold(e, a) {
   715  		t.Fatalf("expected account id backfilled on request params to be %v, got %v", e, a)
   716  	}
   717  
   718  	if modifiedInput.Bucket == nil {
   719  		t.Fatalf("expected Bucket value to be set, was not")
   720  	}
   721  
   722  	if e, a := "mybucket", *modifiedInput.Bucket; !strings.EqualFold(e, a) {
   723  		t.Fatalf("expected modified input bucket name to be %v, got %v", e, a)
   724  	}
   725  }