mirror of
https://github.com/Luzifer/s3sync.git
synced 2024-12-20 19:41:15 +00:00
Update dependencies, switch to dep for vendoring
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
0339e06989
commit
788bb3fe97
2439 changed files with 1621989 additions and 2997 deletions
152
Godeps/Godeps.json
generated
152
Godeps/Godeps.json
generated
|
@ -1,152 +0,0 @@
|
||||||
{
|
|
||||||
"ImportPath": "github.com/Luzifer/s3sync",
|
|
||||||
"GoVersion": "go1.8",
|
|
||||||
"GodepVersion": "v79",
|
|
||||||
"Packages": [
|
|
||||||
"./..."
|
|
||||||
],
|
|
||||||
"Deps": [
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/request",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/session",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/restxml",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/service/s3",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/aws/aws-sdk-go/service/sts",
|
|
||||||
"Comment": "v1.8.30-1-g26d4122",
|
|
||||||
"Rev": "26d4122e877bd86f43d528ad7fbde237dbbd3fa9"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/go-ini/ini",
|
|
||||||
"Comment": "v1.24.0",
|
|
||||||
"Rev": "e3c2d47c61e5333f9aa2974695dd94396eb69c75"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/inconshreveable/mousetrap",
|
|
||||||
"Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/jmespath/go-jmespath",
|
|
||||||
"Comment": "0.2.2-14-gbd40a43",
|
|
||||||
"Rev": "bd40a432e4c76585ef6b72d3fd96fb9b6dc7b68d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
|
||||||
"Rev": "9c28e4bbd74e5c3ed7aacbc552b2cab7cfdfe744"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
|
||||||
"Rev": "c7e63cf4530bcd3ba943729cee0efeff2ebea63f"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
44
Gopkg.lock
generated
Normal file
44
Gopkg.lock
generated
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/aws/aws-sdk-go"
|
||||||
|
packages = ["aws","aws/awserr","aws/awsutil","aws/client","aws/client/metadata","aws/corehandlers","aws/credentials","aws/credentials/ec2rolecreds","aws/credentials/endpointcreds","aws/credentials/stscreds","aws/defaults","aws/ec2metadata","aws/endpoints","aws/request","aws/session","aws/signer/v4","internal/shareddefaults","private/protocol","private/protocol/query","private/protocol/query/queryutil","private/protocol/rest","private/protocol/restxml","private/protocol/xml/xmlutil","service/s3","service/sts"]
|
||||||
|
revision = "e6c5e190452424b404ecdb81d6e3991d46b18e9d"
|
||||||
|
version = "v1.12.26"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/go-ini/ini"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "f280b3ba517bf5fc98922624f21fb0e7a92adaec"
|
||||||
|
version = "v1.30.3"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/inconshreveable/mousetrap"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||||
|
version = "v1.0"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/jmespath/go-jmespath"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "0b12d6b5"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/spf13/cobra"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
|
||||||
|
version = "v0.0.1"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/spf13/pflag"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
||||||
|
version = "v1.0.0"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "835841c132beb3b9b5687e3deb89497b60510b6d96b2c28d27bd0de1cd37bb53"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
28
Gopkg.toml
Normal file
28
Gopkg.toml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/aws/aws-sdk-go"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/spf13/cobra"
|
14
vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Please fill out the sections below to help us address your issue.
|
||||||
|
|
||||||
|
### Version of AWS SDK for Go?
|
||||||
|
|
||||||
|
|
||||||
|
### Version of Go (`go version`)?
|
||||||
|
|
||||||
|
|
||||||
|
### What issue did you see?
|
||||||
|
|
||||||
|
### Steps to reproduce
|
||||||
|
|
||||||
|
If you have have an runnable example, please include it.
|
||||||
|
|
3
vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
3
vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
For changes to files under the `/model/` folder, and manual edits to autogenerated code (e.g. `/service/s3/api.go`) please create an Issue instead of a PR for those type of changes.
|
||||||
|
|
||||||
|
If there is an existing bug or feature this PR is answers please reference it here.
|
11
vendor/github.com/aws/aws-sdk-go/.gitignore
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
dist
|
||||||
|
/doc
|
||||||
|
/doc-staging
|
||||||
|
.yardoc
|
||||||
|
Gemfile.lock
|
||||||
|
awstesting/integration/smoke/**/importmarker__.go
|
||||||
|
awstesting/integration/smoke/_test/
|
||||||
|
/vendor/bin/
|
||||||
|
/vendor/pkg/
|
||||||
|
/vendor/src/
|
||||||
|
/private/model/cli/gen-api/gen-api
|
14
vendor/github.com/aws/aws-sdk-go/.godoc_config
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/.godoc_config
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"PkgHandler": {
|
||||||
|
"Pattern": "/sdk-for-go/api/",
|
||||||
|
"StripPrefix": "/sdk-for-go/api",
|
||||||
|
"Include": ["/src/github.com/aws/aws-sdk-go/aws", "/src/github.com/aws/aws-sdk-go/service"],
|
||||||
|
"Exclude": ["/src/cmd", "/src/github.com/aws/aws-sdk-go/awstesting", "/src/github.com/aws/aws-sdk-go/awsmigrate"],
|
||||||
|
"IgnoredSuffixes": ["iface"]
|
||||||
|
},
|
||||||
|
"Github": {
|
||||||
|
"Tag": "master",
|
||||||
|
"Repo": "/aws/aws-sdk-go",
|
||||||
|
"UseGithub": true
|
||||||
|
}
|
||||||
|
}
|
29
vendor/github.com/aws/aws-sdk-go/.travis.yml
generated
vendored
Normal file
29
vendor/github.com/aws/aws-sdk-go/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
language: go
|
||||||
|
|
||||||
|
sudo: required
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.5.x
|
||||||
|
- 1.6.x
|
||||||
|
- 1.7.x
|
||||||
|
- 1.8.x
|
||||||
|
- 1.9.x
|
||||||
|
- tip
|
||||||
|
|
||||||
|
# Use Go 1.5's vendoring experiment for 1.5 tests.
|
||||||
|
env:
|
||||||
|
- GO15VENDOREXPERIMENT=1
|
||||||
|
|
||||||
|
install:
|
||||||
|
- make get-deps
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make unit-with-race-cover
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
2188
vendor/github.com/aws/aws-sdk-go/CHANGELOG.md
generated
vendored
Normal file
2188
vendor/github.com/aws/aws-sdk-go/CHANGELOG.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
5
vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md
generated
vendored
Normal file
5
vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
### SDK Features
|
||||||
|
|
||||||
|
### SDK Enhancements
|
||||||
|
|
||||||
|
### SDK Bugs
|
127
vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md
generated
vendored
Normal file
127
vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md
generated
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
Contributing to the AWS SDK for Go
|
||||||
|
|
||||||
|
We work hard to provide a high-quality and useful SDK, and we greatly value
|
||||||
|
feedback and contributions from our community. Whether it's a bug report,
|
||||||
|
new feature, correction, or additional documentation, we welcome your issues
|
||||||
|
and pull requests. Please read through this document before submitting any
|
||||||
|
issues or pull requests to ensure we have all the necessary information to
|
||||||
|
effectively respond to your bug report or contribution.
|
||||||
|
|
||||||
|
|
||||||
|
## Filing Bug Reports
|
||||||
|
|
||||||
|
You can file bug reports against the SDK on the [GitHub issues][issues] page.
|
||||||
|
|
||||||
|
If you are filing a report for a bug or regression in the SDK, it's extremely
|
||||||
|
helpful to provide as much information as possible when opening the original
|
||||||
|
issue. This helps us reproduce and investigate the possible bug without having
|
||||||
|
to wait for this extra information to be provided. Please read the following
|
||||||
|
guidelines prior to filing a bug report.
|
||||||
|
|
||||||
|
1. Search through existing [issues][] to ensure that your specific issue has
|
||||||
|
not yet been reported. If it is a common issue, it is likely there is
|
||||||
|
already a bug report for your problem.
|
||||||
|
|
||||||
|
2. Ensure that you have tested the latest version of the SDK. Although you
|
||||||
|
may have an issue against an older version of the SDK, we cannot provide
|
||||||
|
bug fixes for old versions. It's also possible that the bug may have been
|
||||||
|
fixed in the latest release.
|
||||||
|
|
||||||
|
3. Provide as much information about your environment, SDK version, and
|
||||||
|
relevant dependencies as possible. For example, let us know what version
|
||||||
|
of Go you are using, which and version of the operating system, and the
|
||||||
|
the environment your code is running in. e.g Container.
|
||||||
|
|
||||||
|
4. Provide a minimal test case that reproduces your issue or any error
|
||||||
|
information you related to your problem. We can provide feedback much
|
||||||
|
more quickly if we know what operations you are calling in the SDK. If
|
||||||
|
you cannot provide a full test case, provide as much code as you can
|
||||||
|
to help us diagnose the problem. Any relevant information should be provided
|
||||||
|
as well, like whether this is a persistent issue, or if it only occurs
|
||||||
|
some of the time.
|
||||||
|
|
||||||
|
|
||||||
|
## Submitting Pull Requests
|
||||||
|
|
||||||
|
We are always happy to receive code and documentation contributions to the SDK.
|
||||||
|
Please be aware of the following notes prior to opening a pull request:
|
||||||
|
|
||||||
|
1. The SDK is released under the [Apache license][license]. Any code you submit
|
||||||
|
will be released under that license. For substantial contributions, we may
|
||||||
|
ask you to sign a [Contributor License Agreement (CLA)][cla].
|
||||||
|
|
||||||
|
2. If you would like to implement support for a significant feature that is not
|
||||||
|
yet available in the SDK, please talk to us beforehand to avoid any
|
||||||
|
duplication of effort.
|
||||||
|
|
||||||
|
3. Wherever possible, pull requests should contain tests as appropriate.
|
||||||
|
Bugfixes should contain tests that exercise the corrected behavior (i.e., the
|
||||||
|
test should fail without the bugfix and pass with it), and new features
|
||||||
|
should be accompanied by tests exercising the feature.
|
||||||
|
|
||||||
|
4. Pull requests that contain failing tests will not be merged until the test
|
||||||
|
failures are addressed. Pull requests that cause a significant drop in the
|
||||||
|
SDK's test coverage percentage are unlikely to be merged until tests have
|
||||||
|
been added.
|
||||||
|
|
||||||
|
5. The JSON files under the SDK's `models` folder are sourced from outside the SDK.
|
||||||
|
Such as `models/apis/ec2/2016-11-15/api.json`. We will not accept pull requests
|
||||||
|
directly on these models. If you discover an issue with the models please
|
||||||
|
create a [GitHub issue][issues] describing the issue.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
To run the tests locally, running the `make unit` command will `go get` the
|
||||||
|
SDK's testing dependencies, and run vet, link and unit tests for the SDK.
|
||||||
|
|
||||||
|
```
|
||||||
|
make unit
|
||||||
|
```
|
||||||
|
|
||||||
|
Standard go testing functionality is supported as well. To test SDK code that
|
||||||
|
is tagged with `codegen` you'll need to set the build tag in the go test
|
||||||
|
command. The `make unit` command will do this automatically.
|
||||||
|
|
||||||
|
```
|
||||||
|
go test -tags codegen ./private/...
|
||||||
|
```
|
||||||
|
|
||||||
|
See the `Makefile` for additional testing tags that can be used in testing.
|
||||||
|
|
||||||
|
To test on multiple platform the SDK includes several DockerFiles under the
|
||||||
|
`awstesting/sandbox` folder, and associated make recipes to to execute
|
||||||
|
unit testing within environments configured for specific Go versions.
|
||||||
|
|
||||||
|
```
|
||||||
|
make sandbox-test-go18
|
||||||
|
```
|
||||||
|
|
||||||
|
To run all sandbox environments use the following make recipe
|
||||||
|
|
||||||
|
```
|
||||||
|
# Optionally update the Go tip that will be used during the batch testing
|
||||||
|
make update-aws-golang-tip
|
||||||
|
|
||||||
|
# Run all SDK tests for supported Go versions in sandboxes
|
||||||
|
make sandbox-test
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition the sandbox environment include make recipes for interactive modes
|
||||||
|
so you can run command within the Docker container and context of the SDK.
|
||||||
|
|
||||||
|
```
|
||||||
|
make sandbox-go18
|
||||||
|
```
|
||||||
|
|
||||||
|
### Changelog
|
||||||
|
|
||||||
|
You can see all release changes in the `CHANGELOG.md` file at the root of the
|
||||||
|
repository. The release notes added to this file will contain service client
|
||||||
|
updates, and major SDK changes.
|
||||||
|
|
||||||
|
[issues]: https://github.com/aws/aws-sdk-go/issues
|
||||||
|
[pr]: https://github.com/aws/aws-sdk-go/pulls
|
||||||
|
[license]: http://aws.amazon.com/apache2.0/
|
||||||
|
[cla]: http://en.wikipedia.org/wiki/Contributor_License_Agreement
|
||||||
|
[releasenotes]: https://github.com/aws/aws-sdk-go/releases
|
||||||
|
|
20
vendor/github.com/aws/aws-sdk-go/Gopkg.lock
generated
vendored
Normal file
20
vendor/github.com/aws/aws-sdk-go/Gopkg.lock
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||||
|
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/go-ini/ini"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "300e940a926eb277d3901b20bdfcc54928ad3642"
|
||||||
|
version = "v1.25.4"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
name = "github.com/jmespath/go-jmespath"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "0b12d6b5"
|
||||||
|
|
||||||
|
[solve-meta]
|
||||||
|
analyzer-name = "dep"
|
||||||
|
analyzer-version = 1
|
||||||
|
inputs-digest = "51a86a867df617990082dec6b868e4efe2fdb2ed0e02a3daa93cd30f962b5085"
|
||||||
|
solver-name = "gps-cdcl"
|
||||||
|
solver-version = 1
|
48
vendor/github.com/aws/aws-sdk-go/Gopkg.toml
generated
vendored
Normal file
48
vendor/github.com/aws/aws-sdk-go/Gopkg.toml
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
# Gopkg.toml example
|
||||||
|
#
|
||||||
|
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||||
|
# for detailed Gopkg.toml documentation.
|
||||||
|
#
|
||||||
|
# required = ["github.com/user/thing/cmd/thing"]
|
||||||
|
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project"
|
||||||
|
# version = "1.0.0"
|
||||||
|
#
|
||||||
|
# [[constraint]]
|
||||||
|
# name = "github.com/user/project2"
|
||||||
|
# branch = "dev"
|
||||||
|
# source = "github.com/myfork/project2"
|
||||||
|
#
|
||||||
|
# [[override]]
|
||||||
|
# name = "github.com/x/y"
|
||||||
|
# version = "2.4.0"
|
||||||
|
|
||||||
|
ignored = [
|
||||||
|
# Testing/Example/Codegen dependencies
|
||||||
|
"github.com/stretchr/testify",
|
||||||
|
"github.com/stretchr/testify/assert",
|
||||||
|
"github.com/stretchr/testify/require",
|
||||||
|
"github.com/go-sql-driver/mysql",
|
||||||
|
"github.com/gucumber/gucumber",
|
||||||
|
"github.com/pkg/errors",
|
||||||
|
"golang.org/x/net",
|
||||||
|
"golang.org/x/net/html",
|
||||||
|
"golang.org/x/net/http2",
|
||||||
|
"golang.org/x/text",
|
||||||
|
"golang.org/x/text/html",
|
||||||
|
"golang.org/x/tools",
|
||||||
|
"golang.org/x/tools/go/loader",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/go-ini/ini"
|
||||||
|
version = "1.25.4"
|
||||||
|
|
||||||
|
[[constraint]]
|
||||||
|
name = "github.com/jmespath/go-jmespath"
|
||||||
|
revision = "0b12d6b5"
|
||||||
|
#version = "0.2.2"
|
187
vendor/github.com/aws/aws-sdk-go/Makefile
generated
vendored
Normal file
187
vendor/github.com/aws/aws-sdk-go/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
LINTIGNOREDOT='awstesting/integration.+should not use dot imports'
|
||||||
|
LINTIGNOREDOC='service/[^/]+/(api|service|waiters)\.go:.+(comment on exported|should have comment or be unexported)'
|
||||||
|
LINTIGNORECONST='service/[^/]+/(api|service|waiters)\.go:.+(type|struct field|const|func) ([^ ]+) should be ([^ ]+)'
|
||||||
|
LINTIGNORESTUTTER='service/[^/]+/(api|service)\.go:.+(and that stutters)'
|
||||||
|
LINTIGNOREINFLECT='service/[^/]+/(api|errors|service)\.go:.+(method|const) .+ should be '
|
||||||
|
LINTIGNOREINFLECTS3UPLOAD='service/s3/s3manager/upload\.go:.+struct field SSEKMSKeyId should be '
|
||||||
|
LINTIGNOREDEPS='vendor/.+\.go'
|
||||||
|
LINTIGNOREPKGCOMMENT='service/[^/]+/doc_custom.go:.+package comment should be of the form'
|
||||||
|
UNIT_TEST_TAGS="example codegen awsinclude"
|
||||||
|
|
||||||
|
SDK_WITH_VENDOR_PKGS=$(shell go list -tags ${UNIT_TEST_TAGS} ./... | grep -v "/vendor/src")
|
||||||
|
SDK_ONLY_PKGS=$(shell go list ./... | grep -v "/vendor/")
|
||||||
|
SDK_UNIT_TEST_ONLY_PKGS=$(shell go list -tags ${UNIT_TEST_TAGS} ./... | grep -v "/vendor/")
|
||||||
|
SDK_GO_1_4=$(shell go version | grep "go1.4")
|
||||||
|
SDK_GO_1_5=$(shell go version | grep "go1.5")
|
||||||
|
SDK_GO_VERSION=$(shell go version | awk '''{print $$3}''' | tr -d '''\n''')
|
||||||
|
|
||||||
|
all: get-deps generate unit
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Please use \`make <target>' where <target> is one of"
|
||||||
|
@echo " api_info to print a list of services and versions"
|
||||||
|
@echo " docs to build SDK documentation"
|
||||||
|
@echo " build to go build the SDK"
|
||||||
|
@echo " unit to run unit tests"
|
||||||
|
@echo " integration to run integration tests"
|
||||||
|
@echo " performance to run performance tests"
|
||||||
|
@echo " verify to verify tests"
|
||||||
|
@echo " lint to lint the SDK"
|
||||||
|
@echo " vet to vet the SDK"
|
||||||
|
@echo " generate to go generate and make services"
|
||||||
|
@echo " gen-test to generate protocol tests"
|
||||||
|
@echo " gen-services to generate services"
|
||||||
|
@echo " get-deps to go get the SDK dependencies"
|
||||||
|
@echo " get-deps-tests to get the SDK's test dependencies"
|
||||||
|
@echo " get-deps-verify to get the SDK's verification dependencies"
|
||||||
|
|
||||||
|
generate: gen-test gen-endpoints gen-services
|
||||||
|
|
||||||
|
gen-test: gen-protocol-test
|
||||||
|
|
||||||
|
gen-services:
|
||||||
|
go generate ./service
|
||||||
|
|
||||||
|
gen-protocol-test:
|
||||||
|
go generate ./private/protocol/...
|
||||||
|
|
||||||
|
gen-endpoints:
|
||||||
|
go generate ./models/endpoints/
|
||||||
|
|
||||||
|
build:
|
||||||
|
@echo "go build SDK and vendor packages"
|
||||||
|
@go build ${SDK_ONLY_PKGS}
|
||||||
|
|
||||||
|
unit: get-deps-tests build verify
|
||||||
|
@echo "go test SDK and vendor packages"
|
||||||
|
@go test -tags ${UNIT_TEST_TAGS} $(SDK_UNIT_TEST_ONLY_PKGS)
|
||||||
|
|
||||||
|
unit-with-race-cover: get-deps-tests build verify
|
||||||
|
@echo "go test SDK and vendor packages"
|
||||||
|
@go test -tags ${UNIT_TEST_TAGS} -race -cpu=1,2,4 $(SDK_UNIT_TEST_ONLY_PKGS)
|
||||||
|
|
||||||
|
integration: get-deps-tests integ-custom smoke-tests performance
|
||||||
|
|
||||||
|
integ-custom:
|
||||||
|
go test -tags "integration" ./awstesting/integration/customizations/...
|
||||||
|
|
||||||
|
cleanup-integ:
|
||||||
|
go run -tags "integration" ./awstesting/cmd/bucket_cleanup/main.go "aws-sdk-go-integration"
|
||||||
|
|
||||||
|
smoke-tests: get-deps-tests
|
||||||
|
gucumber -go-tags "integration" ./awstesting/integration/smoke
|
||||||
|
|
||||||
|
performance: get-deps-tests
|
||||||
|
AWS_TESTING_LOG_RESULTS=${log-detailed} AWS_TESTING_REGION=$(region) AWS_TESTING_DB_TABLE=$(table) gucumber -go-tags "integration" ./awstesting/performance
|
||||||
|
|
||||||
|
sandbox-tests: sandbox-test-go15 sandbox-test-go15-novendorexp sandbox-test-go16 sandbox-test-go17 sandbox-test-go18 sandbox-test-go19 sandbox-test-gotip
|
||||||
|
|
||||||
|
sandbox-build-go15:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5 -t "aws-sdk-go-1.5" .
|
||||||
|
sandbox-go15: sandbox-build-go15
|
||||||
|
docker run -i -t aws-sdk-go-1.5 bash
|
||||||
|
sandbox-test-go15: sandbox-build-go15
|
||||||
|
docker run -t aws-sdk-go-1.5
|
||||||
|
|
||||||
|
sandbox-build-go15-novendorexp:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.5-novendorexp -t "aws-sdk-go-1.5-novendorexp" .
|
||||||
|
sandbox-go15-novendorexp: sandbox-build-go15-novendorexp
|
||||||
|
docker run -i -t aws-sdk-go-1.5-novendorexp bash
|
||||||
|
sandbox-test-go15-novendorexp: sandbox-build-go15-novendorexp
|
||||||
|
docker run -t aws-sdk-go-1.5-novendorexp
|
||||||
|
|
||||||
|
sandbox-build-go16:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.6 -t "aws-sdk-go-1.6" .
|
||||||
|
sandbox-go16: sandbox-build-go16
|
||||||
|
docker run -i -t aws-sdk-go-1.6 bash
|
||||||
|
sandbox-test-go16: sandbox-build-go16
|
||||||
|
docker run -t aws-sdk-go-1.6
|
||||||
|
|
||||||
|
sandbox-build-go17:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.7 -t "aws-sdk-go-1.7" .
|
||||||
|
sandbox-go17: sandbox-build-go17
|
||||||
|
docker run -i -t aws-sdk-go-1.7 bash
|
||||||
|
sandbox-test-go17: sandbox-build-go17
|
||||||
|
docker run -t aws-sdk-go-1.7
|
||||||
|
|
||||||
|
sandbox-build-go18:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.8 -t "aws-sdk-go-1.8" .
|
||||||
|
sandbox-go18: sandbox-build-go18
|
||||||
|
docker run -i -t aws-sdk-go-1.8 bash
|
||||||
|
sandbox-test-go18: sandbox-build-go18
|
||||||
|
docker run -t aws-sdk-go-1.8
|
||||||
|
|
||||||
|
sandbox-build-go19:
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.go1.8 -t "aws-sdk-go-1.9" .
|
||||||
|
sandbox-go19: sandbox-build-go19
|
||||||
|
docker run -i -t aws-sdk-go-1.9 bash
|
||||||
|
sandbox-test-go19: sandbox-build-go19
|
||||||
|
docker run -t aws-sdk-go-1.9
|
||||||
|
|
||||||
|
sandbox-build-gotip:
|
||||||
|
@echo "Run make update-aws-golang-tip, if this test fails because missing aws-golang:tip container"
|
||||||
|
docker build -f ./awstesting/sandbox/Dockerfile.test.gotip -t "aws-sdk-go-tip" .
|
||||||
|
sandbox-gotip: sandbox-build-gotip
|
||||||
|
docker run -i -t aws-sdk-go-tip bash
|
||||||
|
sandbox-test-gotip: sandbox-build-gotip
|
||||||
|
docker run -t aws-sdk-go-tip
|
||||||
|
|
||||||
|
update-aws-golang-tip:
|
||||||
|
docker build --no-cache=true -f ./awstesting/sandbox/Dockerfile.golang-tip -t "aws-golang:tip" .
|
||||||
|
|
||||||
|
verify: get-deps-verify lint vet
|
||||||
|
|
||||||
|
lint:
|
||||||
|
@echo "go lint SDK and vendor packages"
|
||||||
|
@lint=`if [ \( -z "${SDK_GO_1_4}" \) -a \( -z "${SDK_GO_1_5}" \) ]; then golint ./...; else echo "skipping golint"; fi`; \
|
||||||
|
lint=`echo "$$lint" | grep -E -v -e ${LINTIGNOREDOT} -e ${LINTIGNOREDOC} -e ${LINTIGNORECONST} -e ${LINTIGNORESTUTTER} -e ${LINTIGNOREINFLECT} -e ${LINTIGNOREDEPS} -e ${LINTIGNOREINFLECTS3UPLOAD} -e ${LINTIGNOREPKGCOMMENT}`; \
|
||||||
|
echo "$$lint"; \
|
||||||
|
if [ "$$lint" != "" ] && [ "$$lint" != "skipping golint" ]; then exit 1; fi
|
||||||
|
|
||||||
|
SDK_BASE_FOLDERS=$(shell ls -d */ | grep -v vendor | grep -v awsmigrate)
|
||||||
|
ifneq (,$(findstring go1.4, ${SDK_GO_VERSION}))
|
||||||
|
GO_VET_CMD=echo skipping go vet, ${SDK_GO_VERSION}
|
||||||
|
else ifneq (,$(findstring go1.6, ${SDK_GO_VERSION}))
|
||||||
|
GO_VET_CMD=go tool vet --all -shadow -example=false
|
||||||
|
else
|
||||||
|
GO_VET_CMD=go tool vet --all -shadow
|
||||||
|
endif
|
||||||
|
|
||||||
|
vet:
|
||||||
|
${GO_VET_CMD} ${SDK_BASE_FOLDERS}
|
||||||
|
|
||||||
|
get-deps: get-deps-tests get-deps-verify
|
||||||
|
@echo "go get SDK dependencies"
|
||||||
|
@go get -v $(SDK_ONLY_PKGS)
|
||||||
|
|
||||||
|
get-deps-tests:
|
||||||
|
@echo "go get SDK testing dependencies"
|
||||||
|
go get github.com/gucumber/gucumber/cmd/gucumber
|
||||||
|
go get github.com/stretchr/testify
|
||||||
|
go get github.com/smartystreets/goconvey
|
||||||
|
go get golang.org/x/net/html
|
||||||
|
go get golang.org/x/net/http2
|
||||||
|
|
||||||
|
get-deps-verify:
|
||||||
|
@echo "go get SDK verification utilities"
|
||||||
|
@if [ \( -z "${SDK_GO_1_4}" \) -a \( -z "${SDK_GO_1_5}" \) ]; then go get github.com/golang/lint/golint; else echo "skipped getting golint"; fi
|
||||||
|
|
||||||
|
bench:
|
||||||
|
@echo "go bench SDK packages"
|
||||||
|
@go test -run NONE -bench . -benchmem -tags 'bench' $(SDK_ONLY_PKGS)
|
||||||
|
|
||||||
|
bench-protocol:
|
||||||
|
@echo "go bench SDK protocol marshallers"
|
||||||
|
@go test -run NONE -bench . -benchmem -tags 'bench' ./private/protocol/...
|
||||||
|
|
||||||
|
docs:
|
||||||
|
@echo "generate SDK docs"
|
||||||
|
@# This env variable, DOCS, is for internal use
|
||||||
|
@if [ -z ${AWS_DOC_GEN_TOOL} ]; then\
|
||||||
|
rm -rf doc && bundle install && bundle exec yard;\
|
||||||
|
else\
|
||||||
|
$(AWS_DOC_GEN_TOOL) `pwd`;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
api_info:
|
||||||
|
@go run private/model/cli/api-info/api-info.go
|
449
vendor/github.com/aws/aws-sdk-go/README.md
generated
vendored
Normal file
449
vendor/github.com/aws/aws-sdk-go/README.md
generated
vendored
Normal file
|
@ -0,0 +1,449 @@
|
||||||
|
[![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api) [![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go) [![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
|
||||||
|
|
||||||
|
# AWS SDK for Go
|
||||||
|
|
||||||
|
aws-sdk-go is the official AWS SDK for the Go programming language.
|
||||||
|
|
||||||
|
Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for information about the latest bug fixes, updates, and features added to the SDK.
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
If you are using Go 1.5 with the `GO15VENDOREXPERIMENT=1` vendoring flag, or 1.6 and higher you can use the following command to retrieve the SDK. The SDK's non-testing dependencies will be included and are vendored in the `vendor` folder.
|
||||||
|
|
||||||
|
go get -u github.com/aws/aws-sdk-go
|
||||||
|
|
||||||
|
Otherwise if your Go environment does not have vendoring support enabled, or you do not want to include the vendored SDK's dependencies you can use the following command to retrieve the SDK and its non-testing dependencies using `go get`.
|
||||||
|
|
||||||
|
go get -u github.com/aws/aws-sdk-go/aws/...
|
||||||
|
go get -u github.com/aws/aws-sdk-go/service/...
|
||||||
|
|
||||||
|
If you're looking to retrieve just the SDK without any dependencies use the following command.
|
||||||
|
|
||||||
|
go get -d github.com/aws/aws-sdk-go/
|
||||||
|
|
||||||
|
These two processes will still include the `vendor` folder and it should be deleted if its not going to be used by your environment.
|
||||||
|
|
||||||
|
rm -rf $GOPATH/src/github.com/aws/aws-sdk-go/vendor
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests.
|
||||||
|
|
||||||
|
* Ask a question on [StackOverflow](http://stackoverflow.com/) and tag it with the [`aws-sdk-go`](http://stackoverflow.com/questions/tagged/aws-sdk-go) tag.
|
||||||
|
* Come join the AWS SDK for Go community chat on [gitter](https://gitter.im/aws/aws-sdk-go).
|
||||||
|
* Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html).
|
||||||
|
* If you think you may have found a bug, please open an [issue](https://github.com/aws/aws-sdk-go/issues/new).
|
||||||
|
|
||||||
|
## Opening Issues
|
||||||
|
|
||||||
|
If you encounter a bug with the AWS SDK for Go we would like to hear about it. Search the [existing issues](https://github.com/aws/aws-sdk-go/issues) and see if others are also experiencing the issue before opening a new issue. Please include the version of AWS SDK for Go, Go language, and OS you’re using. Please also include repro case when appropriate.
|
||||||
|
|
||||||
|
The GitHub issues are intended for bug reports and feature requests. For help and questions with using AWS SDK for GO please make use of the resources listed in the [Getting Help](https://github.com/aws/aws-sdk-go#getting-help) section. Keeping the list of open issues lean will help us respond in a timely manner.
|
||||||
|
|
||||||
|
## Reference Documentation
|
||||||
|
|
||||||
|
[`Getting Started Guide`](https://aws.amazon.com/sdk-for-go/) - This document is a general introduction how to configure and make requests with the SDK. If this is your first time using the SDK, this documentation and the API documentation will help you get started. This document focuses on the syntax and behavior of the SDK. The [Service Developer Guide](https://aws.amazon.com/documentation/) will help you get started using specific AWS services.
|
||||||
|
|
||||||
|
[`SDK API Reference Documentation`](https://docs.aws.amazon.com/sdk-for-go/api/) - Use this document to look up all API operation input and output parameters for AWS services supported by the SDK. The API reference also includes documentation of the SDK, and examples how to using the SDK, service client API operations, and API operation require parameters.
|
||||||
|
|
||||||
|
[`Service Developer Guide`](https://aws.amazon.com/documentation/) - Use this documentation to learn how to interface with an AWS service. These are great guides both, if you're getting started with a service, or looking for more information on a service. You should not need this document for coding, though in some cases, services may supply helpful samples that you might want to look out for.
|
||||||
|
|
||||||
|
[`SDK Examples`](https://github.com/aws/aws-sdk-go/tree/master/example) - Included in the SDK's repo are a several hand crafted examples using the SDK features and AWS services.
|
||||||
|
|
||||||
|
## Overview of SDK's Packages
|
||||||
|
|
||||||
|
The SDK is composed of two main components, SDK core, and service clients.
|
||||||
|
The SDK core packages are all available under the aws package at the root of
|
||||||
|
the SDK. Each client for a supported AWS service is available within its own
|
||||||
|
package under the service folder at the root of the SDK.
|
||||||
|
|
||||||
|
* aws - SDK core, provides common shared types such as Config, Logger,
|
||||||
|
and utilities to make working with API parameters easier.
|
||||||
|
|
||||||
|
* awserr - Provides the error interface that the SDK will use for all
|
||||||
|
errors that occur in the SDK's processing. This includes service API
|
||||||
|
response errors as well. The Error type is made up of a code and message.
|
||||||
|
Cast the SDK's returned error type to awserr.Error and call the Code
|
||||||
|
method to compare returned error to specific error codes. See the package's
|
||||||
|
documentation for additional values that can be extracted such as RequestID.
|
||||||
|
|
||||||
|
* credentials - Provides the types and built in credentials providers
|
||||||
|
the SDK will use to retrieve AWS credentials to make API requests with.
|
||||||
|
Nested under this folder are also additional credentials providers such as
|
||||||
|
stscreds for assuming IAM roles, and ec2rolecreds for EC2 Instance roles.
|
||||||
|
|
||||||
|
* endpoints - Provides the AWS Regions and Endpoints metadata for the SDK.
|
||||||
|
Use this to lookup AWS service endpoint information such as which services
|
||||||
|
are in a region, and what regions a service is in. Constants are also provided
|
||||||
|
for all region identifiers, e.g UsWest2RegionID for "us-west-2".
|
||||||
|
|
||||||
|
* session - Provides initial default configuration, and load
|
||||||
|
configuration from external sources such as environment and shared
|
||||||
|
credentials file.
|
||||||
|
|
||||||
|
* request - Provides the API request sending, and retry logic for the SDK.
|
||||||
|
This package also includes utilities for defining your own request
|
||||||
|
retryer, and configuring how the SDK processes the request.
|
||||||
|
|
||||||
|
* service - Clients for AWS services. All services supported by the SDK are
|
||||||
|
available under this folder.
|
||||||
|
|
||||||
|
## How to Use the SDK's AWS Service Clients
|
||||||
|
|
||||||
|
The SDK includes the Go types and utilities you can use to make requests to
|
||||||
|
AWS service APIs. Within the service folder at the root of the SDK you'll find
|
||||||
|
a package for each AWS service the SDK supports. All service clients follows
|
||||||
|
a common pattern of creation and usage.
|
||||||
|
|
||||||
|
When creating a client for an AWS service you'll first need to have a Session
|
||||||
|
value constructed. The Session provides shared configuration that can be shared
|
||||||
|
between your service clients. When service clients are created you can pass
|
||||||
|
in additional configuration via the aws.Config type to override configuration
|
||||||
|
provided by in the Session to create service client instances with custom
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
Once the service's client is created you can use it to make API requests the
|
||||||
|
AWS service. These clients are safe to use concurrently.
|
||||||
|
|
||||||
|
## Configuring the SDK
|
||||||
|
|
||||||
|
In the AWS SDK for Go, you can configure settings for service clients, such
|
||||||
|
as the log level and maximum number of retries. Most settings are optional;
|
||||||
|
however, for each service client, you must specify a region and your credentials.
|
||||||
|
The SDK uses these values to send requests to the correct AWS region and sign
|
||||||
|
requests with the correct credentials. You can specify these values as part
|
||||||
|
of a session or as environment variables.
|
||||||
|
|
||||||
|
See the SDK's [configuration guide][config_guide] for more information.
|
||||||
|
|
||||||
|
See the [session][session_pkg] package documentation for more information on how to use Session
|
||||||
|
with the SDK.
|
||||||
|
|
||||||
|
See the [Config][config_typ] type in the [aws][aws_pkg] package for more information on configuration
|
||||||
|
options.
|
||||||
|
|
||||||
|
[config_guide]: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html
|
||||||
|
[session_pkg]: https://docs.aws.amazon.com/sdk-for-go/api/aws/session/
|
||||||
|
[config_typ]: https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||||
|
[aws_pkg]: https://docs.aws.amazon.com/sdk-for-go/api/aws/
|
||||||
|
|
||||||
|
### Configuring Credentials
|
||||||
|
|
||||||
|
When using the SDK you'll generally need your AWS credentials to authenticate
|
||||||
|
with AWS services. The SDK supports multiple methods of supporting these
|
||||||
|
credentials. By default the SDK will source credentials automatically from
|
||||||
|
its default credential chain. See the session package for more information
|
||||||
|
on this chain, and how to configure it. The common items in the credential
|
||||||
|
chain are the following:
|
||||||
|
|
||||||
|
* Environment Credentials - Set of environment variables that are useful
|
||||||
|
when sub processes are created for specific roles.
|
||||||
|
|
||||||
|
* Shared Credentials file (~/.aws/credentials) - This file stores your
|
||||||
|
credentials based on a profile name and is useful for local development.
|
||||||
|
|
||||||
|
* EC2 Instance Role Credentials - Use EC2 Instance Role to assign credentials
|
||||||
|
to application running on an EC2 instance. This removes the need to manage
|
||||||
|
credential files in production.
|
||||||
|
|
||||||
|
Credentials can be configured in code as well by setting the Config's Credentials
|
||||||
|
value to a custom provider or using one of the providers included with the
|
||||||
|
SDK to bypass the default credential chain and use a custom one. This is
|
||||||
|
helpful when you want to instruct the SDK to only use a specific set of
|
||||||
|
credentials or providers.
|
||||||
|
|
||||||
|
This example creates a credential provider for assuming an IAM role, "myRoleARN"
|
||||||
|
and configures the S3 service client to use that role for API requests.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Initial credentials loaded from SDK's default credential chain. Such as
|
||||||
|
// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
|
||||||
|
// Role. These credentials will be used to to make the STS Assume Role API.
|
||||||
|
sess := session.Must(session.NewSession())
|
||||||
|
|
||||||
|
// Create the credentials from AssumeRoleProvider to assume the role
|
||||||
|
// referenced by the "myRoleARN" ARN.
|
||||||
|
creds := stscreds.NewCredentials(sess, "myRoleArn")
|
||||||
|
|
||||||
|
// Create service client value configured for credentials
|
||||||
|
// from assumed role.
|
||||||
|
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [credentials][credentials_pkg] package documentation for more information on credential
|
||||||
|
providers included with the SDK, and how to customize the SDK's usage of
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
The SDK has support for the shared configuration file (~/.aws/config). This
|
||||||
|
support can be enabled by setting the environment variable, "AWS_SDK_LOAD_CONFIG=1",
|
||||||
|
or enabling the feature in code when creating a Session via the
|
||||||
|
Option's SharedConfigState parameter.
|
||||||
|
|
||||||
|
```go
|
||||||
|
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
SharedConfigState: session.SharedConfigEnable,
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
[credentials_pkg]: https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials
|
||||||
|
|
||||||
|
### Configuring AWS Region
|
||||||
|
|
||||||
|
In addition to the credentials you'll need to specify the region the SDK
|
||||||
|
will use to make AWS API requests to. In the SDK you can specify the region
|
||||||
|
either with an environment variable, or directly in code when a Session or
|
||||||
|
service client is created. The last value specified in code wins if the region
|
||||||
|
is specified multiple ways.
|
||||||
|
|
||||||
|
To set the region via the environment variable set the "AWS_REGION" to the
|
||||||
|
region you want to the SDK to use. Using this method to set the region will
|
||||||
|
allow you to run your application in multiple regions without needing additional
|
||||||
|
code in the application to select the region.
|
||||||
|
|
||||||
|
AWS_REGION=us-west-2
|
||||||
|
|
||||||
|
The endpoints package includes constants for all regions the SDK knows. The
|
||||||
|
values are all suffixed with RegionID. These values are helpful, because they
|
||||||
|
reduce the need to type the region string manually.
|
||||||
|
|
||||||
|
To set the region on a Session use the aws package's Config struct parameter
|
||||||
|
Region to the AWS region you want the service clients created from the session to
|
||||||
|
use. This is helpful when you want to create multiple service clients, and
|
||||||
|
all of the clients make API requests to the same region.
|
||||||
|
|
||||||
|
```go
|
||||||
|
sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
Region: aws.String(endpoints.UsWest2RegionID),
|
||||||
|
}))
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [endpoints][endpoints_pkg] package for the AWS Regions and Endpoints metadata.
|
||||||
|
|
||||||
|
In addition to setting the region when creating a Session you can also set
|
||||||
|
the region on a per service client bases. This overrides the region of a
|
||||||
|
Session. This is helpful when you want to create service clients in specific
|
||||||
|
regions different from the Session's region.
|
||||||
|
|
||||||
|
```go
|
||||||
|
svc := s3.New(sess, &aws.Config{
|
||||||
|
Region: aws.String(endpoints.UsWest2RegionID),
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
See the [Config][config_typ] type in the [aws][aws_pkg] package for more information and additional
|
||||||
|
options such as setting the Endpoint, and other service client configuration options.
|
||||||
|
|
||||||
|
[endpoints_pkg]: https://docs.aws.amazon.com/sdk-for-go/api/aws/endpoints/
|
||||||
|
|
||||||
|
## Making API Requests
|
||||||
|
|
||||||
|
Once the client is created you can make an API request to the service.
|
||||||
|
Each API method takes a input parameter, and returns the service response
|
||||||
|
and an error. The SDK provides methods for making the API call in multiple ways.
|
||||||
|
|
||||||
|
In this list we'll use the S3 ListObjects API as an example for the different
|
||||||
|
ways of making API requests.
|
||||||
|
|
||||||
|
* ListObjects - Base API operation that will make the API request to the service.
|
||||||
|
|
||||||
|
* ListObjectsRequest - API methods suffixed with Request will construct the
|
||||||
|
API request, but not send it. This is also helpful when you want to get a
|
||||||
|
presigned URL for a request, and share the presigned URL instead of your
|
||||||
|
application making the request directly.
|
||||||
|
|
||||||
|
* ListObjectsPages - Same as the base API operation, but uses a callback to
|
||||||
|
automatically handle pagination of the API's response.
|
||||||
|
|
||||||
|
* ListObjectsWithContext - Same as base API operation, but adds support for
|
||||||
|
the Context pattern. This is helpful for controlling the canceling of in
|
||||||
|
flight requests. See the Go standard library context package for more
|
||||||
|
information. This method also takes request package's Option functional
|
||||||
|
options as the variadic argument for modifying how the request will be
|
||||||
|
made, or extracting information from the raw HTTP response.
|
||||||
|
|
||||||
|
* ListObjectsPagesWithContext - same as ListObjectsPages, but adds support for
|
||||||
|
the Context pattern. Similar to ListObjectsWithContext this method also
|
||||||
|
takes the request package's Option function option types as the variadic
|
||||||
|
argument.
|
||||||
|
|
||||||
|
In addition to the API operations the SDK also includes several higher level
|
||||||
|
methods that abstract checking for and waiting for an AWS resource to be in
|
||||||
|
a desired state. In this list we'll use WaitUntilBucketExists to demonstrate
|
||||||
|
the different forms of waiters.
|
||||||
|
|
||||||
|
* WaitUntilBucketExists. - Method to make API request to query an AWS service for
|
||||||
|
a resource's state. Will return successfully when that state is accomplished.
|
||||||
|
|
||||||
|
* WaitUntilBucketExistsWithContext - Same as WaitUntilBucketExists, but adds
|
||||||
|
support for the Context pattern. In addition these methods take request
|
||||||
|
package's WaiterOptions to configure the waiter, and how underlying request
|
||||||
|
will be made by the SDK.
|
||||||
|
|
||||||
|
The API method will document which error codes the service might return for
|
||||||
|
the operation. These errors will also be available as const strings prefixed
|
||||||
|
with "ErrCode" in the service client's package. If there are no errors listed
|
||||||
|
in the API's SDK documentation you'll need to consult the AWS service's API
|
||||||
|
documentation for the errors that could be returned.
|
||||||
|
|
||||||
|
```go
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
result, err := svc.GetObjectWithContext(ctx, &s3.GetObjectInput{
|
||||||
|
Bucket: aws.String("my-bucket"),
|
||||||
|
Key: aws.String("my-key"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// Cast err to awserr.Error to handle specific error codes.
|
||||||
|
aerr, ok := err.(awserr.Error)
|
||||||
|
if ok && aerr.Code() == s3.ErrCodeNoSuchKey {
|
||||||
|
// Specific error code handling
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure to close the body when done with it for S3 GetObject APIs or
|
||||||
|
// will leak connections.
|
||||||
|
defer result.Body.Close()
|
||||||
|
|
||||||
|
fmt.Println("Object Size:", aws.StringValue(result.ContentLength))
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Request Pagination and Resource Waiters
|
||||||
|
|
||||||
|
Pagination helper methods are suffixed with "Pages", and provide the
|
||||||
|
functionality needed to round trip API page requests. Pagination methods
|
||||||
|
take a callback function that will be called for each page of the API's response.
|
||||||
|
|
||||||
|
```go
|
||||||
|
objects := []string{}
|
||||||
|
err := svc.ListObjectsPagesWithContext(ctx, &s3.ListObjectsInput{
|
||||||
|
Bucket: aws.String(myBucket),
|
||||||
|
}, func(p *s3.ListObjectsOutput, lastPage bool) bool {
|
||||||
|
for _, o := range p.Contents {
|
||||||
|
objects = append(objects, aws.StringValue(o.Key))
|
||||||
|
}
|
||||||
|
return true // continue paging
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("failed to list objects for bucket, %s, %v", myBucket, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Objects in bucket:", objects)
|
||||||
|
```
|
||||||
|
|
||||||
|
Waiter helper methods provide the functionality to wait for an AWS resource
|
||||||
|
state. These methods abstract the logic needed to to check the state of an
|
||||||
|
AWS resource, and wait until that resource is in a desired state. The waiter
|
||||||
|
will block until the resource is in the state that is desired, an error occurs,
|
||||||
|
or the waiter times out. If a resource times out the error code returned will
|
||||||
|
be request.WaiterResourceNotReadyErrorCode.
|
||||||
|
|
||||||
|
```go
|
||||||
|
err := svc.WaitUntilBucketExistsWithContext(ctx, &s3.HeadBucketInput{
|
||||||
|
Bucket: aws.String(myBucket),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
aerr, ok := err.(awserr.Error)
|
||||||
|
if ok && aerr.Code() == request.WaiterResourceNotReadyErrorCode {
|
||||||
|
fmt.Fprintf(os.Stderr, "timed out while waiting for bucket to exist")
|
||||||
|
}
|
||||||
|
panic(fmt.Errorf("failed to wait for bucket to exist, %v", err))
|
||||||
|
}
|
||||||
|
fmt.Println("Bucket", myBucket, "exists")
|
||||||
|
```
|
||||||
|
|
||||||
|
## Complete SDK Example
|
||||||
|
|
||||||
|
This example shows a complete working Go file which will upload a file to S3
|
||||||
|
and use the Context pattern to implement timeout logic that will cancel the
|
||||||
|
request if it takes too long. This example highlights how to use sessions,
|
||||||
|
create a service client, make a request, handle the error, and process the
|
||||||
|
response.
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Uploads a file to S3 given a bucket and object key. Also takes a duration
|
||||||
|
// value to terminate the update if it doesn't complete within that time.
|
||||||
|
//
|
||||||
|
// The AWS Region needs to be provided in the AWS shared config or on the
|
||||||
|
// environment variable as `AWS_REGION`. Credentials also must be provided
|
||||||
|
// Will default to shared config file, but can load from environment if provided.
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// # Upload myfile.txt to myBucket/myKey. Must complete within 10 minutes or will fail
|
||||||
|
// go run withContext.go -b mybucket -k myKey -d 10m < myfile.txt
|
||||||
|
func main() {
|
||||||
|
var bucket, key string
|
||||||
|
var timeout time.Duration
|
||||||
|
|
||||||
|
flag.StringVar(&bucket, "b", "", "Bucket name.")
|
||||||
|
flag.StringVar(&key, "k", "", "Object key name.")
|
||||||
|
flag.DurationVar(&timeout, "d", 0, "Upload timeout.")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// All clients require a Session. The Session provides the client with
|
||||||
|
// shared configuration such as region, endpoint, and credentials. A
|
||||||
|
// Session should be shared where possible to take advantage of
|
||||||
|
// configuration and credential caching. See the session package for
|
||||||
|
// more information.
|
||||||
|
sess := session.Must(session.NewSession())
|
||||||
|
|
||||||
|
// Create a new instance of the service's client with a Session.
|
||||||
|
// Optional aws.Config values can also be provided as variadic arguments
|
||||||
|
// to the New function. This option allows you to provide service
|
||||||
|
// specific configuration.
|
||||||
|
svc := s3.New(sess)
|
||||||
|
|
||||||
|
// Create a context with a timeout that will abort the upload if it takes
|
||||||
|
// more than the passed in timeout.
|
||||||
|
ctx := context.Background()
|
||||||
|
var cancelFn func()
|
||||||
|
if timeout > 0 {
|
||||||
|
ctx, cancelFn = context.WithTimeout(ctx, timeout)
|
||||||
|
}
|
||||||
|
// Ensure the context is canceled to prevent leaking.
|
||||||
|
// See context package for more information, https://golang.org/pkg/context/
|
||||||
|
defer cancelFn()
|
||||||
|
|
||||||
|
// Uploads the object to S3. The Context will interrupt the request if the
|
||||||
|
// timeout expires.
|
||||||
|
_, err := svc.PutObjectWithContext(ctx, &s3.PutObjectInput{
|
||||||
|
Bucket: aws.String(bucket),
|
||||||
|
Key: aws.String(key),
|
||||||
|
Body: os.Stdin,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode {
|
||||||
|
// If the SDK can determine the request or retry delay was canceled
|
||||||
|
// by a context the CanceledErrorCode error code will be returned.
|
||||||
|
fmt.Fprintf(os.Stderr, "upload canceled due to timeout, %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(os.Stderr, "failed to upload object, %v\n", err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This SDK is distributed under the
|
||||||
|
[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),
|
||||||
|
see LICENSE.txt and NOTICE.txt for more information.
|
86
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go
generated
vendored
Normal file
86
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// Package arn provides a parser for interacting with Amazon Resource Names.
|
||||||
|
package arn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
arnDelimiter = ":"
|
||||||
|
arnSections = 6
|
||||||
|
arnPrefix = "arn:"
|
||||||
|
|
||||||
|
// zero-indexed
|
||||||
|
sectionPartition = 1
|
||||||
|
sectionService = 2
|
||||||
|
sectionRegion = 3
|
||||||
|
sectionAccountID = 4
|
||||||
|
sectionResource = 5
|
||||||
|
|
||||||
|
// errors
|
||||||
|
invalidPrefix = "arn: invalid prefix"
|
||||||
|
invalidSections = "arn: not enough sections"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ARN captures the individual fields of an Amazon Resource Name.
|
||||||
|
// See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html for more information.
|
||||||
|
type ARN struct {
|
||||||
|
// The partition that the resource is in. For standard AWS regions, the partition is "aws". If you have resources in
|
||||||
|
// other partitions, the partition is "aws-partitionname". For example, the partition for resources in the China
|
||||||
|
// (Beijing) region is "aws-cn".
|
||||||
|
Partition string
|
||||||
|
|
||||||
|
// The service namespace that identifies the AWS product (for example, Amazon S3, IAM, or Amazon RDS). For a list of
|
||||||
|
// namespaces, see
|
||||||
|
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces.
|
||||||
|
Service string
|
||||||
|
|
||||||
|
// The region the resource resides in. Note that the ARNs for some resources do not require a region, so this
|
||||||
|
// component might be omitted.
|
||||||
|
Region string
|
||||||
|
|
||||||
|
// The ID of the AWS account that owns the resource, without the hyphens. For example, 123456789012. Note that the
|
||||||
|
// ARNs for some resources don't require an account number, so this component might be omitted.
|
||||||
|
AccountID string
|
||||||
|
|
||||||
|
// The content of this part of the ARN varies by service. It often includes an indicator of the type of resource —
|
||||||
|
// for example, an IAM user or Amazon RDS database - followed by a slash (/) or a colon (:), followed by the
|
||||||
|
// resource name itself. Some services allows paths for resource names, as described in
|
||||||
|
// http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-paths.
|
||||||
|
Resource string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse parses an ARN into its constituent parts.
|
||||||
|
//
|
||||||
|
// Some example ARNs:
|
||||||
|
// arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment
|
||||||
|
// arn:aws:iam::123456789012:user/David
|
||||||
|
// arn:aws:rds:eu-west-1:123456789012:db:mysql-db
|
||||||
|
// arn:aws:s3:::my_corporate_bucket/exampleobject.png
|
||||||
|
func Parse(arn string) (ARN, error) {
|
||||||
|
if !strings.HasPrefix(arn, arnPrefix) {
|
||||||
|
return ARN{}, errors.New(invalidPrefix)
|
||||||
|
}
|
||||||
|
sections := strings.SplitN(arn, arnDelimiter, arnSections)
|
||||||
|
if len(sections) != arnSections {
|
||||||
|
return ARN{}, errors.New(invalidSections)
|
||||||
|
}
|
||||||
|
return ARN{
|
||||||
|
Partition: sections[sectionPartition],
|
||||||
|
Service: sections[sectionService],
|
||||||
|
Region: sections[sectionRegion],
|
||||||
|
AccountID: sections[sectionAccountID],
|
||||||
|
Resource: sections[sectionResource],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the canonical representation of the ARN
|
||||||
|
func (arn ARN) String() string {
|
||||||
|
return arnPrefix +
|
||||||
|
arn.Partition + arnDelimiter +
|
||||||
|
arn.Service + arnDelimiter +
|
||||||
|
arn.Region + arnDelimiter +
|
||||||
|
arn.AccountID + arnDelimiter +
|
||||||
|
arn.Resource
|
||||||
|
}
|
90
vendor/github.com/aws/aws-sdk-go/aws/arn/arn_test.go
generated
vendored
Normal file
90
vendor/github.com/aws/aws-sdk-go/aws/arn/arn_test.go
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package arn
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseARN(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
input string
|
||||||
|
arn ARN
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
input: "invalid",
|
||||||
|
err: errors.New(invalidPrefix),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:nope",
|
||||||
|
err: errors.New(invalidSections),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:aws:ecr:us-west-2:123456789012:repository/foo/bar",
|
||||||
|
arn: ARN{
|
||||||
|
Partition: "aws",
|
||||||
|
Service: "ecr",
|
||||||
|
Region: "us-west-2",
|
||||||
|
AccountID: "123456789012",
|
||||||
|
Resource: "repository/foo/bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:aws:elasticbeanstalk:us-east-1:123456789012:environment/My App/MyEnvironment",
|
||||||
|
arn: ARN{
|
||||||
|
Partition: "aws",
|
||||||
|
Service: "elasticbeanstalk",
|
||||||
|
Region: "us-east-1",
|
||||||
|
AccountID: "123456789012",
|
||||||
|
Resource: "environment/My App/MyEnvironment",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:aws:iam::123456789012:user/David",
|
||||||
|
arn: ARN{
|
||||||
|
Partition: "aws",
|
||||||
|
Service: "iam",
|
||||||
|
Region: "",
|
||||||
|
AccountID: "123456789012",
|
||||||
|
Resource: "user/David",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:aws:rds:eu-west-1:123456789012:db:mysql-db",
|
||||||
|
arn: ARN{
|
||||||
|
Partition: "aws",
|
||||||
|
Service: "rds",
|
||||||
|
Region: "eu-west-1",
|
||||||
|
AccountID: "123456789012",
|
||||||
|
Resource: "db:mysql-db",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: "arn:aws:s3:::my_corporate_bucket/exampleobject.png",
|
||||||
|
arn: ARN{
|
||||||
|
Partition: "aws",
|
||||||
|
Service: "s3",
|
||||||
|
Region: "",
|
||||||
|
AccountID: "",
|
||||||
|
Resource: "my_corporate_bucket/exampleobject.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run(tc.input, func(t *testing.T) {
|
||||||
|
spec, err := Parse(tc.input)
|
||||||
|
if tc.arn != spec {
|
||||||
|
t.Errorf("Expected %q to parse as %v, but got %v", tc.input, tc.arn, spec)
|
||||||
|
}
|
||||||
|
if err == nil && tc.err != nil {
|
||||||
|
t.Errorf("Expected err to be %v, but got nil", tc.err)
|
||||||
|
} else if err != nil && tc.err == nil {
|
||||||
|
t.Errorf("Expected err to be nil, but got %v", err)
|
||||||
|
} else if err != nil && tc.err != nil && err.Error() != tc.err.Error() {
|
||||||
|
t.Errorf("Expected err to be %v, but got %v", tc.err, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
353
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go
generated
vendored
Normal file
353
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy_test.go
generated
vendored
Normal file
|
@ -0,0 +1,353 @@
|
||||||
|
package awsutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleCopy() {
|
||||||
|
type Foo struct {
|
||||||
|
A int
|
||||||
|
B []*string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the initial value
|
||||||
|
str1 := "hello"
|
||||||
|
str2 := "bye bye"
|
||||||
|
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
|
||||||
|
|
||||||
|
// Do the copy
|
||||||
|
var f2 Foo
|
||||||
|
awsutil.Copy(&f2, f1)
|
||||||
|
|
||||||
|
// Print the result
|
||||||
|
fmt.Println(awsutil.Prettify(f2))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {
|
||||||
|
// A: 1,
|
||||||
|
// B: ["hello","bye bye"]
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopy1(t *testing.T) {
|
||||||
|
type Bar struct {
|
||||||
|
a *int
|
||||||
|
B *int
|
||||||
|
c int
|
||||||
|
D int
|
||||||
|
}
|
||||||
|
type Foo struct {
|
||||||
|
A int
|
||||||
|
B []*string
|
||||||
|
C map[string]*int
|
||||||
|
D *time.Time
|
||||||
|
E *Bar
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the initial value
|
||||||
|
str1 := "hello"
|
||||||
|
str2 := "bye bye"
|
||||||
|
int1 := 1
|
||||||
|
int2 := 2
|
||||||
|
intPtr1 := 1
|
||||||
|
intPtr2 := 2
|
||||||
|
now := time.Now()
|
||||||
|
f1 := &Foo{
|
||||||
|
A: 1,
|
||||||
|
B: []*string{&str1, &str2},
|
||||||
|
C: map[string]*int{
|
||||||
|
"A": &int1,
|
||||||
|
"B": &int2,
|
||||||
|
},
|
||||||
|
D: &now,
|
||||||
|
E: &Bar{
|
||||||
|
&intPtr1,
|
||||||
|
&intPtr2,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the copy
|
||||||
|
var f2 Foo
|
||||||
|
awsutil.Copy(&f2, f1)
|
||||||
|
|
||||||
|
// Values are equal
|
||||||
|
if v1, v2 := f2.A, f1.A; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B, f1.B; !reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.C, f1.C; !reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.D, f1.D; !v1.Equal(*v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.B, f1.E.B; !reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.D, f1.E.D; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// But pointers are not!
|
||||||
|
str3 := "nothello"
|
||||||
|
int3 := 57
|
||||||
|
f2.A = 100
|
||||||
|
*f2.B[0] = str3
|
||||||
|
*f2.C["B"] = int3
|
||||||
|
*f2.D = time.Now()
|
||||||
|
f2.E.a = &int3
|
||||||
|
*f2.E.B = int3
|
||||||
|
f2.E.c = 5
|
||||||
|
f2.E.D = 5
|
||||||
|
if v1, v2 := f2.A, f1.A; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B, f1.B; reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.C, f1.C; reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.D, f1.D; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.a, f1.E.a; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.B, f1.E.B; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.c, f1.E.c; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.E.D, f1.E.D; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyNestedWithUnexported(t *testing.T) {
|
||||||
|
type Bar struct {
|
||||||
|
a int
|
||||||
|
B int
|
||||||
|
}
|
||||||
|
type Foo struct {
|
||||||
|
A string
|
||||||
|
B Bar
|
||||||
|
}
|
||||||
|
|
||||||
|
f1 := &Foo{A: "string", B: Bar{a: 1, B: 2}}
|
||||||
|
|
||||||
|
var f2 Foo
|
||||||
|
awsutil.Copy(&f2, f1)
|
||||||
|
|
||||||
|
// Values match
|
||||||
|
if v1, v2 := f2.A, f1.A; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B, f1.B; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B.a, f1.B.a; v1 == v2 {
|
||||||
|
t.Errorf("expected values to be not equivalent, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B.B, f2.B.B; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyIgnoreNilMembers(t *testing.T) {
|
||||||
|
type Foo struct {
|
||||||
|
A *string
|
||||||
|
B []string
|
||||||
|
C map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
f := &Foo{}
|
||||||
|
if v1 := f.A; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f.B; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f.C; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var f2 Foo
|
||||||
|
awsutil.Copy(&f2, f)
|
||||||
|
if v1 := f2.A; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f2.B; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f2.C; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fcopy := awsutil.CopyOf(f)
|
||||||
|
f3 := fcopy.(*Foo)
|
||||||
|
if v1 := f3.A; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f3.B; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1 := f3.C; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyPrimitive(t *testing.T) {
|
||||||
|
str := "hello"
|
||||||
|
var s string
|
||||||
|
awsutil.Copy(&s, &str)
|
||||||
|
if v1, v2 := "hello", s; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyNil(t *testing.T) {
|
||||||
|
var s string
|
||||||
|
awsutil.Copy(&s, nil)
|
||||||
|
if v1, v2 := "", s; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyReader(t *testing.T) {
|
||||||
|
var buf io.Reader = bytes.NewReader([]byte("hello world"))
|
||||||
|
var r io.Reader
|
||||||
|
awsutil.Copy(&r, buf)
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if v1, v2 := []byte("hello world"), b; !bytes.Equal(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// empty bytes because this is not a deep copy
|
||||||
|
b, err = ioutil.ReadAll(buf)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if v1, v2 := []byte(""), b; !bytes.Equal(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyDifferentStructs(t *testing.T) {
|
||||||
|
type SrcFoo struct {
|
||||||
|
A int
|
||||||
|
B []*string
|
||||||
|
C map[string]*int
|
||||||
|
SrcUnique string
|
||||||
|
SameNameDiffType int
|
||||||
|
unexportedPtr *int
|
||||||
|
ExportedPtr *int
|
||||||
|
}
|
||||||
|
type DstFoo struct {
|
||||||
|
A int
|
||||||
|
B []*string
|
||||||
|
C map[string]*int
|
||||||
|
DstUnique int
|
||||||
|
SameNameDiffType string
|
||||||
|
unexportedPtr *int
|
||||||
|
ExportedPtr *int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the initial value
|
||||||
|
str1 := "hello"
|
||||||
|
str2 := "bye bye"
|
||||||
|
int1 := 1
|
||||||
|
int2 := 2
|
||||||
|
f1 := &SrcFoo{
|
||||||
|
A: 1,
|
||||||
|
B: []*string{&str1, &str2},
|
||||||
|
C: map[string]*int{
|
||||||
|
"A": &int1,
|
||||||
|
"B": &int2,
|
||||||
|
},
|
||||||
|
SrcUnique: "unique",
|
||||||
|
SameNameDiffType: 1,
|
||||||
|
unexportedPtr: &int1,
|
||||||
|
ExportedPtr: &int2,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the copy
|
||||||
|
var f2 DstFoo
|
||||||
|
awsutil.Copy(&f2, f1)
|
||||||
|
|
||||||
|
// Values are equal
|
||||||
|
if v1, v2 := f2.A, f1.A; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.B, f1.B; !reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := f2.C, f1.C; !reflect.DeepEqual(v1, v2) {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := "unique", f1.SrcUnique; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := 1, f1.SameNameDiffType; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := 0, f2.DstUnique; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := "", f2.SameNameDiffType; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := int1, *f1.unexportedPtr; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1 := f2.unexportedPtr; v1 != nil {
|
||||||
|
t.Errorf("expected nil, but received %v", v1)
|
||||||
|
}
|
||||||
|
if v1, v2 := int2, *f1.ExportedPtr; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
if v1, v2 := int2, *f2.ExportedPtr; v1 != v2 {
|
||||||
|
t.Errorf("expected values to be equivalent but received %v and %v", v1, v2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleCopyOf() {
|
||||||
|
type Foo struct {
|
||||||
|
A int
|
||||||
|
B []*string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the initial value
|
||||||
|
str1 := "hello"
|
||||||
|
str2 := "bye bye"
|
||||||
|
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
|
||||||
|
|
||||||
|
// Do the copy
|
||||||
|
v := awsutil.CopyOf(f1)
|
||||||
|
var f2 *Foo = v.(*Foo)
|
||||||
|
|
||||||
|
// Print the result
|
||||||
|
fmt.Println(awsutil.Prettify(f2))
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// {
|
||||||
|
// A: 1,
|
||||||
|
// B: ["hello","bye bye"]
|
||||||
|
// }
|
||||||
|
}
|
30
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go
generated
vendored
Normal file
30
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal_test.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package awsutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDeepEqual(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
a, b interface{}
|
||||||
|
equal bool
|
||||||
|
}{
|
||||||
|
{"a", "a", true},
|
||||||
|
{"a", "b", false},
|
||||||
|
{"a", aws.String(""), false},
|
||||||
|
{"a", nil, false},
|
||||||
|
{"a", aws.String("a"), true},
|
||||||
|
{(*bool)(nil), (*bool)(nil), true},
|
||||||
|
{(*bool)(nil), (*string)(nil), false},
|
||||||
|
{nil, nil, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
if awsutil.DeepEqual(c.a, c.b) != c.equal {
|
||||||
|
t.Errorf("%d, a:%v b:%v, %t", i, c.a, c.b, c.equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
182
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go
generated
vendored
Normal file
182
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value_test.go
generated
vendored
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
package awsutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Struct struct {
|
||||||
|
A []Struct
|
||||||
|
z []Struct
|
||||||
|
B *Struct
|
||||||
|
D *Struct
|
||||||
|
C string
|
||||||
|
E map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = Struct{
|
||||||
|
A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
|
||||||
|
z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
|
||||||
|
B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
|
||||||
|
C: "initial",
|
||||||
|
}
|
||||||
|
var data2 = Struct{A: []Struct{
|
||||||
|
{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
|
||||||
|
{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
|
||||||
|
}}
|
||||||
|
|
||||||
|
func TestValueAtPathSuccess(t *testing.T) {
|
||||||
|
var testCases = []struct {
|
||||||
|
expect []interface{}
|
||||||
|
data interface{}
|
||||||
|
path string
|
||||||
|
}{
|
||||||
|
{[]interface{}{"initial"}, data, "C"},
|
||||||
|
{[]interface{}{"value1"}, data, "A[0].C"},
|
||||||
|
{[]interface{}{"value2"}, data, "A[1].C"},
|
||||||
|
{[]interface{}{"value3"}, data, "A[2].C"},
|
||||||
|
{[]interface{}{"value3"}, data, "a[2].c"},
|
||||||
|
{[]interface{}{"value3"}, data, "A[-1].C"},
|
||||||
|
{[]interface{}{"value1", "value2", "value3"}, data, "A[].C"},
|
||||||
|
{[]interface{}{"terminal"}, data, "B . B . C"},
|
||||||
|
{[]interface{}{"initial"}, data, "A.D.X || C"},
|
||||||
|
{[]interface{}{"initial"}, data, "A[0].B || C"},
|
||||||
|
{[]interface{}{
|
||||||
|
Struct{A: []Struct{{C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}, {C: "1"}}},
|
||||||
|
Struct{A: []Struct{{C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}, {C: "2"}}},
|
||||||
|
}, data2, "A"},
|
||||||
|
}
|
||||||
|
for i, c := range testCases {
|
||||||
|
v, err := awsutil.ValuesAtPath(c.data, c.path)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("case %v, expected no error, %v", i, c.path)
|
||||||
|
}
|
||||||
|
if e, a := c.expect, v; !awsutil.DeepEqual(e, a) {
|
||||||
|
t.Errorf("case %v, %v", i, c.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValueAtPathFailure(t *testing.T) {
|
||||||
|
var testCases = []struct {
|
||||||
|
expect []interface{}
|
||||||
|
errContains string
|
||||||
|
data interface{}
|
||||||
|
path string
|
||||||
|
}{
|
||||||
|
{nil, "", data, "C.x"},
|
||||||
|
{nil, "SyntaxError: Invalid token: tDot", data, ".x"},
|
||||||
|
{nil, "", data, "X.Y.Z"},
|
||||||
|
{nil, "", data, "A[100].C"},
|
||||||
|
{nil, "", data, "A[3].C"},
|
||||||
|
{nil, "", data, "B.B.C.Z"},
|
||||||
|
{nil, "", data, "z[-1].C"},
|
||||||
|
{nil, "", nil, "A.B.C"},
|
||||||
|
{[]interface{}{}, "", Struct{}, "A"},
|
||||||
|
{nil, "", data, "A[0].B.C"},
|
||||||
|
{nil, "", data, "D"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range testCases {
|
||||||
|
v, err := awsutil.ValuesAtPath(c.data, c.path)
|
||||||
|
if c.errContains != "" {
|
||||||
|
if !strings.Contains(err.Error(), c.errContains) {
|
||||||
|
t.Errorf("case %v, expected error, %v", i, c.path)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("case %v, expected no error, %v", i, c.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if e, a := c.expect, v; !awsutil.DeepEqual(e, a) {
|
||||||
|
t.Errorf("case %v, %v", i, c.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetValueAtPathSuccess(t *testing.T) {
|
||||||
|
var s Struct
|
||||||
|
awsutil.SetValueAtPath(&s, "C", "test1")
|
||||||
|
awsutil.SetValueAtPath(&s, "B.B.C", "test2")
|
||||||
|
awsutil.SetValueAtPath(&s, "B.D.C", "test3")
|
||||||
|
if e, a := "test1", s.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "test2", s.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "test3", s.B.D.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
awsutil.SetValueAtPath(&s, "B.*.C", "test0")
|
||||||
|
if e, a := "test0", s.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "test0", s.B.D.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
var s2 Struct
|
||||||
|
awsutil.SetValueAtPath(&s2, "b.b.c", "test0")
|
||||||
|
if e, a := "test0", s2.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
awsutil.SetValueAtPath(&s2, "A", []Struct{{}})
|
||||||
|
if e, a := []Struct{{}}, s2.A; !awsutil.DeepEqual(e, a) {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
str := "foo"
|
||||||
|
|
||||||
|
s3 := Struct{}
|
||||||
|
awsutil.SetValueAtPath(&s3, "b.b.c", str)
|
||||||
|
if e, a := "foo", s3.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s3 = Struct{B: &Struct{B: &Struct{C: str}}}
|
||||||
|
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
|
||||||
|
if e, a := "", s3.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s3 = Struct{}
|
||||||
|
awsutil.SetValueAtPath(&s3, "b.b.c", nil)
|
||||||
|
if e, a := "", s3.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s3 = Struct{}
|
||||||
|
awsutil.SetValueAtPath(&s3, "b.b.c", &str)
|
||||||
|
if e, a := "foo", s3.B.B.C; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
var s4 struct{ Name *string }
|
||||||
|
awsutil.SetValueAtPath(&s4, "Name", str)
|
||||||
|
if e, a := str, *s4.Name; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s4 = struct{ Name *string }{}
|
||||||
|
awsutil.SetValueAtPath(&s4, "Name", nil)
|
||||||
|
if e, a := (*string)(nil), s4.Name; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s4 = struct{ Name *string }{Name: &str}
|
||||||
|
awsutil.SetValueAtPath(&s4, "Name", nil)
|
||||||
|
if e, a := (*string)(nil), s4.Name; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
s4 = struct{ Name *string }{}
|
||||||
|
awsutil.SetValueAtPath(&s4, "Name", &str)
|
||||||
|
if e, a := str, *s4.Name; e != a {
|
||||||
|
t.Errorf("expected %v, but received %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
78
vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go
generated
vendored
Normal file
78
vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func pushBackTestHandler(name string, list *request.HandlerList) *bool {
|
||||||
|
called := false
|
||||||
|
(*list).PushBackNamed(request.NamedHandler{
|
||||||
|
Name: name,
|
||||||
|
Fn: func(r *request.Request) {
|
||||||
|
called = true
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return &called
|
||||||
|
}
|
||||||
|
|
||||||
|
func pushFrontTestHandler(name string, list *request.HandlerList) *bool {
|
||||||
|
called := false
|
||||||
|
(*list).PushFrontNamed(request.NamedHandler{
|
||||||
|
Name: name,
|
||||||
|
Fn: func(r *request.Request) {
|
||||||
|
called = true
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return &called
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewClient_CopyHandlers(t *testing.T) {
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
firstCalled := pushBackTestHandler("first", &handlers.Send)
|
||||||
|
secondCalled := pushBackTestHandler("second", &handlers.Send)
|
||||||
|
|
||||||
|
var clientHandlerCalled *bool
|
||||||
|
c := New(aws.Config{}, metadata.ClientInfo{}, handlers,
|
||||||
|
func(c *Client) {
|
||||||
|
clientHandlerCalled = pushFrontTestHandler("client handler", &c.Handlers.Send)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if e, a := 2, handlers.Send.Len(); e != a {
|
||||||
|
t.Errorf("expect %d original handlers, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 3, c.Handlers.Send.Len(); e != a {
|
||||||
|
t.Errorf("expect %d client handlers, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers.Send.Run(nil)
|
||||||
|
if !*firstCalled {
|
||||||
|
t.Errorf("expect first handler to of been called")
|
||||||
|
}
|
||||||
|
*firstCalled = false
|
||||||
|
if !*secondCalled {
|
||||||
|
t.Errorf("expect second handler to of been called")
|
||||||
|
}
|
||||||
|
*secondCalled = false
|
||||||
|
if *clientHandlerCalled {
|
||||||
|
t.Errorf("expect client handler to not of been called, but was")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Handlers.Send.Run(nil)
|
||||||
|
if !*firstCalled {
|
||||||
|
t.Errorf("expect client's first handler to of been called")
|
||||||
|
}
|
||||||
|
if !*secondCalled {
|
||||||
|
t.Errorf("expect client's second handler to of been called")
|
||||||
|
}
|
||||||
|
if !*clientHandlerCalled {
|
||||||
|
t.Errorf("expect client's client handler to of been called")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
56
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
56
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
|
@ -2,6 +2,7 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -15,11 +16,11 @@ import (
|
||||||
// the MaxRetries method:
|
// the MaxRetries method:
|
||||||
//
|
//
|
||||||
// type retryer struct {
|
// type retryer struct {
|
||||||
// service.DefaultRetryer
|
// client.DefaultRetryer
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // This implementation always has 100 max retries
|
// // This implementation always has 100 max retries
|
||||||
// func (d retryer) MaxRetries() uint { return 100 }
|
// func (d retryer) MaxRetries() int { return 100 }
|
||||||
type DefaultRetryer struct {
|
type DefaultRetryer struct {
|
||||||
NumMaxRetries int
|
NumMaxRetries int
|
||||||
}
|
}
|
||||||
|
@ -38,6 +39,10 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
||||||
minTime := 30
|
minTime := 30
|
||||||
throttle := d.shouldThrottle(r)
|
throttle := d.shouldThrottle(r)
|
||||||
if throttle {
|
if throttle {
|
||||||
|
if delay, ok := getRetryDelay(r); ok {
|
||||||
|
return delay
|
||||||
|
}
|
||||||
|
|
||||||
minTime = 500
|
minTime = 500
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,12 +73,49 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
||||||
|
|
||||||
// ShouldThrottle returns true if the request should be throttled.
|
// ShouldThrottle returns true if the request should be throttled.
|
||||||
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
||||||
if r.HTTPResponse.StatusCode == 502 ||
|
switch r.HTTPResponse.StatusCode {
|
||||||
r.HTTPResponse.StatusCode == 503 ||
|
case 429:
|
||||||
r.HTTPResponse.StatusCode == 504 {
|
case 502:
|
||||||
return true
|
case 503:
|
||||||
}
|
case 504:
|
||||||
|
default:
|
||||||
return r.IsErrorThrottle()
|
return r.IsErrorThrottle()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will look in the Retry-After header, RFC 7231, for how long
|
||||||
|
// it will wait before attempting another request
|
||||||
|
func getRetryDelay(r *request.Request) (time.Duration, bool) {
|
||||||
|
if !canUseRetryAfterHeader(r) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
delayStr := r.HTTPResponse.Header.Get("Retry-After")
|
||||||
|
if len(delayStr) == 0 {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
delay, err := strconv.Atoi(delayStr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Duration(delay) * time.Second, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will look at the status code to see if the retry header pertains to
|
||||||
|
// the status code.
|
||||||
|
func canUseRetryAfterHeader(r *request.Request) bool {
|
||||||
|
switch r.HTTPResponse.StatusCode {
|
||||||
|
case 429:
|
||||||
|
case 503:
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// lockedSource is a thread-safe implementation of rand.Source
|
// lockedSource is a thread-safe implementation of rand.Source
|
||||||
|
|
166
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer_test.go
generated
vendored
Normal file
166
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer_test.go
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRetryThrottleStatusCodes(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
expectThrottle bool
|
||||||
|
expectRetry bool
|
||||||
|
r request.Request
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 200},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 429},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 502},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 503},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 504},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 500},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
d := DefaultRetryer{NumMaxRetries: 10}
|
||||||
|
for i, c := range cases {
|
||||||
|
throttle := d.shouldThrottle(&c.r)
|
||||||
|
retry := d.ShouldRetry(&c.r)
|
||||||
|
|
||||||
|
if e, a := c.expectThrottle, throttle; e != a {
|
||||||
|
t.Errorf("%d: expected %v, but received %v", i, e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := c.expectRetry, retry; e != a {
|
||||||
|
t.Errorf("%d: expected %v, but received %v", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCanUseRetryAfter(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
r request.Request
|
||||||
|
e bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 200},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 500},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 429},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 503},
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
a := canUseRetryAfterHeader(&c.r)
|
||||||
|
if c.e != a {
|
||||||
|
t.Errorf("%d: expected %v, but received %v", i, c.e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRetryDelay(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
r request.Request
|
||||||
|
e time.Duration
|
||||||
|
equal bool
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 429, Header: http.Header{"Retry-After": []string{"3600"}}},
|
||||||
|
},
|
||||||
|
3600 * time.Second,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 503, Header: http.Header{"Retry-After": []string{"120"}}},
|
||||||
|
},
|
||||||
|
120 * time.Second,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 503, Header: http.Header{"Retry-After": []string{"120"}}},
|
||||||
|
},
|
||||||
|
1 * time.Second,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request.Request{
|
||||||
|
HTTPResponse: &http.Response{StatusCode: 503, Header: http.Header{"Retry-After": []string{""}}},
|
||||||
|
},
|
||||||
|
0 * time.Second,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
a, ok := getRetryDelay(&c.r)
|
||||||
|
if c.ok != ok {
|
||||||
|
t.Errorf("%d: expected %v, but received %v", i, c.ok, ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.e != a) == c.equal {
|
||||||
|
t.Errorf("%d: expected %v, but received %v", i, c.e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
vendor/github.com/aws/aws-sdk-go/aws/client/logger_test.go
generated
vendored
Normal file
57
vendor/github.com/aws/aws-sdk-go/aws/client/logger_test.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockCloser struct {
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (closer *mockCloser) Read(b []byte) (int, error) {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (closer *mockCloser) Close() error {
|
||||||
|
closer.closed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTeeReaderCloser(t *testing.T) {
|
||||||
|
expected := "FOO"
|
||||||
|
buf := bytes.NewBuffer([]byte(expected))
|
||||||
|
lw := bytes.NewBuffer(nil)
|
||||||
|
c := &mockCloser{}
|
||||||
|
closer := teeReaderCloser{
|
||||||
|
io.TeeReader(buf, lw),
|
||||||
|
c,
|
||||||
|
}
|
||||||
|
|
||||||
|
b := make([]byte, len(expected))
|
||||||
|
_, err := closer.Read(b)
|
||||||
|
closer.Close()
|
||||||
|
|
||||||
|
if expected != lw.String() {
|
||||||
|
t.Errorf("Expected %q, but received %q", expected, lw.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Expected 'nil', but received %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.closed {
|
||||||
|
t.Error("Expected 'true', but received 'false'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLogWriter(t *testing.T) {
|
||||||
|
expected := "FOO"
|
||||||
|
lw := &logWriter{nil, bytes.NewBuffer(nil)}
|
||||||
|
lw.Write([]byte(expected))
|
||||||
|
|
||||||
|
if expected != lw.buf.String() {
|
||||||
|
t.Errorf("Expected %q, but received %q", expected, lw.buf.String())
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
|
@ -95,7 +95,7 @@ type Config struct {
|
||||||
// recoverable failures.
|
// recoverable failures.
|
||||||
//
|
//
|
||||||
// When nil or the value does not implement the request.Retryer interface,
|
// When nil or the value does not implement the request.Retryer interface,
|
||||||
// the request.DefaultRetryer will be used.
|
// the client.DefaultRetryer will be used.
|
||||||
//
|
//
|
||||||
// When both Retryer and MaxRetries are non-nil, the former is used and
|
// When both Retryer and MaxRetries are non-nil, the former is used and
|
||||||
// the latter ignored.
|
// the latter ignored.
|
||||||
|
|
86
vendor/github.com/aws/aws-sdk-go/aws/config_test.go
generated
vendored
Normal file
86
vendor/github.com/aws/aws-sdk-go/aws/config_test.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
|
||||||
|
var copyTestConfig = Config{
|
||||||
|
Credentials: testCredentials,
|
||||||
|
Endpoint: String("CopyTestEndpoint"),
|
||||||
|
Region: String("COPY_TEST_AWS_REGION"),
|
||||||
|
DisableSSL: Bool(true),
|
||||||
|
HTTPClient: http.DefaultClient,
|
||||||
|
LogLevel: LogLevel(LogDebug),
|
||||||
|
Logger: NewDefaultLogger(),
|
||||||
|
MaxRetries: Int(3),
|
||||||
|
DisableParamValidation: Bool(true),
|
||||||
|
DisableComputeChecksums: Bool(true),
|
||||||
|
S3ForcePathStyle: Bool(true),
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopy(t *testing.T) {
|
||||||
|
want := copyTestConfig
|
||||||
|
got := copyTestConfig.Copy()
|
||||||
|
if !reflect.DeepEqual(*got, want) {
|
||||||
|
t.Errorf("Copy() = %+v", got)
|
||||||
|
t.Errorf(" want %+v", want)
|
||||||
|
}
|
||||||
|
|
||||||
|
got.Region = String("other")
|
||||||
|
if got.Region == want.Region {
|
||||||
|
t.Errorf("Expect setting copy values not not reflect in source")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCopyReturnsNewInstance(t *testing.T) {
|
||||||
|
want := copyTestConfig
|
||||||
|
got := copyTestConfig.Copy()
|
||||||
|
if got == &want {
|
||||||
|
t.Errorf("Copy() = %p; want different instance as source %p", got, &want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mergeTestZeroValueConfig = Config{}
|
||||||
|
|
||||||
|
var mergeTestConfig = Config{
|
||||||
|
Credentials: testCredentials,
|
||||||
|
Endpoint: String("MergeTestEndpoint"),
|
||||||
|
Region: String("MERGE_TEST_AWS_REGION"),
|
||||||
|
DisableSSL: Bool(true),
|
||||||
|
HTTPClient: http.DefaultClient,
|
||||||
|
LogLevel: LogLevel(LogDebug),
|
||||||
|
Logger: NewDefaultLogger(),
|
||||||
|
MaxRetries: Int(10),
|
||||||
|
DisableParamValidation: Bool(true),
|
||||||
|
DisableComputeChecksums: Bool(true),
|
||||||
|
S3ForcePathStyle: Bool(true),
|
||||||
|
}
|
||||||
|
|
||||||
|
var mergeTests = []struct {
|
||||||
|
cfg *Config
|
||||||
|
in *Config
|
||||||
|
want *Config
|
||||||
|
}{
|
||||||
|
{&Config{}, nil, &Config{}},
|
||||||
|
{&Config{}, &mergeTestZeroValueConfig, &Config{}},
|
||||||
|
{&Config{}, &mergeTestConfig, &mergeTestConfig},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMerge(t *testing.T) {
|
||||||
|
for i, tt := range mergeTests {
|
||||||
|
got := tt.cfg.Copy()
|
||||||
|
got.MergeIn(tt.in)
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Config %d %+v", i, tt.cfg)
|
||||||
|
t.Errorf(" Merge(%+v)", tt.in)
|
||||||
|
t.Errorf(" got %+v", got)
|
||||||
|
t.Errorf(" want %+v", tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
|
@ -4,9 +4,9 @@ package aws
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// An emptyCtx is a copy of the the Go 1.7 context.emptyCtx type. This
|
// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
|
||||||
// is copied to provide a 1.6 and 1.5 safe version of context that is compatible
|
// provide a 1.6 and 1.5 safe version of context that is compatible with Go
|
||||||
// with Go 1.7's Context.
|
// 1.7's Context.
|
||||||
//
|
//
|
||||||
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
||||||
// struct{}, since vars of this type must have distinct addresses.
|
// struct{}, since vars of this type must have distinct addresses.
|
||||||
|
|
37
vendor/github.com/aws/aws-sdk-go/aws/context_test.go
generated
vendored
Normal file
37
vendor/github.com/aws/aws-sdk-go/aws/context_test.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package aws_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSleepWithContext(t *testing.T) {
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
|
||||||
|
err := aws.SleepWithContext(ctx, 1*time.Millisecond)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect context to not be canceled, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSleepWithContext_Canceled(t *testing.T) {
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
|
||||||
|
expectErr := fmt.Errorf("context canceled")
|
||||||
|
|
||||||
|
ctx.Error = expectErr
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
|
||||||
|
err := aws.SleepWithContext(ctx, 1*time.Millisecond)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, did not get one")
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := expectErr, err; e != a {
|
||||||
|
t.Errorf("expect %v error, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
18
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
18
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
|
@ -311,6 +311,24 @@ func TimeValue(v *time.Time) time.Time {
|
||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SecondsTimeValue converts an int64 pointer to a time.Time value
|
||||||
|
// representing seconds since Epoch or time.Time{} if the pointer is nil.
|
||||||
|
func SecondsTimeValue(v *int64) time.Time {
|
||||||
|
if v != nil {
|
||||||
|
return time.Unix((*v / 1000), 0)
|
||||||
|
}
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MillisecondsTimeValue converts an int64 pointer to a time.Time value
|
||||||
|
// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil.
|
||||||
|
func MillisecondsTimeValue(v *int64) time.Time {
|
||||||
|
if v != nil {
|
||||||
|
return time.Unix(0, (*v * 1000000))
|
||||||
|
}
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
||||||
// The result is undefined if the Unix time cannot be represented by an int64.
|
// The result is undefined if the Unix time cannot be represented by an int64.
|
||||||
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
||||||
|
|
641
vendor/github.com/aws/aws-sdk-go/aws/convert_types_test.go
generated
vendored
Normal file
641
vendor/github.com/aws/aws-sdk-go/aws/convert_types_test.go
generated
vendored
Normal file
|
@ -0,0 +1,641 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testCasesStringSlice = [][]string{
|
||||||
|
{"a", "b", "c", "d", "e"},
|
||||||
|
{"a", "b", "", "", "e"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesStringSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := StringSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := StringValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesStringValueSlice = [][]*string{
|
||||||
|
{String("a"), String("b"), nil, String("c")},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesStringValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := StringValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if out[i] != "" {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := StringSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if *(out2[i]) != "" {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *in[i], *out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesStringMap = []map[string]string{
|
||||||
|
{"a": "1", "b": "2", "c": "3"},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStringMap(t *testing.T) {
|
||||||
|
for idx, in := range testCasesStringMap {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := StringMap(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := StringValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesBoolSlice = [][]bool{
|
||||||
|
{true, true, false, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBoolSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesBoolSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := BoolSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := BoolValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesBoolValueSlice = [][]*bool{}
|
||||||
|
|
||||||
|
func TestBoolValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesBoolValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := BoolValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if out[i] {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := BoolSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if *(out2[i]) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := in[i], out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesBoolMap = []map[string]bool{
|
||||||
|
{"a": true, "b": false, "c": true},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBoolMap(t *testing.T) {
|
||||||
|
for idx, in := range testCasesBoolMap {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := BoolMap(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := BoolValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesIntSlice = [][]int{
|
||||||
|
{1, 2, 3, 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesIntSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := IntSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := IntValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesIntValueSlice = [][]*int{}
|
||||||
|
|
||||||
|
func TestIntValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesIntValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := IntValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if out[i] != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := IntSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if *(out2[i]) != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := in[i], out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesIntMap = []map[string]int{
|
||||||
|
{"a": 3, "b": 2, "c": 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIntMap(t *testing.T) {
|
||||||
|
for idx, in := range testCasesIntMap {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := IntMap(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := IntValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesInt64Slice = [][]int64{
|
||||||
|
{1, 2, 3, 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInt64Slice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesInt64Slice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Int64Slice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Int64ValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesInt64ValueSlice = [][]*int64{}
|
||||||
|
|
||||||
|
func TestInt64ValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesInt64ValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Int64ValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if out[i] != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Int64Slice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if *(out2[i]) != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := in[i], out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesInt64Map = []map[string]int64{
|
||||||
|
{"a": 3, "b": 2, "c": 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInt64Map(t *testing.T) {
|
||||||
|
for idx, in := range testCasesInt64Map {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Int64Map(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Int64ValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesFloat64Slice = [][]float64{
|
||||||
|
{1, 2, 3, 4},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFloat64Slice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesFloat64Slice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Float64Slice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Float64ValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesFloat64ValueSlice = [][]*float64{}
|
||||||
|
|
||||||
|
func TestFloat64ValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesFloat64ValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Float64ValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if out[i] != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Float64Slice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if *(out2[i]) != 0 {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := in[i], out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesFloat64Map = []map[string]float64{
|
||||||
|
{"a": 3, "b": 2, "c": 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFloat64Map(t *testing.T) {
|
||||||
|
for idx, in := range testCasesFloat64Map {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := Float64Map(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := Float64ValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesTimeSlice = [][]time.Time{
|
||||||
|
{time.Now(), time.Now().AddDate(100, 0, 0)},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesTimeSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := TimeSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := TimeValueSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesTimeValueSlice = [][]*time.Time{}
|
||||||
|
|
||||||
|
func TestTimeValueSlice(t *testing.T) {
|
||||||
|
for idx, in := range testCasesTimeValueSlice {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := TimeValueSlice(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if in[i] == nil {
|
||||||
|
if !out[i].IsZero() {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := *(in[i]), out[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := TimeSlice(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out2 {
|
||||||
|
if in[i] == nil {
|
||||||
|
if !(*(out2[i])).IsZero() {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := in[i], out2[i]; e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesTimeMap = []map[string]time.Time{
|
||||||
|
{"a": time.Now().AddDate(-100, 0, 0), "b": time.Now()},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeMap(t *testing.T) {
|
||||||
|
for idx, in := range testCasesTimeMap {
|
||||||
|
if in == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
out := TimeMap(in)
|
||||||
|
if e, a := len(out), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
for i := range out {
|
||||||
|
if e, a := in[i], *(out[i]); e != a {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out2 := TimeValueMap(out)
|
||||||
|
if e, a := len(out2), len(in); e != a {
|
||||||
|
t.Errorf("Unexpected len at idx %d", idx)
|
||||||
|
}
|
||||||
|
if e, a := in, out2; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("Unexpected value at idx %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimeValueTestCase struct {
|
||||||
|
in int64
|
||||||
|
outSecs time.Time
|
||||||
|
outMillis time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var testCasesTimeValue = []TimeValueTestCase{
|
||||||
|
{
|
||||||
|
in: int64(1501558289000),
|
||||||
|
outSecs: time.Unix(1501558289, 0),
|
||||||
|
outMillis: time.Unix(1501558289, 0),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
in: int64(1501558289001),
|
||||||
|
outSecs: time.Unix(1501558289, 0),
|
||||||
|
outMillis: time.Unix(1501558289, 1*1000000),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSecondsTimeValue(t *testing.T) {
|
||||||
|
for idx, testCase := range testCasesTimeValue {
|
||||||
|
out := SecondsTimeValue(&testCase.in)
|
||||||
|
if e, a := testCase.outSecs, out; e != a {
|
||||||
|
t.Errorf("Unexpected value for time value at %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMillisecondsTimeValue(t *testing.T) {
|
||||||
|
for idx, testCase := range testCasesTimeValue {
|
||||||
|
out := MillisecondsTimeValue(&testCase.in)
|
||||||
|
if e, a := testCase.outMillis, out; e != a {
|
||||||
|
t.Errorf("Unexpected value for time value at %d", idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_1_8_test.go
generated
vendored
Normal file
64
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_1_8_test.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package corehandlers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSendHandler_HEADNoBody(t *testing.T) {
|
||||||
|
TLSBundleCertFile, TLSBundleKeyFile, TLSBundleCAFile, err := awstesting.CreateTLSBundleFiles()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer awstesting.CleanupTLSBundleFiles(TLSBundleCertFile, TLSBundleKeyFile, TLSBundleCAFile)
|
||||||
|
|
||||||
|
endpoint, err := awstesting.CreateTLSServer(TLSBundleCertFile, TLSBundleKeyFile, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
transport := http.DefaultTransport.(*http.Transport)
|
||||||
|
// test server's certificate is self-signed certificate
|
||||||
|
transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
|
http2.ConfigureTransport(transport)
|
||||||
|
|
||||||
|
sess, err := session.NewSessionWithOptions(session.Options{
|
||||||
|
Config: aws.Config{
|
||||||
|
HTTPClient: &http.Client{},
|
||||||
|
Endpoint: aws.String(endpoint),
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
S3ForcePathStyle: aws.Bool(true),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
svc := s3.New(sess)
|
||||||
|
|
||||||
|
req, _ := svc.HeadObjectRequest(&s3.HeadObjectInput{
|
||||||
|
Bucket: aws.String("bucketname"),
|
||||||
|
Key: aws.String("keyname"),
|
||||||
|
})
|
||||||
|
|
||||||
|
if e, a := request.NoBody, req.HTTPRequest.Body; e != a {
|
||||||
|
t.Fatalf("expect %T request body, got %T", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = req.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, req.HTTPResponse.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
398
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go
generated
vendored
Normal file
398
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go
generated
vendored
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
package corehandlers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidateEndpointHandler(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
svc := awstesting.NewClient(aws.NewConfig().WithRegion("us-west-2"))
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||||
|
|
||||||
|
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
err := req.Build()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateEndpointHandlerErrorRegion(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
svc := awstesting.NewClient()
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||||
|
|
||||||
|
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
err := req.Build()
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expect error, got none")
|
||||||
|
}
|
||||||
|
if e, a := aws.ErrMissingRegion, err; e != a {
|
||||||
|
t.Errorf("expect %v to be %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockCredsProvider struct {
|
||||||
|
expired bool
|
||||||
|
retrieveCalled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockCredsProvider) Retrieve() (credentials.Value, error) {
|
||||||
|
m.retrieveCalled = true
|
||||||
|
return credentials.Value{ProviderName: "mockCredsProvider"}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockCredsProvider) IsExpired() bool {
|
||||||
|
return m.expired
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAfterRetryRefreshCreds(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
credProvider := &mockCredsProvider{}
|
||||||
|
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
Credentials: credentials.NewCredentials(credProvider),
|
||||||
|
MaxRetries: aws.Int(1),
|
||||||
|
})
|
||||||
|
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) {
|
||||||
|
r.Error = awserr.New("UnknownError", "", nil)
|
||||||
|
r.HTTPResponse = &http.Response{StatusCode: 400, Body: ioutil.NopCloser(bytes.NewBuffer([]byte{}))}
|
||||||
|
})
|
||||||
|
svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
||||||
|
r.Error = awserr.New("ExpiredTokenException", "", nil)
|
||||||
|
})
|
||||||
|
svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||||
|
|
||||||
|
if !svc.Config.Credentials.IsExpired() {
|
||||||
|
t.Errorf("Expect to start out expired")
|
||||||
|
}
|
||||||
|
if credProvider.retrieveCalled {
|
||||||
|
t.Errorf("expect not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
req.Send()
|
||||||
|
|
||||||
|
if !svc.Config.Credentials.IsExpired() {
|
||||||
|
t.Errorf("Expect to start out expired")
|
||||||
|
}
|
||||||
|
if credProvider.retrieveCalled {
|
||||||
|
t.Errorf("expect not called")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := svc.Config.Credentials.Get()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if !credProvider.retrieveCalled {
|
||||||
|
t.Errorf("expect not called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAfterRetryWithContextCanceled(t *testing.T) {
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)}
|
||||||
|
req.SetContext(ctx)
|
||||||
|
|
||||||
|
req.Error = fmt.Errorf("some error")
|
||||||
|
req.Retryable = aws.Bool(true)
|
||||||
|
req.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
ctx.Error = fmt.Errorf("context canceled")
|
||||||
|
|
||||||
|
corehandlers.AfterRetryHandler.Fn(req)
|
||||||
|
|
||||||
|
if req.Error == nil {
|
||||||
|
t.Fatalf("expect error but didn't receive one")
|
||||||
|
}
|
||||||
|
|
||||||
|
aerr := req.Error.(awserr.Error)
|
||||||
|
|
||||||
|
if e, a := request.CanceledErrorCode, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q, error code got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAfterRetryWithContext(t *testing.T) {
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)}
|
||||||
|
req.SetContext(ctx)
|
||||||
|
|
||||||
|
req.Error = fmt.Errorf("some error")
|
||||||
|
req.Retryable = aws.Bool(true)
|
||||||
|
req.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
corehandlers.AfterRetryHandler.Fn(req)
|
||||||
|
|
||||||
|
if req.Error != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", req.Error)
|
||||||
|
}
|
||||||
|
if e, a := 1, req.RetryCount; e != a {
|
||||||
|
t.Errorf("expect retry count to be %d, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendWithContextCanceled(t *testing.T) {
|
||||||
|
c := awstesting.NewClient(&aws.Config{
|
||||||
|
SleepDelay: func(dur time.Duration) {
|
||||||
|
t.Errorf("SleepDelay should not be called")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)}
|
||||||
|
req.SetContext(ctx)
|
||||||
|
|
||||||
|
req.Error = fmt.Errorf("some error")
|
||||||
|
req.Retryable = aws.Bool(true)
|
||||||
|
req.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: 500,
|
||||||
|
}
|
||||||
|
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
ctx.Error = fmt.Errorf("context canceled")
|
||||||
|
|
||||||
|
corehandlers.SendHandler.Fn(req)
|
||||||
|
|
||||||
|
if req.Error == nil {
|
||||||
|
t.Fatalf("expect error but didn't receive one")
|
||||||
|
}
|
||||||
|
|
||||||
|
aerr := req.Error.(awserr.Error)
|
||||||
|
|
||||||
|
if e, a := request.CanceledErrorCode, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q, error code got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testSendHandlerTransport struct{}
|
||||||
|
|
||||||
|
func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
|
return nil, fmt.Errorf("mock error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendHandlerError(t *testing.T) {
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Transport: &testSendHandlerTransport{},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||||
|
r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
|
||||||
|
r.Send()
|
||||||
|
|
||||||
|
if r.Error == nil {
|
||||||
|
t.Errorf("expect error, got none")
|
||||||
|
}
|
||||||
|
if r.HTTPResponse == nil {
|
||||||
|
t.Errorf("expect response, got none")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSendWithoutFollowRedirects(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/original":
|
||||||
|
w.Header().Set("Location", "/redirected")
|
||||||
|
w.WriteHeader(301)
|
||||||
|
case "/redirected":
|
||||||
|
t.Fatalf("expect not to redirect, but was")
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
})
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||||
|
|
||||||
|
r := svc.NewRequest(&request.Operation{
|
||||||
|
Name: "Operation",
|
||||||
|
HTTPPath: "/original",
|
||||||
|
}, nil, nil)
|
||||||
|
r.DisableFollowRedirects = true
|
||||||
|
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 301, r.HTTPResponse.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateReqSigHandler(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Req *request.Request
|
||||||
|
Resign bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Req: &request.Request{
|
||||||
|
Config: aws.Config{Credentials: credentials.AnonymousCredentials},
|
||||||
|
Time: time.Now().Add(-15 * time.Minute),
|
||||||
|
},
|
||||||
|
Resign: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Req: &request.Request{
|
||||||
|
Time: time.Now().Add(-15 * time.Minute),
|
||||||
|
},
|
||||||
|
Resign: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Req: &request.Request{
|
||||||
|
Time: time.Now().Add(-1 * time.Minute),
|
||||||
|
},
|
||||||
|
Resign: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
resigned := false
|
||||||
|
c.Req.Handlers.Sign.PushBack(func(r *request.Request) {
|
||||||
|
resigned = true
|
||||||
|
})
|
||||||
|
|
||||||
|
corehandlers.ValidateReqSigHandler.Fn(c.Req)
|
||||||
|
|
||||||
|
if c.Req.Error != nil {
|
||||||
|
t.Errorf("expect no error, got %v", c.Req.Error)
|
||||||
|
}
|
||||||
|
if e, a := c.Resign, resigned; e != a {
|
||||||
|
t.Errorf("%d, expect %v to be %v", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupContentLengthTestServer(t *testing.T, hasContentLength bool, contentLength int64) *httptest.Server {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, ok := r.Header["Content-Length"]
|
||||||
|
if e, a := hasContentLength, ok; e != a {
|
||||||
|
t.Errorf("expect %v to be %v", e, a)
|
||||||
|
}
|
||||||
|
if hasContentLength {
|
||||||
|
if e, a := contentLength, r.ContentLength; e != a {
|
||||||
|
t.Errorf("expect %v to be %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
r.Body.Close()
|
||||||
|
|
||||||
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
if hasContentLength {
|
||||||
|
if e, a := "content-length", authHeader; !strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to be in %v", e, a)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if e, a := "content-length", authHeader; strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to not be in %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := contentLength, int64(len(b)); e != a {
|
||||||
|
t.Errorf("expect %v to be %v", e, a)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildContentLength_ZeroBody(t *testing.T) {
|
||||||
|
server := setupContentLengthTestServer(t, false, 0)
|
||||||
|
|
||||||
|
svc := s3.New(unit.Session, &aws.Config{
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
S3ForcePathStyle: aws.Bool(true),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
})
|
||||||
|
_, err := svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: aws.String("bucketname"),
|
||||||
|
Key: aws.String("keyname"),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildContentLength_NegativeBody(t *testing.T) {
|
||||||
|
server := setupContentLengthTestServer(t, false, 0)
|
||||||
|
|
||||||
|
svc := s3.New(unit.Session, &aws.Config{
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
S3ForcePathStyle: aws.Bool(true),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
})
|
||||||
|
req, _ := svc.GetObjectRequest(&s3.GetObjectInput{
|
||||||
|
Bucket: aws.String("bucketname"),
|
||||||
|
Key: aws.String("keyname"),
|
||||||
|
})
|
||||||
|
|
||||||
|
req.HTTPRequest.Header.Set("Content-Length", "-1")
|
||||||
|
|
||||||
|
if req.Error != nil {
|
||||||
|
t.Errorf("expect no error, got %v", req.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildContentLength_WithBody(t *testing.T) {
|
||||||
|
server := setupContentLengthTestServer(t, true, 1024)
|
||||||
|
|
||||||
|
svc := s3.New(unit.Session, &aws.Config{
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
S3ForcePathStyle: aws.Bool(true),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
})
|
||||||
|
_, err := svc.PutObject(&s3.PutObjectInput{
|
||||||
|
Bucket: aws.String("bucketname"),
|
||||||
|
Key: aws.String("keyname"),
|
||||||
|
Body: bytes.NewReader(make([]byte, 1024)),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
286
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go
generated
vendored
Normal file
286
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator_test.go
generated
vendored
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
package corehandlers_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/kinesis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testSvc = func() *client.Client {
|
||||||
|
s := &client.Client{
|
||||||
|
Config: aws.Config{},
|
||||||
|
ClientInfo: metadata.ClientInfo{
|
||||||
|
ServiceName: "mock-service",
|
||||||
|
APIVersion: "2015-01-01",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}()
|
||||||
|
|
||||||
|
type StructShape struct {
|
||||||
|
_ struct{} `type:"structure"`
|
||||||
|
|
||||||
|
RequiredList []*ConditionalStructShape `required:"true"`
|
||||||
|
RequiredMap map[string]*ConditionalStructShape `required:"true"`
|
||||||
|
RequiredBool *bool `required:"true"`
|
||||||
|
OptionalStruct *ConditionalStructShape
|
||||||
|
|
||||||
|
hiddenParameter *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StructShape) Validate() error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "StructShape"}
|
||||||
|
if s.RequiredList == nil {
|
||||||
|
invalidParams.Add(request.NewErrParamRequired("RequiredList"))
|
||||||
|
}
|
||||||
|
if s.RequiredMap == nil {
|
||||||
|
invalidParams.Add(request.NewErrParamRequired("RequiredMap"))
|
||||||
|
}
|
||||||
|
if s.RequiredBool == nil {
|
||||||
|
invalidParams.Add(request.NewErrParamRequired("RequiredBool"))
|
||||||
|
}
|
||||||
|
if s.RequiredList != nil {
|
||||||
|
for i, v := range s.RequiredList {
|
||||||
|
if v == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RequiredList", i), err.(request.ErrInvalidParams))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.RequiredMap != nil {
|
||||||
|
for i, v := range s.RequiredMap {
|
||||||
|
if v == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := v.Validate(); err != nil {
|
||||||
|
invalidParams.AddNested(fmt.Sprintf("%s[%v]", "RequiredMap", i), err.(request.ErrInvalidParams))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.OptionalStruct != nil {
|
||||||
|
if err := s.OptionalStruct.Validate(); err != nil {
|
||||||
|
invalidParams.AddNested("OptionalStruct", err.(request.ErrInvalidParams))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if invalidParams.Len() > 0 {
|
||||||
|
return invalidParams
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConditionalStructShape struct {
|
||||||
|
_ struct{} `type:"structure"`
|
||||||
|
|
||||||
|
Name *string `required:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ConditionalStructShape) Validate() error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "ConditionalStructShape"}
|
||||||
|
if s.Name == nil {
|
||||||
|
invalidParams.Add(request.NewErrParamRequired("Name"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if invalidParams.Len() > 0 {
|
||||||
|
return invalidParams
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNoErrors(t *testing.T) {
|
||||||
|
input := &StructShape{
|
||||||
|
RequiredList: []*ConditionalStructShape{},
|
||||||
|
RequiredMap: map[string]*ConditionalStructShape{
|
||||||
|
"key1": {Name: aws.String("Name")},
|
||||||
|
"key2": {Name: aws.String("Name")},
|
||||||
|
},
|
||||||
|
RequiredBool: aws.Bool(true),
|
||||||
|
OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")},
|
||||||
|
}
|
||||||
|
|
||||||
|
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||||
|
corehandlers.ValidateParametersHandler.Fn(req)
|
||||||
|
if req.Error != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", req.Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMissingRequiredParameters(t *testing.T) {
|
||||||
|
input := &StructShape{}
|
||||||
|
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||||
|
corehandlers.ValidateParametersHandler.Fn(req)
|
||||||
|
|
||||||
|
if req.Error == nil {
|
||||||
|
t.Fatalf("expect error")
|
||||||
|
}
|
||||||
|
if e, a := "InvalidParameter", req.Error.(awserr.Error).Code(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "3 validation error(s) found.", req.Error.(awserr.Error).Message(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := req.Error.(awserr.BatchedErrors).OrigErrs()
|
||||||
|
if e, a := 3, len(errs); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.RequiredList.", errs[0].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.RequiredMap.", errs[1].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.RequiredBool.", errs[2].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := "InvalidParameter: 3 validation error(s) found.\n- missing required field, StructShape.RequiredList.\n- missing required field, StructShape.RequiredMap.\n- missing required field, StructShape.RequiredBool.\n", req.Error.Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedMissingRequiredParameters(t *testing.T) {
|
||||||
|
input := &StructShape{
|
||||||
|
RequiredList: []*ConditionalStructShape{{}},
|
||||||
|
RequiredMap: map[string]*ConditionalStructShape{
|
||||||
|
"key1": {Name: aws.String("Name")},
|
||||||
|
"key2": {},
|
||||||
|
},
|
||||||
|
RequiredBool: aws.Bool(true),
|
||||||
|
OptionalStruct: &ConditionalStructShape{},
|
||||||
|
}
|
||||||
|
|
||||||
|
req := testSvc.NewRequest(&request.Operation{}, input, nil)
|
||||||
|
corehandlers.ValidateParametersHandler.Fn(req)
|
||||||
|
|
||||||
|
if req.Error == nil {
|
||||||
|
t.Fatalf("expect error")
|
||||||
|
}
|
||||||
|
if e, a := "InvalidParameter", req.Error.(awserr.Error).Code(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "3 validation error(s) found.", req.Error.(awserr.Error).Message(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
errs := req.Error.(awserr.BatchedErrors).OrigErrs()
|
||||||
|
if e, a := 3, len(errs); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.RequiredList[0].Name.", errs[0].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.RequiredMap[key2].Name.", errs[1].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "ParamRequiredError: missing required field, StructShape.OptionalStruct.Name.", errs[2].Error(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testInput struct {
|
||||||
|
StringField *string `min:"5"`
|
||||||
|
ListField []string `min:"3"`
|
||||||
|
MapField map[string]string `min:"4"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s testInput) Validate() error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "testInput"}
|
||||||
|
if s.StringField != nil && len(*s.StringField) < 5 {
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
|
||||||
|
}
|
||||||
|
if s.ListField != nil && len(s.ListField) < 3 {
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
|
||||||
|
}
|
||||||
|
if s.MapField != nil && len(s.MapField) < 4 {
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("MapField", 4))
|
||||||
|
}
|
||||||
|
|
||||||
|
if invalidParams.Len() > 0 {
|
||||||
|
return invalidParams
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var testsFieldMin = []struct {
|
||||||
|
err awserr.Error
|
||||||
|
in testInput
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
err: func() awserr.Error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "testInput"}
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
|
||||||
|
return invalidParams
|
||||||
|
}(),
|
||||||
|
in: testInput{StringField: aws.String("abcd")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: func() awserr.Error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "testInput"}
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
|
||||||
|
return invalidParams
|
||||||
|
}(),
|
||||||
|
in: testInput{StringField: aws.String("abcd"), ListField: []string{"a", "b"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: func() awserr.Error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "testInput"}
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("StringField", 5))
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("ListField", 3))
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("MapField", 4))
|
||||||
|
return invalidParams
|
||||||
|
}(),
|
||||||
|
in: testInput{StringField: aws.String("abcd"), ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
in: testInput{StringField: aws.String("abcde"),
|
||||||
|
ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateFieldMinParameter(t *testing.T) {
|
||||||
|
for i, c := range testsFieldMin {
|
||||||
|
req := testSvc.NewRequest(&request.Operation{}, &c.in, nil)
|
||||||
|
corehandlers.ValidateParametersHandler.Fn(req)
|
||||||
|
|
||||||
|
if e, a := c.err, req.Error; !reflect.DeepEqual(e,a) {
|
||||||
|
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkValidateAny(b *testing.B) {
|
||||||
|
input := &kinesis.PutRecordsInput{
|
||||||
|
StreamName: aws.String("stream"),
|
||||||
|
}
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
record := &kinesis.PutRecordsRequestEntry{
|
||||||
|
Data: make([]byte, 10000),
|
||||||
|
PartitionKey: aws.String("partition"),
|
||||||
|
}
|
||||||
|
input.Records = append(input.Records, record)
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := kinesis.New(unit.Session).PutRecordsRequest(input)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
corehandlers.ValidateParametersHandler.Fn(req)
|
||||||
|
if err := req.Error; err != nil {
|
||||||
|
b.Fatalf("validation failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
154
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go
generated
vendored
Normal file
154
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type secondStubProvider struct {
|
||||||
|
creds Value
|
||||||
|
expired bool
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *secondStubProvider) Retrieve() (Value, error) {
|
||||||
|
s.expired = false
|
||||||
|
s.creds.ProviderName = "secondStubProvider"
|
||||||
|
return s.creds, s.err
|
||||||
|
}
|
||||||
|
func (s *secondStubProvider) IsExpired() bool {
|
||||||
|
return s.expired
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderWithNames(t *testing.T) {
|
||||||
|
p := &ChainProvider{
|
||||||
|
Providers: []Provider{
|
||||||
|
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
|
||||||
|
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
|
||||||
|
&secondStubProvider{
|
||||||
|
creds: Value{
|
||||||
|
AccessKeyID: "AKIF",
|
||||||
|
SecretAccessKey: "NOSECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&stubProvider{
|
||||||
|
creds: Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
assert.Equal(t, "secondStubProvider", creds.ProviderName, "Expect provider name to match")
|
||||||
|
|
||||||
|
// Also check credentials
|
||||||
|
assert.Equal(t, "AKIF", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "NOSECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderGet(t *testing.T) {
|
||||||
|
p := &ChainProvider{
|
||||||
|
Providers: []Provider{
|
||||||
|
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
|
||||||
|
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
|
||||||
|
&stubProvider{
|
||||||
|
creds: Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderIsExpired(t *testing.T) {
|
||||||
|
stubProvider := &stubProvider{expired: true}
|
||||||
|
p := &ChainProvider{
|
||||||
|
Providers: []Provider{
|
||||||
|
stubProvider,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect expired to be true before any Retrieve")
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
|
||||||
|
|
||||||
|
stubProvider.expired = true
|
||||||
|
assert.True(t, p.IsExpired(), "Expect return of expired provider")
|
||||||
|
|
||||||
|
_, err = p.Retrieve()
|
||||||
|
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderWithNoProvider(t *testing.T) {
|
||||||
|
p := &ChainProvider{
|
||||||
|
Providers: []Provider{},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect expired with no providers")
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
assert.Equal(t,
|
||||||
|
ErrNoValidProvidersFoundInChain,
|
||||||
|
err,
|
||||||
|
"Expect no providers error returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderWithNoValidProvider(t *testing.T) {
|
||||||
|
errs := []error{
|
||||||
|
awserr.New("FirstError", "first provider error", nil),
|
||||||
|
awserr.New("SecondError", "second provider error", nil),
|
||||||
|
}
|
||||||
|
p := &ChainProvider{
|
||||||
|
Providers: []Provider{
|
||||||
|
&stubProvider{err: errs[0]},
|
||||||
|
&stubProvider{err: errs[1]},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect expired with no providers")
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
|
||||||
|
assert.Equal(t,
|
||||||
|
ErrNoValidProvidersFoundInChain,
|
||||||
|
err,
|
||||||
|
"Expect no providers error returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChainProviderWithNoValidProviderWithVerboseEnabled(t *testing.T) {
|
||||||
|
errs := []error{
|
||||||
|
awserr.New("FirstError", "first provider error", nil),
|
||||||
|
awserr.New("SecondError", "second provider error", nil),
|
||||||
|
}
|
||||||
|
p := &ChainProvider{
|
||||||
|
VerboseErrors: true,
|
||||||
|
Providers: []Provider{
|
||||||
|
&stubProvider{err: errs[0]},
|
||||||
|
&stubProvider{err: errs[1]},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect expired with no providers")
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
|
||||||
|
assert.Equal(t,
|
||||||
|
awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs),
|
||||||
|
err,
|
||||||
|
"Expect no providers error returned")
|
||||||
|
}
|
73
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go
generated
vendored
Normal file
73
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials_test.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stubProvider struct {
|
||||||
|
creds Value
|
||||||
|
expired bool
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stubProvider) Retrieve() (Value, error) {
|
||||||
|
s.expired = false
|
||||||
|
s.creds.ProviderName = "stubProvider"
|
||||||
|
return s.creds, s.err
|
||||||
|
}
|
||||||
|
func (s *stubProvider) IsExpired() bool {
|
||||||
|
return s.expired
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCredentialsGet(t *testing.T) {
|
||||||
|
c := NewCredentials(&stubProvider{
|
||||||
|
creds: Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
expired: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
creds, err := c.Get()
|
||||||
|
assert.Nil(t, err, "Expected no error")
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCredentialsGetWithError(t *testing.T) {
|
||||||
|
c := NewCredentials(&stubProvider{err: awserr.New("provider error", "", nil), expired: true})
|
||||||
|
|
||||||
|
_, err := c.Get()
|
||||||
|
assert.Equal(t, "provider error", err.(awserr.Error).Code(), "Expected provider error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCredentialsExpire(t *testing.T) {
|
||||||
|
stub := &stubProvider{}
|
||||||
|
c := NewCredentials(stub)
|
||||||
|
|
||||||
|
stub.expired = false
|
||||||
|
assert.True(t, c.IsExpired(), "Expected to start out expired")
|
||||||
|
c.Expire()
|
||||||
|
assert.True(t, c.IsExpired(), "Expected to be expired")
|
||||||
|
|
||||||
|
c.forceRefresh = false
|
||||||
|
assert.False(t, c.IsExpired(), "Expected not to be expired")
|
||||||
|
|
||||||
|
stub.expired = true
|
||||||
|
assert.True(t, c.IsExpired(), "Expected to be expired")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCredentialsGetWithProviderName(t *testing.T) {
|
||||||
|
stub := &stubProvider{}
|
||||||
|
|
||||||
|
c := NewCredentials(stub)
|
||||||
|
|
||||||
|
creds, err := c.Get()
|
||||||
|
assert.Nil(t, err, "Expected no error")
|
||||||
|
assert.Equal(t, creds.ProviderName, "stubProvider", "Expected provider name to match")
|
||||||
|
}
|
159
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go
generated
vendored
Normal file
159
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
package ec2rolecreds_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
const credsRespTmpl = `{
|
||||||
|
"Code": "Success",
|
||||||
|
"Type": "AWS-HMAC",
|
||||||
|
"AccessKeyId" : "accessKey",
|
||||||
|
"SecretAccessKey" : "secret",
|
||||||
|
"Token" : "token",
|
||||||
|
"Expiration" : "%s",
|
||||||
|
"LastUpdated" : "2009-11-23T0:00:00Z"
|
||||||
|
}`
|
||||||
|
|
||||||
|
const credsFailRespTmpl = `{
|
||||||
|
"Code": "ErrorCode",
|
||||||
|
"Message": "ErrorMsg",
|
||||||
|
"LastUpdated": "2009-11-23T0:00:00Z"
|
||||||
|
}`
|
||||||
|
|
||||||
|
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
|
||||||
|
fmt.Fprintln(w, "RoleName")
|
||||||
|
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
|
||||||
|
if failAssume {
|
||||||
|
fmt.Fprintf(w, credsFailRespTmpl)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(w, credsRespTmpl, expireOn)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http.Error(w, "bad request", http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
return server
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEC2RoleProvider(t *testing.T) {
|
||||||
|
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
p := &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error, %v", err)
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEC2RoleProviderFailAssume(t *testing.T) {
|
||||||
|
server := initTestServer("2014-12-16T01:51:37Z", true)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
p := &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Error(t, err, "Expect error")
|
||||||
|
|
||||||
|
e := err.(awserr.Error)
|
||||||
|
assert.Equal(t, "ErrorCode", e.Code())
|
||||||
|
assert.Equal(t, "ErrorMsg", e.Message())
|
||||||
|
assert.Nil(t, e.OrigErr())
|
||||||
|
|
||||||
|
assert.Equal(t, "", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEC2RoleProviderIsExpired(t *testing.T) {
|
||||||
|
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
p := &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||||
|
}
|
||||||
|
p.CurrentTime = func() time.Time {
|
||||||
|
return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||||
|
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error, %v", err)
|
||||||
|
|
||||||
|
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||||
|
|
||||||
|
p.CurrentTime = func() time.Time {
|
||||||
|
return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
|
||||||
|
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
p := &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||||
|
ExpiryWindow: time.Hour * 1,
|
||||||
|
}
|
||||||
|
p.CurrentTime = func() time.Time {
|
||||||
|
return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||||
|
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error, %v", err)
|
||||||
|
|
||||||
|
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||||
|
|
||||||
|
p.CurrentTime = func() time.Time {
|
||||||
|
return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEC3RoleProvider(b *testing.B) {
|
||||||
|
server := initTestServer("2014-12-16T01:51:37Z", false)
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
p := &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")}),
|
||||||
|
}
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := p.Retrieve(); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider_test.go
generated
vendored
Normal file
111
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package endpointcreds_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRetrieveRefreshableCredentials(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, "/path/to/endpoint", r.URL.Path)
|
||||||
|
assert.Equal(t, "application/json", r.Header.Get("Accept"))
|
||||||
|
assert.Equal(t, "else", r.URL.Query().Get("something"))
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
err := encoder.Encode(map[string]interface{}{
|
||||||
|
"AccessKeyID": "AKID",
|
||||||
|
"SecretAccessKey": "SECRET",
|
||||||
|
"Token": "TOKEN",
|
||||||
|
"Expiration": time.Now().Add(1 * time.Hour),
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("failed to write out creds", err)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
client := endpointcreds.NewProviderClient(*unit.Session.Config,
|
||||||
|
unit.Session.Handlers,
|
||||||
|
server.URL+"/path/to/endpoint?something=else",
|
||||||
|
)
|
||||||
|
creds, err := client.Retrieve()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey)
|
||||||
|
assert.Equal(t, "TOKEN", creds.SessionToken)
|
||||||
|
assert.False(t, client.IsExpired())
|
||||||
|
|
||||||
|
client.(*endpointcreds.Provider).CurrentTime = func() time.Time {
|
||||||
|
return time.Now().Add(2 * time.Hour)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, client.IsExpired())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRetrieveStaticCredentials(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
err := encoder.Encode(map[string]interface{}{
|
||||||
|
"AccessKeyID": "AKID",
|
||||||
|
"SecretAccessKey": "SECRET",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("failed to write out creds", err)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
client := endpointcreds.NewProviderClient(*unit.Session.Config, unit.Session.Handlers, server.URL)
|
||||||
|
creds, err := client.Retrieve()
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.False(t, client.IsExpired())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFailedRetrieveCredentials(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(400)
|
||||||
|
encoder := json.NewEncoder(w)
|
||||||
|
err := encoder.Encode(map[string]interface{}{
|
||||||
|
"Code": "Error",
|
||||||
|
"Message": "Message",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("failed to write error", err)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
client := endpointcreds.NewProviderClient(*unit.Session.Config, unit.Session.Handlers, server.URL)
|
||||||
|
creds, err := client.Retrieve()
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
|
||||||
|
assert.Equal(t, "CredentialsEndpointError", aerr.Code())
|
||||||
|
assert.Equal(t, "failed to load credentials", aerr.Message())
|
||||||
|
|
||||||
|
aerr = aerr.OrigErr().(awserr.Error)
|
||||||
|
assert.Equal(t, "Error", aerr.Code())
|
||||||
|
assert.Equal(t, "Message", aerr.Message())
|
||||||
|
|
||||||
|
assert.Empty(t, creds.AccessKeyID)
|
||||||
|
assert.Empty(t, creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.True(t, client.IsExpired())
|
||||||
|
}
|
70
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider_test.go
generated
vendored
Normal file
70
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEnvProviderRetrieve(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||||
|
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||||
|
os.Setenv("AWS_SESSION_TOKEN", "token")
|
||||||
|
|
||||||
|
e := EnvProvider{}
|
||||||
|
creds, err := e.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "access", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvProviderIsExpired(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||||
|
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||||
|
os.Setenv("AWS_SESSION_TOKEN", "token")
|
||||||
|
|
||||||
|
e := EnvProvider{}
|
||||||
|
|
||||||
|
assert.True(t, e.IsExpired(), "Expect creds to be expired before retrieve.")
|
||||||
|
|
||||||
|
_, err := e.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.False(t, e.IsExpired(), "Expect creds to not be expired after retrieve.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvProviderNoAccessKeyID(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_SECRET_ACCESS_KEY", "secret")
|
||||||
|
|
||||||
|
e := EnvProvider{}
|
||||||
|
creds, err := e.Retrieve()
|
||||||
|
assert.Equal(t, ErrAccessKeyIDNotFound, err, "ErrAccessKeyIDNotFound expected, but was %#v error: %#v", creds, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvProviderNoSecretAccessKey(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_ACCESS_KEY_ID", "access")
|
||||||
|
|
||||||
|
e := EnvProvider{}
|
||||||
|
creds, err := e.Retrieve()
|
||||||
|
assert.Equal(t, ErrSecretAccessKeyNotFound, err, "ErrSecretAccessKeyNotFound expected, but was %#v error: %#v", creds, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnvProviderAlternateNames(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_ACCESS_KEY", "access")
|
||||||
|
os.Setenv("AWS_SECRET_KEY", "secret")
|
||||||
|
|
||||||
|
e := EnvProvider{}
|
||||||
|
creds, err := e.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "access", creds.AccessKeyID, "Expected access key ID")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expected secret access key")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expected no token")
|
||||||
|
}
|
5
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/doc_1_7.go
generated
vendored
Normal file
5
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/doc_1_7.go
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
// Package plugincreds provides usage of Go plugins for providing credentials
|
||||||
|
// to the SDK. Only available with Go 1.8 and above.
|
||||||
|
package plugincreds
|
211
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/provider.go
generated
vendored
Normal file
211
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/provider.go
generated
vendored
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
// Package plugincreds implements a credentials provider sourced from a Go
|
||||||
|
// plugin. This package allows you to use a Go plugin to retrieve AWS credentials
|
||||||
|
// for the SDK to use for service API calls.
|
||||||
|
//
|
||||||
|
// As of Go 1.8 plugins are only supported on the Linux platform.
|
||||||
|
//
|
||||||
|
// Plugin Symbol Name
|
||||||
|
//
|
||||||
|
// The "GetAWSSDKCredentialProvider" is the symbol name that will be used to
|
||||||
|
// lookup the credentials provider getter from the plugin. If you want to use a
|
||||||
|
// custom symbol name you should use GetPluginProviderFnsByName to lookup the
|
||||||
|
// symbol by a custom name.
|
||||||
|
//
|
||||||
|
// This symbol is a function that returns two additional functions. One to
|
||||||
|
// retrieve the credentials, and another to determine if the credentials have
|
||||||
|
// expired.
|
||||||
|
//
|
||||||
|
// Plugin Symbol Signature
|
||||||
|
//
|
||||||
|
// The plugin credential provider requires the symbol to match the
|
||||||
|
// following signature.
|
||||||
|
//
|
||||||
|
// func() (RetrieveFn func() (key, secret, token string, err error), IsExpiredFn func() bool)
|
||||||
|
//
|
||||||
|
// Plugin Implementation Exmaple
|
||||||
|
//
|
||||||
|
// The following is an example implementation of a SDK credential provider using
|
||||||
|
// the plugin provider in this package. See the SDK's example/aws/credential/plugincreds/plugin
|
||||||
|
// folder for a runnable example of this.
|
||||||
|
//
|
||||||
|
// package main
|
||||||
|
//
|
||||||
|
// func main() {}
|
||||||
|
//
|
||||||
|
// var myCredProvider provider
|
||||||
|
//
|
||||||
|
// // Build: go build -o plugin.so -buildmode=plugin plugin.go
|
||||||
|
// func init() {
|
||||||
|
// // Initialize a mock credential provider with stubs
|
||||||
|
// myCredProvider = provider{"a","b","c"}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // GetAWSSDKCredentialProvider is the symbol SDK will lookup and use to
|
||||||
|
// // get the credential provider's retrieve and isExpired functions.
|
||||||
|
// func GetAWSSDKCredentialProvider() (func() (key, secret, token string, err error), func() bool) {
|
||||||
|
// return myCredProvider.Retrieve, myCredProvider.IsExpired
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // mock implementation of a type that returns retrieves credentials and
|
||||||
|
// // returns if they have expired.
|
||||||
|
// type provider struct {
|
||||||
|
// key, secret, token string
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func (p provider) Retrieve() (key, secret, token string, err error) {
|
||||||
|
// return p.key, p.secret, p.token, nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func (p *provider) IsExpired() bool {
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Configuring SDK for Plugin Credentials
|
||||||
|
//
|
||||||
|
// To configure the SDK to use a plugin's credential provider you'll need to first
|
||||||
|
// open the plugin file using the plugin standard library package. Once you have
|
||||||
|
// a handle to the plugin you can use the NewCredentials function of this package
|
||||||
|
// to create a new credentials.Credentials value that can be set as the
|
||||||
|
// credentials loader of a Session or Config. See the SDK's example/aws/credential/plugincreds
|
||||||
|
// folder for a runnable example of this.
|
||||||
|
//
|
||||||
|
// // Open plugin, and load it into the process.
|
||||||
|
// p, err := plugin.Open("somefile.so")
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Create a new Credentials value which will source the provider's Retrieve
|
||||||
|
// // and IsExpired functions from the plugin.
|
||||||
|
// creds, err := plugincreds.NewCredentials(p)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Example to configure a Session with the newly created credentials that
|
||||||
|
// // will be sourced using the plugin's functionality.
|
||||||
|
// sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
// Credentials: creds,
|
||||||
|
// }))
|
||||||
|
package plugincreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"plugin"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProviderSymbolName the symbol name the SDK will use to lookup the plugin
|
||||||
|
// provider value from.
|
||||||
|
const ProviderSymbolName = `GetAWSSDKCredentialProvider`
|
||||||
|
|
||||||
|
// ProviderName is the name this credentials provider will label any returned
|
||||||
|
// credentials Value with.
|
||||||
|
const ProviderName = `PluginCredentialsProvider`
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrCodeLookupSymbolError failed to lookup symbol
|
||||||
|
ErrCodeLookupSymbolError = "LookupSymbolError"
|
||||||
|
|
||||||
|
// ErrCodeInvalidSymbolError symbol invalid
|
||||||
|
ErrCodeInvalidSymbolError = "InvalidSymbolError"
|
||||||
|
|
||||||
|
// ErrCodePluginRetrieveNil Retrieve function was nil
|
||||||
|
ErrCodePluginRetrieveNil = "PluginRetrieveNilError"
|
||||||
|
|
||||||
|
// ErrCodePluginIsExpiredNil IsExpired Function was nil
|
||||||
|
ErrCodePluginIsExpiredNil = "PluginIsExpiredNilError"
|
||||||
|
|
||||||
|
// ErrCodePluginProviderRetrieve plugin provider's retrieve returned error
|
||||||
|
ErrCodePluginProviderRetrieve = "PluginProviderRetrieveError"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Provider is the credentials provider that will use the plugin provided
|
||||||
|
// Retrieve and IsExpired functions to retrieve credentials.
|
||||||
|
type Provider struct {
|
||||||
|
RetrieveFn func() (key, secret, token string, err error)
|
||||||
|
IsExpiredFn func() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCredentials returns a new Credentials loader using the plugin provider.
|
||||||
|
// If the symbol isn't found or is invalid in the plugin an error will be
|
||||||
|
// returned.
|
||||||
|
func NewCredentials(p *plugin.Plugin) (*credentials.Credentials, error) {
|
||||||
|
retrieve, isExpired, err := GetPluginProviderFns(p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials.NewCredentials(Provider{
|
||||||
|
RetrieveFn: retrieve,
|
||||||
|
IsExpiredFn: isExpired,
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve will return the credentials Value if they were successfully retrieved
|
||||||
|
// from the underlying plugin provider. An error will be returned otherwise.
|
||||||
|
func (p Provider) Retrieve() (credentials.Value, error) {
|
||||||
|
creds := credentials.Value{
|
||||||
|
ProviderName: ProviderName,
|
||||||
|
}
|
||||||
|
|
||||||
|
k, s, t, err := p.RetrieveFn()
|
||||||
|
if err != nil {
|
||||||
|
return creds, awserr.New(ErrCodePluginProviderRetrieve,
|
||||||
|
"failed to retrieve credentials with plugin provider", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
creds.AccessKeyID = k
|
||||||
|
creds.SecretAccessKey = s
|
||||||
|
creds.SessionToken = t
|
||||||
|
|
||||||
|
return creds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExpired will return the expired state of the underlying plugin provider.
|
||||||
|
func (p Provider) IsExpired() bool {
|
||||||
|
return p.IsExpiredFn()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPluginProviderFns returns the plugin's Retrieve and IsExpired functions
|
||||||
|
// returned by the plugin's credential provider getter.
|
||||||
|
//
|
||||||
|
// Uses ProviderSymbolName as the symbol name when lookup up the symbol. If you
|
||||||
|
// want to use a different symbol name, use GetPluginProviderFnsByName.
|
||||||
|
func GetPluginProviderFns(p *plugin.Plugin) (func() (key, secret, token string, err error), func() bool, error) {
|
||||||
|
return GetPluginProviderFnsByName(p, ProviderSymbolName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPluginProviderFnsByName returns the plugin's Retrieve and IsExpired functions
|
||||||
|
// returned by the plugin's credential provider getter.
|
||||||
|
//
|
||||||
|
// Same as GetPluginProviderFns, but takes a custom symbolName to lookup with.
|
||||||
|
func GetPluginProviderFnsByName(p *plugin.Plugin, symbolName string) (func() (key, secret, token string, err error), func() bool, error) {
|
||||||
|
sym, err := p.Lookup(symbolName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, awserr.New(ErrCodeLookupSymbolError,
|
||||||
|
fmt.Sprintf("failed to lookup %s plugin provider symbol", symbolName), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn, ok := sym.(func() (func() (key, secret, token string, err error), func() bool))
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, awserr.New(ErrCodeInvalidSymbolError,
|
||||||
|
fmt.Sprintf("symbol %T, does not match the 'func() (func() (key, secret, token string, err error), func() bool)' type", sym), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieveFn, isExpiredFn := fn()
|
||||||
|
if retrieveFn == nil {
|
||||||
|
return nil, nil, awserr.New(ErrCodePluginRetrieveNil,
|
||||||
|
"the plugin provider retrieve function cannot be nil", nil)
|
||||||
|
}
|
||||||
|
if isExpiredFn == nil {
|
||||||
|
return nil, nil, awserr.New(ErrCodePluginIsExpiredNil,
|
||||||
|
"the plugin provider isExpired function cannot be nil", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return retrieveFn, isExpiredFn, nil
|
||||||
|
}
|
71
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/provider_test.go
generated
vendored
Normal file
71
vendor/github.com/aws/aws-sdk-go/aws/credentials/plugincreds/provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
// +build go1.8,awsinclude
|
||||||
|
|
||||||
|
package plugincreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestProvider_Passthrough(t *testing.T) {
|
||||||
|
p := Provider{
|
||||||
|
RetrieveFn: func() (string, string, string, error) {
|
||||||
|
return "key", "secret", "token", nil
|
||||||
|
},
|
||||||
|
IsExpiredFn: func() bool {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := p.Retrieve()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expect := credentials.Value{
|
||||||
|
AccessKeyID: "key",
|
||||||
|
SecretAccessKey: "secret",
|
||||||
|
SessionToken: "token",
|
||||||
|
ProviderName: ProviderName,
|
||||||
|
}
|
||||||
|
if expect != actual {
|
||||||
|
t.Errorf("expect %+v credentials, got %+v", expect, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProvider_Error(t *testing.T) {
|
||||||
|
expectErr := fmt.Errorf("expect error")
|
||||||
|
|
||||||
|
p := Provider{
|
||||||
|
RetrieveFn: func() (string, string, string, error) {
|
||||||
|
return "", "", "", expectErr
|
||||||
|
},
|
||||||
|
IsExpiredFn: func() bool {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := p.Retrieve()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := ErrCodePluginProviderRetrieve, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %s error code, got %s", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := expectErr, aerr.OrigErr(); e != a {
|
||||||
|
t.Errorf("expect %v cause error, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
expect := credentials.Value{
|
||||||
|
ProviderName: ProviderName,
|
||||||
|
}
|
||||||
|
if expect != actual {
|
||||||
|
t.Errorf("expect %+v credentials, got %+v", expect, actual)
|
||||||
|
}
|
||||||
|
}
|
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
|
@ -3,11 +3,11 @@ package credentials
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/go-ini/ini"
|
"github.com/go-ini/ini"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SharedCredsProviderName provides a name of SharedCreds provider
|
// SharedCredsProviderName provides a name of SharedCreds provider
|
||||||
|
@ -15,8 +15,6 @@ const SharedCredsProviderName = "SharedCredentialsProvider"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
||||||
//
|
|
||||||
// @readonly
|
|
||||||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -117,21 +115,22 @@ func loadProfile(filename, profile string) (Value, error) {
|
||||||
//
|
//
|
||||||
// Will return an error if the user's home directory path cannot be found.
|
// Will return an error if the user's home directory path cannot be found.
|
||||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
func (p *SharedCredentialsProvider) filename() (string, error) {
|
||||||
if p.Filename == "" {
|
if len(p.Filename) != 0 {
|
||||||
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" {
|
|
||||||
return p.Filename, nil
|
return p.Filename, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
homeDir := os.Getenv("HOME") // *nix
|
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
|
||||||
if homeDir == "" { // Windows
|
return p.Filename, nil
|
||||||
homeDir = os.Getenv("USERPROFILE")
|
|
||||||
}
|
}
|
||||||
if homeDir == "" {
|
|
||||||
|
if home := shareddefaults.UserHomeDir(); len(home) == 0 {
|
||||||
|
// Backwards compatibility of home directly not found error being returned.
|
||||||
|
// This error is too verbose, failure when opening the file would of been
|
||||||
|
// a better error to return.
|
||||||
return "", ErrSharedCredentialsHomeNotFound
|
return "", ErrSharedCredentialsHomeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
|
p.Filename = shareddefaults.SharedCredentialsFilename()
|
||||||
}
|
|
||||||
|
|
||||||
return p.Filename, nil
|
return p.Filename, nil
|
||||||
}
|
}
|
||||||
|
|
136
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go
generated
vendored
Normal file
136
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSharedCredentialsProvider(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderIsExpired(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||||
|
|
||||||
|
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve")
|
||||||
|
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILE(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "example.ini")
|
||||||
|
p := SharedCredentialsProvider{}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderWithAWS_SHARED_CREDENTIALS_FILEAbsPath(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", filepath.Join(wd, "example.ini"))
|
||||||
|
p := SharedCredentialsProvider{}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderWithAWS_PROFILE(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("AWS_PROFILE", "no_token")
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderWithoutTokenFromProfile(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "no_token"}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProviderColonInCredFile(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: "with_colon"}
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect no token")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedCredentialsProvider_DefaultFilename(t *testing.T) {
|
||||||
|
os.Clearenv()
|
||||||
|
os.Setenv("USERPROFILE", "profile_dir")
|
||||||
|
os.Setenv("HOME", "home_dir")
|
||||||
|
|
||||||
|
// default filename and profile
|
||||||
|
p := SharedCredentialsProvider{}
|
||||||
|
|
||||||
|
filename, err := p.filename()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := shareddefaults.SharedCredentialsFilename(), filename; e != a {
|
||||||
|
t.Errorf("expect %q filename, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSharedCredentialsProvider(b *testing.B) {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
p := SharedCredentialsProvider{Filename: "example.ini", Profile: ""}
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := p.Retrieve()
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider_test.go
generated
vendored
Normal file
34
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package credentials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStaticProviderGet(t *testing.T) {
|
||||||
|
s := StaticProvider{
|
||||||
|
Value: Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := s.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Empty(t, creds.SessionToken, "Expect no session token")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStaticProviderIsExpired(t *testing.T) {
|
||||||
|
s := StaticProvider{
|
||||||
|
Value: Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.False(t, s.IsExpired(), "Expect static credentials to never expire")
|
||||||
|
}
|
150
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go
generated
vendored
Normal file
150
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
package stscreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sts"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stubSTS struct {
|
||||||
|
TestInput func(*sts.AssumeRoleInput)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stubSTS) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
|
||||||
|
if s.TestInput != nil {
|
||||||
|
s.TestInput(input)
|
||||||
|
}
|
||||||
|
expiry := time.Now().Add(60 * time.Minute)
|
||||||
|
return &sts.AssumeRoleOutput{
|
||||||
|
Credentials: &sts.Credentials{
|
||||||
|
// Just reflect the role arn to the provider.
|
||||||
|
AccessKeyId: input.RoleArn,
|
||||||
|
SecretAccessKey: aws.String("assumedSecretAccessKey"),
|
||||||
|
SessionToken: aws.String("assumedSessionToken"),
|
||||||
|
Expiration: &expiry,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssumeRoleProvider(t *testing.T) {
|
||||||
|
stub := &stubSTS{}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN")
|
||||||
|
assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssumeRoleProvider_WithTokenCode(t *testing.T) {
|
||||||
|
stub := &stubSTS{
|
||||||
|
TestInput: func(in *sts.AssumeRoleInput) {
|
||||||
|
assert.Equal(t, "0123456789", *in.SerialNumber)
|
||||||
|
assert.Equal(t, "code", *in.TokenCode)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
SerialNumber: aws.String("0123456789"),
|
||||||
|
TokenCode: aws.String("code"),
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN")
|
||||||
|
assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssumeRoleProvider_WithTokenProvider(t *testing.T) {
|
||||||
|
stub := &stubSTS{
|
||||||
|
TestInput: func(in *sts.AssumeRoleInput) {
|
||||||
|
assert.Equal(t, "0123456789", *in.SerialNumber)
|
||||||
|
assert.Equal(t, "code", *in.TokenCode)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
SerialNumber: aws.String("0123456789"),
|
||||||
|
TokenProvider: func() (string, error) {
|
||||||
|
return "code", nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Nil(t, err, "Expect no error")
|
||||||
|
|
||||||
|
assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN")
|
||||||
|
assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match")
|
||||||
|
assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssumeRoleProvider_WithTokenProviderError(t *testing.T) {
|
||||||
|
stub := &stubSTS{
|
||||||
|
TestInput: func(in *sts.AssumeRoleInput) {
|
||||||
|
assert.Fail(t, "API request should not of been called")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
SerialNumber: aws.String("0123456789"),
|
||||||
|
TokenProvider: func() (string, error) {
|
||||||
|
return "", fmt.Errorf("error occurred")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
assert.Empty(t, creds.AccessKeyID)
|
||||||
|
assert.Empty(t, creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAssumeRoleProvider_MFAWithNoToken(t *testing.T) {
|
||||||
|
stub := &stubSTS{
|
||||||
|
TestInput: func(in *sts.AssumeRoleInput) {
|
||||||
|
assert.Fail(t, "API request should not of been called")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
SerialNumber: aws.String("0123456789"),
|
||||||
|
}
|
||||||
|
|
||||||
|
creds, err := p.Retrieve()
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
assert.Empty(t, creds.AccessKeyID)
|
||||||
|
assert.Empty(t, creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAssumeRoleProvider(b *testing.B) {
|
||||||
|
stub := &stubSTS{}
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: stub,
|
||||||
|
RoleARN: "roleARN",
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := p.Retrieve(); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go
generated
vendored
Normal file
88
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHTTPCredProvider(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Host string
|
||||||
|
Fail bool
|
||||||
|
}{
|
||||||
|
{"localhost", false}, {"127.0.0.1", false},
|
||||||
|
{"www.example.com", true}, {"169.254.170.2", true},
|
||||||
|
}
|
||||||
|
|
||||||
|
defer os.Clearenv()
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
u := fmt.Sprintf("http://%s/abc/123", c.Host)
|
||||||
|
os.Setenv(httpProviderEnvVar, u)
|
||||||
|
|
||||||
|
provider := RemoteCredProvider(aws.Config{}, request.Handlers{})
|
||||||
|
if provider == nil {
|
||||||
|
t.Fatalf("%d, expect provider not to be nil, but was", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Fail {
|
||||||
|
creds, err := provider.Retrieve()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("%d, expect error but got none", i)
|
||||||
|
} else {
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := "CredentialsEndpointError", aerr.Code(); e != a {
|
||||||
|
t.Errorf("%d, expect %s error code, got %s", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if e, a := endpointcreds.ProviderName, creds.ProviderName; e != a {
|
||||||
|
t.Errorf("%d, expect %s provider name got %s", i, e, a)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
httpProvider := provider.(*endpointcreds.Provider)
|
||||||
|
if e, a := u, httpProvider.Client.Endpoint; e != a {
|
||||||
|
t.Errorf("%d, expect %q endpoint, got %q", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestECSCredProvider(t *testing.T) {
|
||||||
|
defer os.Clearenv()
|
||||||
|
os.Setenv(ecsCredsProviderEnvVar, "/abc/123")
|
||||||
|
|
||||||
|
provider := RemoteCredProvider(aws.Config{}, request.Handlers{})
|
||||||
|
if provider == nil {
|
||||||
|
t.Fatalf("expect provider not to be nil, but was")
|
||||||
|
}
|
||||||
|
|
||||||
|
httpProvider := provider.(*endpointcreds.Provider)
|
||||||
|
if httpProvider == nil {
|
||||||
|
t.Fatalf("expect provider not to be nil, but was")
|
||||||
|
}
|
||||||
|
if e, a := "http://169.254.170.2/abc/123", httpProvider.Client.Endpoint; e != a {
|
||||||
|
t.Errorf("expect %q endpoint, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultEC2RoleProvider(t *testing.T) {
|
||||||
|
provider := RemoteCredProvider(aws.Config{}, request.Handlers{})
|
||||||
|
if provider == nil {
|
||||||
|
t.Fatalf("expect provider not to be nil, but was")
|
||||||
|
}
|
||||||
|
|
||||||
|
ec2Provider := provider.(*ec2rolecreds.EC2RoleProvider)
|
||||||
|
if ec2Provider == nil {
|
||||||
|
t.Fatalf("expect provider not to be nil, but was")
|
||||||
|
}
|
||||||
|
if e, a := "http://169.254.169.254/latest", ec2Provider.Client.Endpoint; e != a {
|
||||||
|
t.Errorf("expect %q endpoint, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
Normal file
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SharedCredentialsFilename returns the SDK's default file path
|
||||||
|
// for the shared credentials file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/credentials
|
||||||
|
// - Windows: %USERPROFILE%\.aws\credentials
|
||||||
|
func SharedCredentialsFilename() string {
|
||||||
|
return shareddefaults.SharedCredentialsFilename()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigFilename returns the SDK's default file path for
|
||||||
|
// the shared config file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/config
|
||||||
|
// - Windows: %USERPROFILE%\.aws\config
|
||||||
|
func SharedConfigFilename() string {
|
||||||
|
return shareddefaults.SharedConfigFilename()
|
||||||
|
}
|
289
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go
generated
vendored
Normal file
289
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api_test.go
generated
vendored
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
package ec2metadata_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
const instanceIdentityDocument = `{
|
||||||
|
"devpayProductCodes" : null,
|
||||||
|
"availabilityZone" : "us-east-1d",
|
||||||
|
"privateIp" : "10.158.112.84",
|
||||||
|
"version" : "2010-08-31",
|
||||||
|
"region" : "us-east-1",
|
||||||
|
"instanceId" : "i-1234567890abcdef0",
|
||||||
|
"billingProducts" : null,
|
||||||
|
"instanceType" : "t1.micro",
|
||||||
|
"accountId" : "123456789012",
|
||||||
|
"pendingTime" : "2015-11-19T16:32:11Z",
|
||||||
|
"imageId" : "ami-5fb8c835",
|
||||||
|
"kernelId" : "aki-919dcaf8",
|
||||||
|
"ramdiskId" : null,
|
||||||
|
"architecture" : "x86_64"
|
||||||
|
}`
|
||||||
|
|
||||||
|
const validIamInfo = `{
|
||||||
|
"Code" : "Success",
|
||||||
|
"LastUpdated" : "2016-03-17T12:27:32Z",
|
||||||
|
"InstanceProfileArn" : "arn:aws:iam::123456789012:instance-profile/my-instance-profile",
|
||||||
|
"InstanceProfileId" : "AIPAABCDEFGHIJKLMN123"
|
||||||
|
}`
|
||||||
|
|
||||||
|
const unsuccessfulIamInfo = `{
|
||||||
|
"Code" : "Failed",
|
||||||
|
"LastUpdated" : "2016-03-17T12:27:32Z",
|
||||||
|
"InstanceProfileArn" : "arn:aws:iam::123456789012:instance-profile/my-instance-profile",
|
||||||
|
"InstanceProfileId" : "AIPAABCDEFGHIJKLMN123"
|
||||||
|
}`
|
||||||
|
|
||||||
|
func initTestServer(path string, resp string) *httptest.Server {
|
||||||
|
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.RequestURI != path {
|
||||||
|
http.Error(w, "not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write([]byte(resp))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEndpoint(t *testing.T) {
|
||||||
|
c := ec2metadata.New(unit.Session)
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "GetMetadata",
|
||||||
|
HTTPMethod: "GET",
|
||||||
|
HTTPPath: path.Join("/", "meta-data", "testpath"),
|
||||||
|
}
|
||||||
|
|
||||||
|
req := c.NewRequest(op, nil, nil)
|
||||||
|
if e, a := "http://169.254.169.254/latest", req.ClientInfo.Endpoint; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "http://169.254.169.254/latest/meta-data/testpath", req.HTTPRequest.URL.String(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetMetadata(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/meta-data/some/path",
|
||||||
|
"success", // real response includes suffix
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
resp, err := c.GetMetadata("some/path")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "success", resp; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetUserData(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/user-data",
|
||||||
|
"success", // real response includes suffix
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
resp, err := c.GetUserData()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "success", resp; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetUserData_Error(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
reader := strings.NewReader(`<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
|
<head>
|
||||||
|
<title>404 - Not Found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>404 - Not Found</h1>
|
||||||
|
</body>
|
||||||
|
</html>`)
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
w.Header().Set("Content-Length", fmt.Sprintf("%d", reader.Len()))
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
io.Copy(w, reader)
|
||||||
|
}))
|
||||||
|
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
resp, err := c.GetUserData()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expect error")
|
||||||
|
}
|
||||||
|
if len(resp) != 0 {
|
||||||
|
t.Errorf("expect empty, got %v", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := "NotFoundError", aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetRegion(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/meta-data/placement/availability-zone",
|
||||||
|
"us-west-2a", // real response includes suffix
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
region, err := c.Region()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "us-west-2", region; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetadataAvailable(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/meta-data/instance-id",
|
||||||
|
"instance-id",
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
if !c.Available() {
|
||||||
|
t.Errorf("expect available")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetadataIAMInfo_success(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/meta-data/iam/info",
|
||||||
|
validIamInfo,
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
iamInfo, err := c.IAMInfo()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := "Success", iamInfo.Code; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "arn:aws:iam::123456789012:instance-profile/my-instance-profile", iamInfo.InstanceProfileArn; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "AIPAABCDEFGHIJKLMN123", iamInfo.InstanceProfileID; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetadataIAMInfo_failure(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/meta-data/iam/info",
|
||||||
|
unsuccessfulIamInfo,
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
iamInfo, err := c.IAMInfo()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expect error")
|
||||||
|
}
|
||||||
|
if e, a := "", iamInfo.Code; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "", iamInfo.InstanceProfileArn; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "", iamInfo.InstanceProfileID; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetadataNotAvailable(t *testing.T) {
|
||||||
|
c := ec2metadata.New(unit.Session)
|
||||||
|
c.Handlers.Send.Clear()
|
||||||
|
c.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: int(0),
|
||||||
|
Status: http.StatusText(int(0)),
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||||
|
}
|
||||||
|
r.Error = awserr.New("RequestError", "send request failed", nil)
|
||||||
|
r.Retryable = aws.Bool(true) // network errors are retryable
|
||||||
|
})
|
||||||
|
|
||||||
|
if c.Available() {
|
||||||
|
t.Errorf("expect not available")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMetadataErrorResponse(t *testing.T) {
|
||||||
|
c := ec2metadata.New(unit.Session)
|
||||||
|
c.Handlers.Send.Clear()
|
||||||
|
c.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: http.StatusBadRequest,
|
||||||
|
Status: http.StatusText(http.StatusBadRequest),
|
||||||
|
Body: ioutil.NopCloser(strings.NewReader("error message text")),
|
||||||
|
}
|
||||||
|
r.Retryable = aws.Bool(false) // network errors are retryable
|
||||||
|
})
|
||||||
|
|
||||||
|
data, err := c.GetMetadata("uri/path")
|
||||||
|
if len(data) != 0 {
|
||||||
|
t.Errorf("expect empty, got %v", data)
|
||||||
|
}
|
||||||
|
if e, a := "error message text", err.Error(); !strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to be in %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEC2RoleProviderInstanceIdentity(t *testing.T) {
|
||||||
|
server := initTestServer(
|
||||||
|
"/latest/dynamic/instance-identity/document",
|
||||||
|
instanceIdentityDocument,
|
||||||
|
)
|
||||||
|
defer server.Close()
|
||||||
|
c := ec2metadata.New(unit.Session, &aws.Config{Endpoint: aws.String(server.URL + "/latest")})
|
||||||
|
|
||||||
|
doc, err := c.GetInstanceIdentityDocument()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := doc.AccountID, "123456789012"; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := doc.AvailabilityZone, "us-east-1d"; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := doc.Region, "us-east-1"; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
78
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service_test.go
generated
vendored
Normal file
78
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service_test.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package ec2metadata_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestClientOverrideDefaultHTTPClientTimeout(t *testing.T) {
|
||||||
|
svc := ec2metadata.New(unit.Session)
|
||||||
|
|
||||||
|
assert.NotEqual(t, http.DefaultClient, svc.Config.HTTPClient)
|
||||||
|
assert.Equal(t, 5*time.Second, svc.Config.HTTPClient.Timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientNotOverrideDefaultHTTPClientTimeout(t *testing.T) {
|
||||||
|
http.DefaultClient.Transport = &http.Transport{}
|
||||||
|
defer func() {
|
||||||
|
http.DefaultClient.Transport = nil
|
||||||
|
}()
|
||||||
|
|
||||||
|
svc := ec2metadata.New(unit.Session)
|
||||||
|
|
||||||
|
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
|
||||||
|
|
||||||
|
tr, ok := svc.Config.HTTPClient.Transport.(*http.Transport)
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.NotNil(t, tr)
|
||||||
|
assert.Nil(t, tr.Dial)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientDisableOverrideDefaultHTTPClientTimeout(t *testing.T) {
|
||||||
|
svc := ec2metadata.New(unit.Session, aws.NewConfig().WithEC2MetadataDisableTimeoutOverride(true))
|
||||||
|
|
||||||
|
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientOverrideDefaultHTTPClientTimeoutRace(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("us-east-1a"))
|
||||||
|
}))
|
||||||
|
|
||||||
|
cfg := aws.NewConfig().WithEndpoint(server.URL)
|
||||||
|
runEC2MetadataClients(t, cfg, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientOverrideDefaultHTTPClientTimeoutRaceWithTransport(t *testing.T) {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("us-east-1a"))
|
||||||
|
}))
|
||||||
|
|
||||||
|
cfg := aws.NewConfig().WithEndpoint(server.URL).WithHTTPClient(&http.Client{
|
||||||
|
Transport: http.DefaultTransport,
|
||||||
|
})
|
||||||
|
|
||||||
|
runEC2MetadataClients(t, cfg, 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runEC2MetadataClients(t *testing.T, cfg *aws.Config, atOnce int) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
wg.Add(atOnce)
|
||||||
|
for i := 0; i < atOnce; i++ {
|
||||||
|
go func() {
|
||||||
|
svc := ec2metadata.New(unit.Session, cfg)
|
||||||
|
_, err := svc.Region()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
117
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode_test.go
generated
vendored
Normal file
117
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode_test.go
generated
vendored
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDecodeEndpoints_V3(t *testing.T) {
|
||||||
|
const v3Doc = `
|
||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"partitions": [
|
||||||
|
{
|
||||||
|
"defaults": {
|
||||||
|
"hostname": "{service}.{region}.{dnsSuffix}",
|
||||||
|
"protocols": [
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"signatureVersions": [
|
||||||
|
"v4"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dnsSuffix": "amazonaws.com",
|
||||||
|
"partition": "aws",
|
||||||
|
"partitionName": "AWS Standard",
|
||||||
|
"regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$",
|
||||||
|
"regions": {
|
||||||
|
"ap-northeast-1": {
|
||||||
|
"description": "Asia Pacific (Tokyo)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"acm": {
|
||||||
|
"endpoints": {
|
||||||
|
"ap-northeast-1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"s3": {
|
||||||
|
"endpoints": {
|
||||||
|
"ap-northeast-1": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
|
||||||
|
resolver, err := DecodeModel(strings.NewReader(v3Doc))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
endpoint, err := resolver.EndpointFor("acm", "ap-northeast-1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to resolve endpoint, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := endpoint.URL, "https://acm.ap-northeast-1.amazonaws.com"; a != e {
|
||||||
|
t.Errorf("expected %q URL got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
p := resolver.(partitions)[0]
|
||||||
|
|
||||||
|
s3Defaults := p.Services["s3"].Defaults
|
||||||
|
if a, e := s3Defaults.HasDualStack, boxedTrue; a != e {
|
||||||
|
t.Errorf("expect s3 service to have dualstack enabled")
|
||||||
|
}
|
||||||
|
if a, e := s3Defaults.DualStackHostname, "{service}.dualstack.{region}.{dnsSuffix}"; a != e {
|
||||||
|
t.Errorf("expect s3 dualstack host pattern to be %q, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
ec2metaEndpoint := p.Services["ec2metadata"].Endpoints["aws-global"]
|
||||||
|
if a, e := ec2metaEndpoint.Hostname, "169.254.169.254/latest"; a != e {
|
||||||
|
t.Errorf("expect ec2metadata host to be %q, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeEndpoints_NoPartitions(t *testing.T) {
|
||||||
|
const doc = `{ "version": 3 }`
|
||||||
|
|
||||||
|
resolver, err := DecodeModel(strings.NewReader(doc))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if resolver != nil {
|
||||||
|
t.Errorf("expect resolver to be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeEndpoints_UnsupportedVersion(t *testing.T) {
|
||||||
|
const doc = `{ "version": 2 }`
|
||||||
|
|
||||||
|
resolver, err := DecodeModel(strings.NewReader(doc))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error decoding model")
|
||||||
|
}
|
||||||
|
|
||||||
|
if resolver != nil {
|
||||||
|
t.Errorf("expect resolver to be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDecodeModelOptionsSet(t *testing.T) {
|
||||||
|
var actual DecodeModelOptions
|
||||||
|
actual.Set(func(o *DecodeModelOptions) {
|
||||||
|
o.SkipCustomizations = true
|
||||||
|
})
|
||||||
|
|
||||||
|
expect := DecodeModelOptions{
|
||||||
|
SkipCustomizations: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if actual != expect {
|
||||||
|
t.Errorf("expect %v options got %v", expect, actual)
|
||||||
|
}
|
||||||
|
}
|
264
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
264
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
|
@ -44,9 +44,11 @@ const (
|
||||||
// Service identifiers
|
// Service identifiers
|
||||||
const (
|
const (
|
||||||
AcmServiceID = "acm" // Acm.
|
AcmServiceID = "acm" // Acm.
|
||||||
|
ApiPricingServiceID = "api.pricing" // ApiPricing.
|
||||||
ApigatewayServiceID = "apigateway" // Apigateway.
|
ApigatewayServiceID = "apigateway" // Apigateway.
|
||||||
ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling.
|
ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling.
|
||||||
Appstream2ServiceID = "appstream2" // Appstream2.
|
Appstream2ServiceID = "appstream2" // Appstream2.
|
||||||
|
AthenaServiceID = "athena" // Athena.
|
||||||
AutoscalingServiceID = "autoscaling" // Autoscaling.
|
AutoscalingServiceID = "autoscaling" // Autoscaling.
|
||||||
BatchServiceID = "batch" // Batch.
|
BatchServiceID = "batch" // Batch.
|
||||||
BudgetsServiceID = "budgets" // Budgets.
|
BudgetsServiceID = "budgets" // Budgets.
|
||||||
|
@ -54,6 +56,7 @@ const (
|
||||||
CloudformationServiceID = "cloudformation" // Cloudformation.
|
CloudformationServiceID = "cloudformation" // Cloudformation.
|
||||||
CloudfrontServiceID = "cloudfront" // Cloudfront.
|
CloudfrontServiceID = "cloudfront" // Cloudfront.
|
||||||
CloudhsmServiceID = "cloudhsm" // Cloudhsm.
|
CloudhsmServiceID = "cloudhsm" // Cloudhsm.
|
||||||
|
Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2.
|
||||||
CloudsearchServiceID = "cloudsearch" // Cloudsearch.
|
CloudsearchServiceID = "cloudsearch" // Cloudsearch.
|
||||||
CloudtrailServiceID = "cloudtrail" // Cloudtrail.
|
CloudtrailServiceID = "cloudtrail" // Cloudtrail.
|
||||||
CodebuildServiceID = "codebuild" // Codebuild.
|
CodebuildServiceID = "codebuild" // Codebuild.
|
||||||
|
@ -90,6 +93,8 @@ const (
|
||||||
FirehoseServiceID = "firehose" // Firehose.
|
FirehoseServiceID = "firehose" // Firehose.
|
||||||
GameliftServiceID = "gamelift" // Gamelift.
|
GameliftServiceID = "gamelift" // Gamelift.
|
||||||
GlacierServiceID = "glacier" // Glacier.
|
GlacierServiceID = "glacier" // Glacier.
|
||||||
|
GlueServiceID = "glue" // Glue.
|
||||||
|
GreengrassServiceID = "greengrass" // Greengrass.
|
||||||
HealthServiceID = "health" // Health.
|
HealthServiceID = "health" // Health.
|
||||||
IamServiceID = "iam" // Iam.
|
IamServiceID = "iam" // Iam.
|
||||||
ImportexportServiceID = "importexport" // Importexport.
|
ImportexportServiceID = "importexport" // Importexport.
|
||||||
|
@ -104,6 +109,7 @@ const (
|
||||||
MachinelearningServiceID = "machinelearning" // Machinelearning.
|
MachinelearningServiceID = "machinelearning" // Machinelearning.
|
||||||
MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
|
MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
|
||||||
MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace.
|
MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace.
|
||||||
|
MghServiceID = "mgh" // Mgh.
|
||||||
MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics.
|
MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics.
|
||||||
ModelsLexServiceID = "models.lex" // ModelsLex.
|
ModelsLexServiceID = "models.lex" // ModelsLex.
|
||||||
MonitoringServiceID = "monitoring" // Monitoring.
|
MonitoringServiceID = "monitoring" // Monitoring.
|
||||||
|
@ -251,6 +257,16 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"api.pricing": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "pricing",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"apigateway": service{
|
"apigateway": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -259,9 +275,11 @@ var awsPartition = partition{
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-1": endpoint{},
|
"us-west-1": endpoint{},
|
||||||
|
@ -307,6 +325,19 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"athena": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"autoscaling": service{
|
"autoscaling": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"http", "https"},
|
||||||
|
@ -331,7 +362,15 @@ var awsPartition = partition{
|
||||||
"batch": service{
|
"batch": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"budgets": service{
|
"budgets": service{
|
||||||
|
@ -407,6 +446,22 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"cloudhsmv2": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"cloudsearch": service{
|
"cloudsearch": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -447,19 +502,32 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"codecommit": service{
|
"codecommit": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -486,22 +554,32 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"codestar": service{
|
"codestar": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -511,6 +589,7 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
@ -526,6 +605,7 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
@ -541,6 +621,7 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
@ -646,8 +727,10 @@ var awsPartition = partition{
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -715,6 +798,7 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
|
@ -731,6 +815,7 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
|
@ -785,6 +870,7 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -793,7 +879,7 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
"elasticloadbalancing": service{
|
"elasticloadbalancing": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"https"},
|
||||||
},
|
},
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
@ -910,8 +996,11 @@ var awsPartition = partition{
|
||||||
"firehose": service{
|
"firehose": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -922,10 +1011,15 @@ var awsPartition = partition{
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -937,6 +1031,7 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
|
@ -948,6 +1043,27 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"glue": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"greengrass": service{
|
||||||
|
IsRegionalized: boxedTrue,
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"health": service{
|
"health": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -991,6 +1107,7 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1067,9 +1184,11 @@ var awsPartition = partition{
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-1": endpoint{},
|
"us-west-1": endpoint{},
|
||||||
|
@ -1079,6 +1198,10 @@ var awsPartition = partition{
|
||||||
"lightsail": service{
|
"lightsail": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
|
"ap-southeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
@ -1142,6 +1265,12 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"mgh": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"mobileanalytics": service{
|
"mobileanalytics": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1241,6 +1370,7 @@ var awsPartition = partition{
|
||||||
"polly": service{
|
"polly": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1336,23 +1466,23 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{
|
"ap-northeast-1": endpoint{
|
||||||
Hostname: "s3-ap-northeast-1.amazonaws.com",
|
Hostname: "s3.ap-northeast-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{
|
"ap-southeast-1": endpoint{
|
||||||
Hostname: "s3-ap-southeast-1.amazonaws.com",
|
Hostname: "s3.ap-southeast-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"ap-southeast-2": endpoint{
|
"ap-southeast-2": endpoint{
|
||||||
Hostname: "s3-ap-southeast-2.amazonaws.com",
|
Hostname: "s3.ap-southeast-2.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{
|
"eu-west-1": endpoint{
|
||||||
Hostname: "s3-eu-west-1.amazonaws.com",
|
Hostname: "s3.eu-west-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
@ -1364,7 +1494,7 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sa-east-1": endpoint{
|
"sa-east-1": endpoint{
|
||||||
Hostname: "s3-sa-east-1.amazonaws.com",
|
Hostname: "s3.sa-east-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"us-east-1": endpoint{
|
"us-east-1": endpoint{
|
||||||
|
@ -1373,11 +1503,11 @@ var awsPartition = partition{
|
||||||
},
|
},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-1": endpoint{
|
"us-west-1": endpoint{
|
||||||
Hostname: "s3-us-west-1.amazonaws.com",
|
Hostname: "s3.us-west-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"us-west-2": endpoint{
|
"us-west-2": endpoint{
|
||||||
Hostname: "s3-us-west-2.amazonaws.com",
|
Hostname: "s3.us-west-2.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1404,14 +1534,18 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"ca-central-1": endpoint{},
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1428,19 +1562,27 @@ var awsPartition = partition{
|
||||||
"sms": service{
|
"sms": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"snowball": service{
|
"snowball": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-1": endpoint{},
|
"us-west-1": endpoint{},
|
||||||
|
@ -1497,10 +1639,13 @@ var awsPartition = partition{
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"ap-northeast-2": endpoint{},
|
"ap-northeast-2": endpoint{},
|
||||||
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
"ca-central-1": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1512,8 +1657,10 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
|
@ -1687,6 +1834,7 @@ var awsPartition = partition{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
|
"us-west-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1709,6 +1857,7 @@ var awsPartition = partition{
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
"eu-central-1": endpoint{},
|
"eu-central-1": endpoint{},
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
|
"eu-west-2": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
|
@ -1761,6 +1910,18 @@ var awscnPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: services{
|
Services: services{
|
||||||
|
"application-autoscaling": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "autoscaling.{region}.amazonaws.com",
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "application-autoscaling",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"autoscaling": service{
|
"autoscaling": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"http", "https"},
|
||||||
|
@ -1787,6 +1948,12 @@ var awscnPartition = partition{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"cognito-identity": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"config": service{
|
"config": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1826,6 +1993,18 @@ var awscnPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"ecr": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ecs": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"elasticache": service{
|
"elasticache": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1840,7 +2019,7 @@ var awscnPartition = partition{
|
||||||
},
|
},
|
||||||
"elasticloadbalancing": service{
|
"elasticloadbalancing": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"https"},
|
||||||
},
|
},
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
|
@ -1854,6 +2033,7 @@ var awscnPartition = partition{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"es": service{},
|
||||||
"events": service{
|
"events": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1881,12 +2061,28 @@ var awscnPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"iot": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Service: "execute-api",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"kinesis": service{
|
"kinesis": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"lambda": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"logs": service{
|
"logs": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -1922,6 +2118,12 @@ var awscnPartition = partition{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"snowball": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"sns": service{
|
"sns": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"http", "https"},
|
||||||
|
@ -1939,6 +2141,12 @@ var awscnPartition = partition{
|
||||||
"cn-north-1": endpoint{},
|
"cn-north-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"ssm": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"cn-north-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"storagegateway": service{
|
"storagegateway": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -2003,6 +2211,18 @@ var awsusgovPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Services: services{
|
Services: services{
|
||||||
|
"acm": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"apigateway": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"autoscaling": service{
|
"autoscaling": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -2029,6 +2249,12 @@ var awsusgovPartition = partition{
|
||||||
"us-gov-west-1": endpoint{},
|
"us-gov-west-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"codedeploy": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"config": service{
|
"config": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -2155,6 +2381,12 @@ var awsusgovPartition = partition{
|
||||||
"us-gov-west-1": endpoint{},
|
"us-gov-west-1": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"rekognition": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"s3": service{
|
"s3": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
|
@ -2167,11 +2399,17 @@ var awsusgovPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"us-gov-west-1": endpoint{
|
"us-gov-west-1": endpoint{
|
||||||
Hostname: "s3-us-gov-west-1.amazonaws.com",
|
Hostname: "s3.us-gov-west-1.amazonaws.com",
|
||||||
Protocols: []string{"http", "https"},
|
Protocols: []string{"http", "https"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"sms": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"snowball": service{
|
"snowball": service{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
|
@ -2195,6 +2433,12 @@ var awsusgovPartition = partition{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"ssm": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-gov-west-1": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
"streams.dynamodb": service{
|
"streams.dynamodb": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
|
4
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
|
@ -21,12 +21,12 @@
|
||||||
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
||||||
//
|
//
|
||||||
// for _, p := range partitions {
|
// for _, p := range partitions {
|
||||||
// fmt.Println("Regions for", p.Name)
|
// fmt.Println("Regions for", p.ID())
|
||||||
// for id, _ := range p.Regions() {
|
// for id, _ := range p.Regions() {
|
||||||
// fmt.Println("*", id)
|
// fmt.Println("*", id)
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// fmt.Println("Services for", p.Name)
|
// fmt.Println("Services for", p.ID())
|
||||||
// for id, _ := range p.Services() {
|
// for id, _ := range p.Services() {
|
||||||
// fmt.Println("*", id)
|
// fmt.Println("*", id)
|
||||||
// }
|
// }
|
||||||
|
|
335
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints_test.go
generated
vendored
Normal file
335
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints_test.go
generated
vendored
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
package endpoints
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestEnumDefaultPartitions(t *testing.T) {
|
||||||
|
resolver := DefaultResolver()
|
||||||
|
enum, ok := resolver.(EnumPartitions)
|
||||||
|
|
||||||
|
if ok != true {
|
||||||
|
t.Fatalf("resolver must satisfy EnumPartition interface")
|
||||||
|
}
|
||||||
|
|
||||||
|
ps := enum.Partitions()
|
||||||
|
|
||||||
|
if a, e := len(ps), len(defaultPartitions); a != e {
|
||||||
|
t.Errorf("expected %d partitions, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumDefaultRegions(t *testing.T) {
|
||||||
|
expectPart := defaultPartitions[0]
|
||||||
|
partEnum := defaultPartitions[0].Partition()
|
||||||
|
|
||||||
|
regEnum := partEnum.Regions()
|
||||||
|
|
||||||
|
if a, e := len(regEnum), len(expectPart.Regions); a != e {
|
||||||
|
t.Errorf("expected %d regions, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumPartitionServices(t *testing.T) {
|
||||||
|
expectPart := testPartitions[0]
|
||||||
|
partEnum := testPartitions[0].Partition()
|
||||||
|
|
||||||
|
if a, e := partEnum.ID(), "part-id"; a != e {
|
||||||
|
t.Errorf("expect %q partition ID, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
svcEnum := partEnum.Services()
|
||||||
|
|
||||||
|
if a, e := len(svcEnum), len(expectPart.Services); a != e {
|
||||||
|
t.Errorf("expected %d regions, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumRegionServices(t *testing.T) {
|
||||||
|
p := testPartitions[0].Partition()
|
||||||
|
|
||||||
|
rs := p.Regions()
|
||||||
|
|
||||||
|
if a, e := len(rs), 2; a != e {
|
||||||
|
t.Errorf("expect %d regions got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := rs["us-east-1"]; !ok {
|
||||||
|
t.Errorf("expect us-east-1 region to be found, was not")
|
||||||
|
}
|
||||||
|
if _, ok := rs["us-west-2"]; !ok {
|
||||||
|
t.Errorf("expect us-west-2 region to be found, was not")
|
||||||
|
}
|
||||||
|
|
||||||
|
r := rs["us-east-1"]
|
||||||
|
|
||||||
|
if a, e := r.ID(), "us-east-1"; a != e {
|
||||||
|
t.Errorf("expect %q region ID, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
ss := r.Services()
|
||||||
|
if a, e := len(ss), 1; a != e {
|
||||||
|
t.Errorf("expect %d services for us-east-1, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ss["service1"]; !ok {
|
||||||
|
t.Errorf("expect service1 service to be found, was not")
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved, err := r.ResolveEndpoint("service1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := resolved.URL, "https://service1.us-east-1.amazonaws.com"; a != e {
|
||||||
|
t.Errorf("expect %q resolved URL, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumServiceRegions(t *testing.T) {
|
||||||
|
p := testPartitions[0].Partition()
|
||||||
|
|
||||||
|
rs := p.Services()["service1"].Regions()
|
||||||
|
if e, a := 2, len(rs); e != a {
|
||||||
|
t.Errorf("expect %d regions, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := rs["us-east-1"]; !ok {
|
||||||
|
t.Errorf("expect region to be found")
|
||||||
|
}
|
||||||
|
if _, ok := rs["us-west-2"]; !ok {
|
||||||
|
t.Errorf("expect region to be found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumServicesEndpoints(t *testing.T) {
|
||||||
|
p := testPartitions[0].Partition()
|
||||||
|
|
||||||
|
ss := p.Services()
|
||||||
|
|
||||||
|
if a, e := len(ss), 5; a != e {
|
||||||
|
t.Errorf("expect %d regions got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := ss["service1"]; !ok {
|
||||||
|
t.Errorf("expect service1 region to be found, was not")
|
||||||
|
}
|
||||||
|
if _, ok := ss["service2"]; !ok {
|
||||||
|
t.Errorf("expect service2 region to be found, was not")
|
||||||
|
}
|
||||||
|
|
||||||
|
s := ss["service1"]
|
||||||
|
if a, e := s.ID(), "service1"; a != e {
|
||||||
|
t.Errorf("expect %q service ID, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved, err := s.ResolveEndpoint("us-west-2")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := resolved.URL, "https://service1.us-west-2.amazonaws.com"; a != e {
|
||||||
|
t.Errorf("expect %q resolved URL, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnumEndpoints(t *testing.T) {
|
||||||
|
p := testPartitions[0].Partition()
|
||||||
|
s := p.Services()["service1"]
|
||||||
|
|
||||||
|
es := s.Endpoints()
|
||||||
|
if a, e := len(es), 2; a != e {
|
||||||
|
t.Errorf("expect %d endpoints for service2, got %d", e, a)
|
||||||
|
}
|
||||||
|
if _, ok := es["us-east-1"]; !ok {
|
||||||
|
t.Errorf("expect us-east-1 to be found, was not")
|
||||||
|
}
|
||||||
|
|
||||||
|
e := es["us-east-1"]
|
||||||
|
if a, e := e.ID(), "us-east-1"; a != e {
|
||||||
|
t.Errorf("expect %q endpoint ID, got %q", e, a)
|
||||||
|
}
|
||||||
|
if a, e := e.ServiceID(), "service1"; a != e {
|
||||||
|
t.Errorf("expect %q service ID, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved, err := e.ResolveEndpoint()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := resolved.URL, "https://service1.us-east-1.amazonaws.com"; a != e {
|
||||||
|
t.Errorf("expect %q resolved URL, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpointForPartition(t *testing.T) {
|
||||||
|
enum := testPartitions.Partitions()[0]
|
||||||
|
|
||||||
|
expected, err := testPartitions.EndpointFor("service1", "us-east-1")
|
||||||
|
|
||||||
|
actual, err := enum.EndpointFor("service1", "us-east-1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected != actual {
|
||||||
|
t.Errorf("expect resolved endpoint to be %v, but got %v", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddScheme(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
In string
|
||||||
|
Expect string
|
||||||
|
DisableSSL bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
In: "https://example.com",
|
||||||
|
Expect: "https://example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
In: "example.com",
|
||||||
|
Expect: "https://example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
In: "http://example.com",
|
||||||
|
Expect: "http://example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
In: "example.com",
|
||||||
|
Expect: "http://example.com",
|
||||||
|
DisableSSL: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
In: "https://example.com",
|
||||||
|
Expect: "https://example.com",
|
||||||
|
DisableSSL: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
actual := AddScheme(c.In, c.DisableSSL)
|
||||||
|
if actual != c.Expect {
|
||||||
|
t.Errorf("%d, expect URL to be %q, got %q", i, c.Expect, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolverFunc(t *testing.T) {
|
||||||
|
var resolver Resolver
|
||||||
|
|
||||||
|
resolver = ResolverFunc(func(s, r string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
return ResolvedEndpoint{
|
||||||
|
URL: "https://service.region.dnssuffix.com",
|
||||||
|
SigningRegion: "region",
|
||||||
|
SigningName: "service",
|
||||||
|
}, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
resolved, err := resolver.EndpointFor("service", "region", func(o *Options) {
|
||||||
|
o.DisableSSL = true
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := resolved.URL, "https://service.region.dnssuffix.com"; a != e {
|
||||||
|
t.Errorf("expect %q endpoint URL, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a, e := resolved.SigningRegion, "region"; a != e {
|
||||||
|
t.Errorf("expect %q region, got %q", e, a)
|
||||||
|
}
|
||||||
|
if a, e := resolved.SigningName, "service"; a != e {
|
||||||
|
t.Errorf("expect %q signing name, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOptionsSet(t *testing.T) {
|
||||||
|
var actual Options
|
||||||
|
actual.Set(DisableSSLOption, UseDualStackOption, StrictMatchingOption)
|
||||||
|
|
||||||
|
expect := Options{
|
||||||
|
DisableSSL: true,
|
||||||
|
UseDualStack: true,
|
||||||
|
StrictMatching: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if actual != expect {
|
||||||
|
t.Errorf("expect %v options got %v", expect, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegionsForService(t *testing.T) {
|
||||||
|
ps := DefaultPartitions()
|
||||||
|
|
||||||
|
var expect map[string]Region
|
||||||
|
var serviceID string
|
||||||
|
for _, s := range ps[0].Services() {
|
||||||
|
expect = s.Regions()
|
||||||
|
serviceID = s.ID()
|
||||||
|
if len(expect) > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, ok := RegionsForService(ps, ps[0].ID(), serviceID)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expect regions to be found, was not")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(actual) == 0 {
|
||||||
|
t.Fatalf("expect service %s to have regions", serviceID)
|
||||||
|
}
|
||||||
|
if e, a := len(expect), len(actual); e != a {
|
||||||
|
t.Fatalf("expect %d regions, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
for id, r := range actual {
|
||||||
|
if e, a := id, r.ID(); e != a {
|
||||||
|
t.Errorf("expect %s region id, got %s", e, a)
|
||||||
|
}
|
||||||
|
if _, ok := expect[id]; !ok {
|
||||||
|
t.Errorf("expect %s region to be found", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegionsForService_NotFound(t *testing.T) {
|
||||||
|
ps := testPartitions.Partitions()
|
||||||
|
|
||||||
|
actual, ok := RegionsForService(ps, ps[0].ID(), "service-not-exists")
|
||||||
|
if ok {
|
||||||
|
t.Fatalf("expect no regions to be found, but were")
|
||||||
|
}
|
||||||
|
if len(actual) != 0 {
|
||||||
|
t.Errorf("expect no regions, got %v", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPartitionForRegion(t *testing.T) {
|
||||||
|
ps := DefaultPartitions()
|
||||||
|
expect := ps[len(ps)%2]
|
||||||
|
|
||||||
|
var regionID string
|
||||||
|
for id := range expect.Regions() {
|
||||||
|
regionID = id
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, ok := PartitionForRegion(ps, regionID)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expect partition to be found")
|
||||||
|
}
|
||||||
|
if e, a := expect.ID(), actual.ID(); e != a {
|
||||||
|
t.Errorf("expect %s partition, got %s", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPartitionForRegion_NotFound(t *testing.T) {
|
||||||
|
ps := DefaultPartitions()
|
||||||
|
|
||||||
|
actual, ok := PartitionForRegion(ps, "regionNotExists")
|
||||||
|
if ok {
|
||||||
|
t.Errorf("expect no partition to be found, got %v", actual)
|
||||||
|
}
|
||||||
|
}
|
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/example_test.go
generated
vendored
Normal file
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/example_test.go
generated
vendored
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package endpoints_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sqs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ExampleEnumPartitions() {
|
||||||
|
resolver := endpoints.DefaultResolver()
|
||||||
|
partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
||||||
|
|
||||||
|
for _, p := range partitions {
|
||||||
|
fmt.Println("Regions for", p.ID())
|
||||||
|
for id := range p.Regions() {
|
||||||
|
fmt.Println("*", id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Services for", p.ID())
|
||||||
|
for id := range p.Services() {
|
||||||
|
fmt.Println("*", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExampleResolverFunc() {
|
||||||
|
myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
||||||
|
if service == endpoints.S3ServiceID {
|
||||||
|
return endpoints.ResolvedEndpoint{
|
||||||
|
URL: "s3.custom.endpoint.com",
|
||||||
|
SigningRegion: "custom-signing-region",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
|
||||||
|
}
|
||||||
|
|
||||||
|
sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
Region: aws.String("us-west-2"),
|
||||||
|
EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Create the S3 service client with the shared session. This will
|
||||||
|
// automatically use the S3 custom endpoint configured in the custom
|
||||||
|
// endpoint resolver wrapping the default endpoint resolver.
|
||||||
|
s3Svc := s3.New(sess)
|
||||||
|
// Operation calls will be made to the custom endpoint.
|
||||||
|
s3Svc.GetObject(&s3.GetObjectInput{
|
||||||
|
Bucket: aws.String("myBucket"),
|
||||||
|
Key: aws.String("myObjectKey"),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create the SQS service client with the shared session. This will
|
||||||
|
// fallback to the default endpoint resolver because the customization
|
||||||
|
// passes any non S3 service endpoint resolve to the default resolver.
|
||||||
|
sqsSvc := sqs.New(sess)
|
||||||
|
// Operation calls will be made to the default endpoint for SQS for the
|
||||||
|
// region configured.
|
||||||
|
sqsSvc.ReceiveMessage(&sqs.ReceiveMessageInput{
|
||||||
|
QueueUrl: aws.String("my-queue-url"),
|
||||||
|
})
|
||||||
|
}
|
354
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_test.go
generated
vendored
Normal file
354
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_test.go
generated
vendored
Normal file
|
@ -0,0 +1,354 @@
|
||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUnmarshalRegionRegex(t *testing.T) {
|
||||||
|
var input = []byte(`
|
||||||
|
{
|
||||||
|
"regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$"
|
||||||
|
}`)
|
||||||
|
|
||||||
|
p := partition{}
|
||||||
|
err := json.Unmarshal(input, &p)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
expectRegexp, err := regexp.Compile(`^(us|eu|ap|sa|ca)\-\w+\-\d+$`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, expectRegexp.String(), p.RegionRegex.Regexp.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalRegion(t *testing.T) {
|
||||||
|
var input = []byte(`
|
||||||
|
{
|
||||||
|
"aws-global": {
|
||||||
|
"description": "AWS partition-global endpoint"
|
||||||
|
},
|
||||||
|
"us-east-1": {
|
||||||
|
"description": "US East (N. Virginia)"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
|
||||||
|
rs := regions{}
|
||||||
|
err := json.Unmarshal(input, &rs)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, rs, 2)
|
||||||
|
r, ok := rs["aws-global"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Equal(t, "AWS partition-global endpoint", r.Description)
|
||||||
|
|
||||||
|
r, ok = rs["us-east-1"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Equal(t, "US East (N. Virginia)", r.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalServices(t *testing.T) {
|
||||||
|
var input = []byte(`
|
||||||
|
{
|
||||||
|
"acm": {
|
||||||
|
"endpoints": {
|
||||||
|
"us-east-1": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"apigateway": {
|
||||||
|
"isRegionalized": true,
|
||||||
|
"endpoints": {
|
||||||
|
"us-east-1": {},
|
||||||
|
"us-west-2": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notRegionalized": {
|
||||||
|
"isRegionalized": false,
|
||||||
|
"endpoints": {
|
||||||
|
"us-east-1": {},
|
||||||
|
"us-west-2": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
|
||||||
|
ss := services{}
|
||||||
|
err := json.Unmarshal(input, &ss)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, ss, 3)
|
||||||
|
s, ok := ss["acm"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Len(t, s.Endpoints, 1)
|
||||||
|
assert.Equal(t, boxedBoolUnset, s.IsRegionalized)
|
||||||
|
|
||||||
|
s, ok = ss["apigateway"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Len(t, s.Endpoints, 2)
|
||||||
|
assert.Equal(t, boxedTrue, s.IsRegionalized)
|
||||||
|
|
||||||
|
s, ok = ss["notRegionalized"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Len(t, s.Endpoints, 2)
|
||||||
|
assert.Equal(t, boxedFalse, s.IsRegionalized)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalEndpoints(t *testing.T) {
|
||||||
|
var inputs = []byte(`
|
||||||
|
{
|
||||||
|
"aws-global": {
|
||||||
|
"hostname": "cloudfront.amazonaws.com",
|
||||||
|
"protocols": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"signatureVersions": [ "v4" ],
|
||||||
|
"credentialScope": {
|
||||||
|
"region": "us-east-1",
|
||||||
|
"service": "serviceName"
|
||||||
|
},
|
||||||
|
"sslCommonName": "commonName"
|
||||||
|
},
|
||||||
|
"us-east-1": {}
|
||||||
|
}`)
|
||||||
|
|
||||||
|
es := endpoints{}
|
||||||
|
err := json.Unmarshal(inputs, &es)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Len(t, es, 2)
|
||||||
|
s, ok := es["aws-global"]
|
||||||
|
assert.True(t, ok)
|
||||||
|
assert.Equal(t, "cloudfront.amazonaws.com", s.Hostname)
|
||||||
|
assert.Equal(t, []string{"http", "https"}, s.Protocols)
|
||||||
|
assert.Equal(t, []string{"v4"}, s.SignatureVersions)
|
||||||
|
assert.Equal(t, credentialScope{"us-east-1", "serviceName"}, s.CredentialScope)
|
||||||
|
assert.Equal(t, "commonName", s.SSLCommonName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEndpointResolve(t *testing.T) {
|
||||||
|
defs := []endpoint{
|
||||||
|
{
|
||||||
|
Hostname: "{service}.{region}.{dnsSuffix}",
|
||||||
|
SignatureVersions: []string{"v2"},
|
||||||
|
SSLCommonName: "sslCommonName",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Hostname: "other-hostname",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "signing_region",
|
||||||
|
Service: "signing_service",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
e := endpoint{
|
||||||
|
Hostname: "{service}.{region}.{dnsSuffix}",
|
||||||
|
Protocols: []string{"http", "https"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
SSLCommonName: "new sslCommonName",
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved := e.resolve("service", "region", "dnsSuffix",
|
||||||
|
defs, Options{},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Equal(t, "https://service.region.dnsSuffix", resolved.URL)
|
||||||
|
assert.Equal(t, "signing_service", resolved.SigningName)
|
||||||
|
assert.Equal(t, "signing_region", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "v4", resolved.SigningMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEndpointMergeIn(t *testing.T) {
|
||||||
|
expected := endpoint{
|
||||||
|
Hostname: "other hostname",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
SSLCommonName: "ssl common name",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "region",
|
||||||
|
Service: "service",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := endpoint{}
|
||||||
|
actual.mergeIn(endpoint{
|
||||||
|
Hostname: "other hostname",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
SSLCommonName: "ssl common name",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "region",
|
||||||
|
Service: "service",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
var testPartitions = partitions{
|
||||||
|
partition{
|
||||||
|
ID: "part-id",
|
||||||
|
Name: "partitionName",
|
||||||
|
DNSSuffix: "amazonaws.com",
|
||||||
|
RegionRegex: regionRegex{
|
||||||
|
Regexp: func() *regexp.Regexp {
|
||||||
|
reg, _ := regexp.Compile("^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$")
|
||||||
|
return reg
|
||||||
|
}(),
|
||||||
|
},
|
||||||
|
Defaults: endpoint{
|
||||||
|
Hostname: "{service}.{region}.{dnsSuffix}",
|
||||||
|
Protocols: []string{"https"},
|
||||||
|
SignatureVersions: []string{"v4"},
|
||||||
|
},
|
||||||
|
Regions: regions{
|
||||||
|
"us-east-1": region{
|
||||||
|
Description: "region description",
|
||||||
|
},
|
||||||
|
"us-west-2": region{},
|
||||||
|
},
|
||||||
|
Services: services{
|
||||||
|
"s3": service{},
|
||||||
|
"service1": service{
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"us-east-1": {},
|
||||||
|
"us-west-2": {
|
||||||
|
HasDualStack: boxedTrue,
|
||||||
|
DualStackHostname: "{service}.dualstack.{region}.{dnsSuffix}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"service2": service{},
|
||||||
|
"httpService": service{
|
||||||
|
Defaults: endpoint{
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"globalService": service{
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
PartitionEndpoint: "aws-global",
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-global": endpoint{
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-east-1",
|
||||||
|
},
|
||||||
|
Hostname: "globalService.amazonaws.com",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("service2", "us-west-2")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://service2.us-west-2.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-west-2", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "service2", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_DisableSSL(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("service2", "us-west-2", DisableSSLOption)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "http://service2.us-west-2.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-west-2", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "service2", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_UseDualStack(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("service1", "us-west-2", UseDualStackOption)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://service1.dualstack.us-west-2.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-west-2", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "service1", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_HTTPProtocol(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("httpService", "us-west-2")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "http://httpService.us-west-2.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-west-2", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "httpService", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_UnknownService(t *testing.T) {
|
||||||
|
_, err := testPartitions.EndpointFor("unknownservice", "us-west-2")
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
_, ok := err.(UnknownServiceError)
|
||||||
|
assert.True(t, ok, "expect error to be UnknownServiceError")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_ResolveUnknownService(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("unknown-service", "us-region-1",
|
||||||
|
ResolveUnknownServiceOption)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "https://unknown-service.us-region-1.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-region-1", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "unknown-service", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_UnknownMatchedRegion(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("service2", "us-region-1")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://service2.us-region-1.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-region-1", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "service2", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_UnknownRegion(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("service2", "unknownregion")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://service2.unknownregion.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "unknownregion", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "service2", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_StrictPartitionUnknownEndpoint(t *testing.T) {
|
||||||
|
_, err := testPartitions[0].EndpointFor("service2", "unknownregion", StrictMatchingOption)
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
_, ok := err.(UnknownEndpointError)
|
||||||
|
assert.True(t, ok, "expect error to be UnknownEndpointError")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_StrictPartitionsUnknownEndpoint(t *testing.T) {
|
||||||
|
_, err := testPartitions.EndpointFor("service2", "us-region-1", StrictMatchingOption)
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
_, ok := err.(UnknownEndpointError)
|
||||||
|
assert.True(t, ok, "expect error to be UnknownEndpointError")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_NotRegionalized(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("globalService", "us-west-2")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://globalService.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-east-1", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "globalService", resolved.SigningName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveEndpoint_AwsGlobal(t *testing.T) {
|
||||||
|
resolved, err := testPartitions.EndpointFor("globalService", "aws-global")
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "https://globalService.amazonaws.com", resolved.URL)
|
||||||
|
assert.Equal(t, "us-east-1", resolved.SigningRegion)
|
||||||
|
assert.Equal(t, "globalService", resolved.SigningName)
|
||||||
|
}
|
4
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
|
@ -26,14 +26,14 @@ func (l *LogLevelType) Value() LogLevelType {
|
||||||
|
|
||||||
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
||||||
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
||||||
// LogLevel is nill, will default to LogOff comparison.
|
// LogLevel is nil, will default to LogOff comparison.
|
||||||
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
||||||
c := l.Value()
|
c := l.Value()
|
||||||
return c&v == v
|
return c&v == v
|
||||||
}
|
}
|
||||||
|
|
||||||
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
||||||
// Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default
|
// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default
|
||||||
// to LogOff comparison.
|
// to LogOff comparison.
|
||||||
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
||||||
c := l.Value()
|
c := l.Value()
|
||||||
|
|
9
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other_test.go
generated
vendored
Normal file
9
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other_test.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build appengine plan9
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var stubConnectionResetError = errors.New("connection reset")
|
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !appengine,!plan9
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var stubConnectionResetError = &net.OpError{Err: &os.SyscallError{Syscall: "read", Err: syscall.ECONNRESET}}
|
266
vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go
generated
vendored
Normal file
266
vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go
generated
vendored
Normal file
|
@ -0,0 +1,266 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHandlerList(t *testing.T) {
|
||||||
|
s := ""
|
||||||
|
r := &request.Request{}
|
||||||
|
l := request.HandlerList{}
|
||||||
|
l.PushBack(func(r *request.Request) {
|
||||||
|
s += "a"
|
||||||
|
r.Data = s
|
||||||
|
})
|
||||||
|
l.Run(r)
|
||||||
|
if e, a := "a", s; e != a {
|
||||||
|
t.Errorf("expect %q update got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "a", r.Data.(string); e != a {
|
||||||
|
t.Errorf("expect %q data update got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMultipleHandlers(t *testing.T) {
|
||||||
|
r := &request.Request{}
|
||||||
|
l := request.HandlerList{}
|
||||||
|
l.PushBack(func(r *request.Request) { r.Data = nil })
|
||||||
|
l.PushFront(func(r *request.Request) { r.Data = aws.Bool(true) })
|
||||||
|
l.Run(r)
|
||||||
|
if r.Data != nil {
|
||||||
|
t.Error("Expected handler to execute")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNamedHandlers(t *testing.T) {
|
||||||
|
l := request.HandlerList{}
|
||||||
|
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {}}
|
||||||
|
named2 := request.NamedHandler{Name: "NotName", Fn: func(r *request.Request) {}}
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
l.PushBackNamed(named2)
|
||||||
|
l.PushBack(func(r *request.Request) {})
|
||||||
|
if e, a := 4, l.Len(); e != a {
|
||||||
|
t.Errorf("expect %d list length, got %d", e, a)
|
||||||
|
}
|
||||||
|
l.Remove(named)
|
||||||
|
if e, a := 2, l.Len(); e != a {
|
||||||
|
t.Errorf("expect %d list length, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSwapHandlers(t *testing.T) {
|
||||||
|
firstHandlerCalled := 0
|
||||||
|
swappedOutHandlerCalled := 0
|
||||||
|
swappedInHandlerCalled := 0
|
||||||
|
|
||||||
|
l := request.HandlerList{}
|
||||||
|
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {
|
||||||
|
firstHandlerCalled++
|
||||||
|
}}
|
||||||
|
named2 := request.NamedHandler{Name: "SwapOutName", Fn: func(r *request.Request) {
|
||||||
|
swappedOutHandlerCalled++
|
||||||
|
}}
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
l.PushBackNamed(named2)
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
|
||||||
|
l.SwapNamed(request.NamedHandler{Name: "SwapOutName", Fn: func(r *request.Request) {
|
||||||
|
swappedInHandlerCalled++
|
||||||
|
}})
|
||||||
|
|
||||||
|
l.Run(&request.Request{})
|
||||||
|
|
||||||
|
if e, a := 2, firstHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect first handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
if n := swappedOutHandlerCalled; n != 0 {
|
||||||
|
t.Errorf("expect swapped out handler to not be called, was called %d times", n)
|
||||||
|
}
|
||||||
|
if e, a := 1, swappedInHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect swapped in handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetBackNamed_Exists(t *testing.T) {
|
||||||
|
firstHandlerCalled := 0
|
||||||
|
swappedOutHandlerCalled := 0
|
||||||
|
swappedInHandlerCalled := 0
|
||||||
|
|
||||||
|
l := request.HandlerList{}
|
||||||
|
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {
|
||||||
|
firstHandlerCalled++
|
||||||
|
}}
|
||||||
|
named2 := request.NamedHandler{Name: "SwapOutName", Fn: func(r *request.Request) {
|
||||||
|
swappedOutHandlerCalled++
|
||||||
|
}}
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
l.PushBackNamed(named2)
|
||||||
|
|
||||||
|
l.SetBackNamed(request.NamedHandler{Name: "SwapOutName", Fn: func(r *request.Request) {
|
||||||
|
swappedInHandlerCalled++
|
||||||
|
}})
|
||||||
|
|
||||||
|
l.Run(&request.Request{})
|
||||||
|
|
||||||
|
if e, a := 1, firstHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect first handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
if n := swappedOutHandlerCalled; n != 0 {
|
||||||
|
t.Errorf("expect swapped out handler to not be called, was called %d times", n)
|
||||||
|
}
|
||||||
|
if e, a := 1, swappedInHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect swapped in handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetBackNamed_NotExists(t *testing.T) {
|
||||||
|
firstHandlerCalled := 0
|
||||||
|
secondHandlerCalled := 0
|
||||||
|
swappedInHandlerCalled := 0
|
||||||
|
|
||||||
|
l := request.HandlerList{}
|
||||||
|
named := request.NamedHandler{Name: "Name", Fn: func(r *request.Request) {
|
||||||
|
firstHandlerCalled++
|
||||||
|
}}
|
||||||
|
named2 := request.NamedHandler{Name: "OtherName", Fn: func(r *request.Request) {
|
||||||
|
secondHandlerCalled++
|
||||||
|
}}
|
||||||
|
l.PushBackNamed(named)
|
||||||
|
l.PushBackNamed(named2)
|
||||||
|
|
||||||
|
l.SetBackNamed(request.NamedHandler{Name: "SwapOutName", Fn: func(r *request.Request) {
|
||||||
|
swappedInHandlerCalled++
|
||||||
|
}})
|
||||||
|
|
||||||
|
l.Run(&request.Request{})
|
||||||
|
|
||||||
|
if e, a := 1, firstHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect first handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 1, secondHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect second handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 1, swappedInHandlerCalled; e != a {
|
||||||
|
t.Errorf("expect swapped in handler to be called %d, was called %d times", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggedHandlers(t *testing.T) {
|
||||||
|
expectedHandlers := []string{"name1", "name2"}
|
||||||
|
l := request.HandlerList{}
|
||||||
|
loggedHandlers := []string{}
|
||||||
|
l.AfterEachFn = request.HandlerListLogItem
|
||||||
|
cfg := aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) {
|
||||||
|
loggedHandlers = append(loggedHandlers, args[2].(string))
|
||||||
|
})}
|
||||||
|
|
||||||
|
named1 := request.NamedHandler{Name: "name1", Fn: func(r *request.Request) {}}
|
||||||
|
named2 := request.NamedHandler{Name: "name2", Fn: func(r *request.Request) {}}
|
||||||
|
l.PushBackNamed(named1)
|
||||||
|
l.PushBackNamed(named2)
|
||||||
|
l.Run(&request.Request{Config: cfg})
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(expectedHandlers, loggedHandlers) {
|
||||||
|
t.Errorf("expect handlers executed %v to match logged handlers, %v",
|
||||||
|
expectedHandlers, loggedHandlers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStopHandlers(t *testing.T) {
|
||||||
|
l := request.HandlerList{}
|
||||||
|
stopAt := 1
|
||||||
|
l.AfterEachFn = func(item request.HandlerListRunItem) bool {
|
||||||
|
return item.Index != stopAt
|
||||||
|
}
|
||||||
|
|
||||||
|
called := 0
|
||||||
|
l.PushBackNamed(request.NamedHandler{Name: "name1", Fn: func(r *request.Request) {
|
||||||
|
called++
|
||||||
|
}})
|
||||||
|
l.PushBackNamed(request.NamedHandler{Name: "name2", Fn: func(r *request.Request) {
|
||||||
|
called++
|
||||||
|
}})
|
||||||
|
l.PushBackNamed(request.NamedHandler{Name: "name3", Fn: func(r *request.Request) {
|
||||||
|
t.Fatalf("third handler should not be called")
|
||||||
|
}})
|
||||||
|
l.Run(&request.Request{})
|
||||||
|
|
||||||
|
if e, a := 2, called; e != a {
|
||||||
|
t.Errorf("expect %d handlers called, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkNewRequest(b *testing.B) {
|
||||||
|
svc := s3.New(unit.Session)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
r, _ := svc.GetObjectRequest(nil)
|
||||||
|
if r == nil {
|
||||||
|
b.Fatal("r should not be nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHandlersCopy(b *testing.B) {
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
|
||||||
|
handlers.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Build.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Build.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Send.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Send.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Unmarshal.PushBack(func(r *request.Request) {})
|
||||||
|
handlers.Unmarshal.PushBack(func(r *request.Request) {})
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h := handlers.Copy()
|
||||||
|
if e, a := handlers.Validate.Len(), h.Validate.Len(); e != a {
|
||||||
|
b.Fatalf("expected %d handlers got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHandlersPushBack(b *testing.B) {
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h := handlers.Copy()
|
||||||
|
h.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
h.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
h.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
h.Validate.PushBack(func(r *request.Request) {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHandlersPushFront(b *testing.B) {
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h := handlers.Copy()
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkHandlersClear(b *testing.B) {
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
h := handlers.Copy()
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Validate.PushFront(func(r *request.Request) {})
|
||||||
|
h.Clear()
|
||||||
|
}
|
||||||
|
}
|
34
vendor/github.com/aws/aws-sdk-go/aws/request/http_request_copy_test.go
generated
vendored
Normal file
34
vendor/github.com/aws/aws-sdk-go/aws/request/http_request_copy_test.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRequestCopyRace(t *testing.T) {
|
||||||
|
origReq := &http.Request{URL: &url.URL{}, Header: http.Header{}}
|
||||||
|
origReq.Header.Set("Header", "OrigValue")
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
req := copyHTTPRequest(origReq, ioutil.NopCloser(&bytes.Buffer{}))
|
||||||
|
req.Header.Set("Header", "Value")
|
||||||
|
go func() {
|
||||||
|
req2 := copyHTTPRequest(req, ioutil.NopCloser(&bytes.Buffer{}))
|
||||||
|
req2.Header.Add("Header", "Value2")
|
||||||
|
}()
|
||||||
|
_ = req.Header.Get("Header")
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
_ = origReq.Header.Get("Header")
|
||||||
|
}
|
||||||
|
origReq.Header.Get("Header")
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
37
vendor/github.com/aws/aws-sdk-go/aws/request/http_request_retry_test.go
generated
vendored
Normal file
37
vendor/github.com/aws/aws-sdk-go/aws/request/http_request_retry_test.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// +build go1.5
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/mock"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRequestCancelRetry(t *testing.T) {
|
||||||
|
c := make(chan struct{})
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
s := mock.NewMockClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.Clear()
|
||||||
|
s.Handlers.UnmarshalMeta.Clear()
|
||||||
|
s.Handlers.UnmarshalError.Clear()
|
||||||
|
s.Handlers.Send.PushFront(func(r *request.Request) {
|
||||||
|
reqNum++
|
||||||
|
r.Error = errors.New("net/http: request canceled")
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
r.HTTPRequest.Cancel = c
|
||||||
|
close(c)
|
||||||
|
|
||||||
|
err := r.Send()
|
||||||
|
assert.True(t, strings.Contains(err.Error(), "canceled"))
|
||||||
|
assert.Equal(t, 1, reqNum)
|
||||||
|
}
|
139
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader_test.go
generated
vendored
Normal file
139
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader_test.go
generated
vendored
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"sync"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOffsetReaderRead(t *testing.T) {
|
||||||
|
buf := []byte("testData")
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(buf)}
|
||||||
|
|
||||||
|
tempBuf := make([]byte, len(buf))
|
||||||
|
|
||||||
|
n, err := reader.Read(tempBuf)
|
||||||
|
|
||||||
|
assert.Equal(t, n, len(buf))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, buf, tempBuf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOffsetReaderSeek(t *testing.T) {
|
||||||
|
buf := []byte("testData")
|
||||||
|
reader := newOffsetReader(bytes.NewReader(buf), 0)
|
||||||
|
|
||||||
|
orig, err := reader.Seek(0, 1)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(0), orig)
|
||||||
|
|
||||||
|
n, err := reader.Seek(0, 2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(len(buf)), n)
|
||||||
|
|
||||||
|
n, err = reader.Seek(orig, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, int64(0), n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOffsetReaderClose(t *testing.T) {
|
||||||
|
buf := []byte("testData")
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(buf)}
|
||||||
|
|
||||||
|
err := reader.Close()
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
tempBuf := make([]byte, len(buf))
|
||||||
|
n, err := reader.Read(tempBuf)
|
||||||
|
assert.Equal(t, n, 0)
|
||||||
|
assert.Equal(t, err, io.EOF)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOffsetReaderCloseAndCopy(t *testing.T) {
|
||||||
|
buf := []byte("testData")
|
||||||
|
tempBuf := make([]byte, len(buf))
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(buf)}
|
||||||
|
|
||||||
|
newReader := reader.CloseAndCopy(0)
|
||||||
|
|
||||||
|
n, err := reader.Read(tempBuf)
|
||||||
|
assert.Equal(t, n, 0)
|
||||||
|
assert.Equal(t, err, io.EOF)
|
||||||
|
|
||||||
|
n, err = newReader.Read(tempBuf)
|
||||||
|
assert.Equal(t, n, len(buf))
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, buf, tempBuf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOffsetReaderCloseAndCopyOffset(t *testing.T) {
|
||||||
|
buf := []byte("testData")
|
||||||
|
tempBuf := make([]byte, len(buf))
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(buf)}
|
||||||
|
|
||||||
|
newReader := reader.CloseAndCopy(4)
|
||||||
|
n, err := newReader.Read(tempBuf)
|
||||||
|
assert.Equal(t, n, len(buf)-4)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
expected := []byte{'D', 'a', 't', 'a', 0, 0, 0, 0}
|
||||||
|
assert.Equal(t, expected, tempBuf)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOffsetReaderRace(t *testing.T) {
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
|
f := func(reader *offsetReader) {
|
||||||
|
defer wg.Done()
|
||||||
|
var err error
|
||||||
|
buf := make([]byte, 1)
|
||||||
|
_, err = reader.Read(buf)
|
||||||
|
for err != io.EOF {
|
||||||
|
_, err = reader.Read(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
closeFn := func(reader *offsetReader) {
|
||||||
|
defer wg.Done()
|
||||||
|
time.Sleep(time.Duration(rand.Intn(20)+1) * time.Millisecond)
|
||||||
|
reader.Close()
|
||||||
|
}
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(make([]byte, 1024*1024))}
|
||||||
|
wg.Add(1)
|
||||||
|
go f(reader)
|
||||||
|
wg.Add(1)
|
||||||
|
go closeFn(reader)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkOffsetReader(b *testing.B) {
|
||||||
|
bufSize := 1024 * 1024 * 100
|
||||||
|
buf := make([]byte, bufSize)
|
||||||
|
reader := &offsetReader{buf: bytes.NewReader(buf)}
|
||||||
|
|
||||||
|
tempBuf := make([]byte, 1024)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
reader.Read(tempBuf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkBytesReader(b *testing.B) {
|
||||||
|
bufSize := 1024 * 1024 * 100
|
||||||
|
buf := make([]byte, bufSize)
|
||||||
|
reader := bytes.NewReader(buf)
|
||||||
|
|
||||||
|
tempBuf := make([]byte, 1024)
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
reader.Read(tempBuf)
|
||||||
|
}
|
||||||
|
}
|
83
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
83
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
|
@ -24,10 +24,14 @@ const (
|
||||||
// ErrCodeRead is an error that is returned during HTTP reads.
|
// ErrCodeRead is an error that is returned during HTTP reads.
|
||||||
ErrCodeRead = "ReadError"
|
ErrCodeRead = "ReadError"
|
||||||
|
|
||||||
// ErrCodeResponseTimeout is the connection timeout error that is recieved
|
// ErrCodeResponseTimeout is the connection timeout error that is received
|
||||||
// during body reads.
|
// during body reads.
|
||||||
ErrCodeResponseTimeout = "ResponseTimeout"
|
ErrCodeResponseTimeout = "ResponseTimeout"
|
||||||
|
|
||||||
|
// ErrCodeInvalidPresignExpire is returned when the expire time provided to
|
||||||
|
// presign is invalid
|
||||||
|
ErrCodeInvalidPresignExpire = "InvalidPresignExpireError"
|
||||||
|
|
||||||
// CanceledErrorCode is the error code that will be returned by an
|
// CanceledErrorCode is the error code that will be returned by an
|
||||||
// API request that was canceled. Requests given a aws.Context may
|
// API request that was canceled. Requests given a aws.Context may
|
||||||
// return this error when canceled.
|
// return this error when canceled.
|
||||||
|
@ -42,7 +46,6 @@ type Request struct {
|
||||||
|
|
||||||
Retryer
|
Retryer
|
||||||
Time time.Time
|
Time time.Time
|
||||||
ExpireTime time.Duration
|
|
||||||
Operation *Operation
|
Operation *Operation
|
||||||
HTTPRequest *http.Request
|
HTTPRequest *http.Request
|
||||||
HTTPResponse *http.Response
|
HTTPResponse *http.Response
|
||||||
|
@ -60,6 +63,11 @@ type Request struct {
|
||||||
LastSignedAt time.Time
|
LastSignedAt time.Time
|
||||||
DisableFollowRedirects bool
|
DisableFollowRedirects bool
|
||||||
|
|
||||||
|
// A value greater than 0 instructs the request to be signed as Presigned URL
|
||||||
|
// You should not set this field directly. Instead use Request's
|
||||||
|
// Presign or PresignRequest methods.
|
||||||
|
ExpireTime time.Duration
|
||||||
|
|
||||||
context aws.Context
|
context aws.Context
|
||||||
|
|
||||||
built bool
|
built bool
|
||||||
|
@ -250,34 +258,59 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||||
|
|
||||||
// Presign returns the request's signed URL. Error will be returned
|
// Presign returns the request's signed URL. Error will be returned
|
||||||
// if the signing fails.
|
// if the signing fails.
|
||||||
func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
//
|
||||||
r.ExpireTime = expireTime
|
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||||
|
// error is returned if expire duration is 0 or less.
|
||||||
|
func (r *Request) Presign(expire time.Duration) (string, error) {
|
||||||
|
r = r.copy()
|
||||||
|
|
||||||
|
// Presign requires all headers be hoisted. There is no way to retrieve
|
||||||
|
// the signed headers not hoisted without this. Making the presigned URL
|
||||||
|
// useless.
|
||||||
r.NotHoist = false
|
r.NotHoist = false
|
||||||
|
|
||||||
if r.Operation.BeforePresignFn != nil {
|
u, _, err := getPresignedURL(r, expire)
|
||||||
r = r.copy()
|
return u, err
|
||||||
err := r.Operation.BeforePresignFn(r)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Sign()
|
|
||||||
if r.Error != nil {
|
|
||||||
return "", r.Error
|
|
||||||
}
|
|
||||||
return r.HTTPRequest.URL.String(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PresignRequest behaves just like presign, but hoists all headers and signs them.
|
// PresignRequest behaves just like presign, with the addition of returning a
|
||||||
// Also returns the signed hash back to the user
|
// set of headers that were signed.
|
||||||
func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) {
|
//
|
||||||
r.ExpireTime = expireTime
|
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||||
r.NotHoist = true
|
// error is returned if expire duration is 0 or less.
|
||||||
r.Sign()
|
//
|
||||||
if r.Error != nil {
|
// Returns the URL string for the API operation with signature in the query string,
|
||||||
return "", nil, r.Error
|
// and the HTTP headers that were included in the signature. These headers must
|
||||||
|
// be included in any HTTP request made with the presigned URL.
|
||||||
|
//
|
||||||
|
// To prevent hoisting any headers to the query string set NotHoist to true on
|
||||||
|
// this Request value prior to calling PresignRequest.
|
||||||
|
func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) {
|
||||||
|
r = r.copy()
|
||||||
|
return getPresignedURL(r, expire)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) {
|
||||||
|
if expire <= 0 {
|
||||||
|
return "", nil, awserr.New(
|
||||||
|
ErrCodeInvalidPresignExpire,
|
||||||
|
"presigned URL requires an expire duration greater than 0",
|
||||||
|
nil,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.ExpireTime = expire
|
||||||
|
|
||||||
|
if r.Operation.BeforePresignFn != nil {
|
||||||
|
if err := r.Operation.BeforePresignFn(r); err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.Sign(); err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
|
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_5_test.go
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_5_test.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// +build !go1.6
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
var errTimeout = awserr.New("foo", "bar", errors.New("net/http: request canceled Timeout"))
|
51
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_6_test.go
generated
vendored
Normal file
51
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_6_test.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// +build go1.6
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
// go version 1.4 and 1.5 do not return an error. Version 1.5 will url encode
|
||||||
|
// the uri while 1.4 will not
|
||||||
|
func TestRequestInvalidEndpoint(t *testing.T) {
|
||||||
|
endpoint := "http://localhost:90 "
|
||||||
|
|
||||||
|
r := request.New(
|
||||||
|
aws.Config{},
|
||||||
|
metadata.ClientInfo{Endpoint: endpoint},
|
||||||
|
defaults.Handlers(),
|
||||||
|
client.DefaultRetryer{},
|
||||||
|
&request.Operation{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Error(t, r.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type timeoutErr struct {
|
||||||
|
error
|
||||||
|
}
|
||||||
|
|
||||||
|
var errTimeout = awserr.New("foo", "bar", &timeoutErr{
|
||||||
|
errors.New("net/http: request canceled"),
|
||||||
|
})
|
||||||
|
|
||||||
|
func (e *timeoutErr) Timeout() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *timeoutErr) Temporary() bool {
|
||||||
|
return true
|
||||||
|
}
|
24
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7_test.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7_test.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResetBody_WithEmptyBody(t *testing.T) {
|
||||||
|
r := Request{
|
||||||
|
HTTPRequest: &http.Request{},
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := strings.NewReader("")
|
||||||
|
r.Body = reader
|
||||||
|
|
||||||
|
r.ResetBody()
|
||||||
|
|
||||||
|
if a, e := r.HTTPRequest.Body, (noBody{}); a != e {
|
||||||
|
t.Errorf("expected request body to be set to reader, got %#v", r.HTTPRequest.Body)
|
||||||
|
}
|
||||||
|
}
|
85
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8_test.go
generated
vendored
Normal file
85
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8_test.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResetBody_WithEmptyBody(t *testing.T) {
|
||||||
|
r := request.Request{
|
||||||
|
HTTPRequest: &http.Request{},
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := strings.NewReader("")
|
||||||
|
r.Body = reader
|
||||||
|
|
||||||
|
r.ResetBody()
|
||||||
|
|
||||||
|
if a, e := r.HTTPRequest.Body, http.NoBody; a != e {
|
||||||
|
t.Errorf("expected request body to be set to reader, got %#v",
|
||||||
|
r.HTTPRequest.Body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequest_FollowPUTRedirects(t *testing.T) {
|
||||||
|
const bodySize = 1024
|
||||||
|
|
||||||
|
redirectHit := 0
|
||||||
|
endpointHit := 0
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/redirect-me":
|
||||||
|
u := *r.URL
|
||||||
|
u.Path = "/endpoint"
|
||||||
|
w.Header().Set("Location", u.String())
|
||||||
|
w.WriteHeader(307)
|
||||||
|
redirectHit++
|
||||||
|
case "/endpoint":
|
||||||
|
b := bytes.Buffer{}
|
||||||
|
io.Copy(&b, r.Body)
|
||||||
|
r.Body.Close()
|
||||||
|
if e, a := bodySize, b.Len(); e != a {
|
||||||
|
t.Fatalf("expect %d body size, got %d", e, a)
|
||||||
|
}
|
||||||
|
endpointHit++
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected endpoint used, %q", r.URL.String())
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
Region: unit.Session.Config.Region,
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
})
|
||||||
|
|
||||||
|
req := svc.NewRequest(&request.Operation{
|
||||||
|
Name: "Operation",
|
||||||
|
HTTPMethod: "PUT",
|
||||||
|
HTTPPath: "/redirect-me",
|
||||||
|
}, &struct{}{}, &struct{}{})
|
||||||
|
req.SetReaderBody(bytes.NewReader(make([]byte, bodySize)))
|
||||||
|
|
||||||
|
err := req.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, redirectHit; e != a {
|
||||||
|
t.Errorf("expect %d redirect hits, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 1, endpointHit; e != a {
|
||||||
|
t.Errorf("expect %d endpoint hits, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
46
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go
generated
vendored
Normal file
46
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRequest_SetContext(t *testing.T) {
|
||||||
|
svc := awstesting.NewClient()
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||||
|
|
||||||
|
r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
r.SetContext(ctx)
|
||||||
|
|
||||||
|
ctx.Error = fmt.Errorf("context canceled")
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
|
||||||
|
err := r.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only check against canceled because go 1.6 will not use the context's
|
||||||
|
// Err().
|
||||||
|
if e, a := "canceled", err.Error(); !strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %q to be in %q, but was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequest_SetContextPanic(t *testing.T) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r == nil {
|
||||||
|
t.Fatalf("expect SetContext to panic, did not")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
r := &request.Request{}
|
||||||
|
|
||||||
|
r.SetContext(nil)
|
||||||
|
}
|
27
vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go
generated
vendored
Normal file
27
vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCopy(t *testing.T) {
|
||||||
|
handlers := Handlers{}
|
||||||
|
op := &Operation{}
|
||||||
|
op.HTTPMethod = "Foo"
|
||||||
|
req := &Request{}
|
||||||
|
req.Operation = op
|
||||||
|
req.Handlers = handlers
|
||||||
|
|
||||||
|
r := req.copy()
|
||||||
|
|
||||||
|
if r == req {
|
||||||
|
t.Fatal("expect request pointer copy to be different")
|
||||||
|
}
|
||||||
|
if r.Operation == req.Operation {
|
||||||
|
t.Errorf("expect request operation pointer to be different")
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := req.Operation.HTTPMethod, r.Operation.HTTPMethod; e != a {
|
||||||
|
t.Errorf("expect %q http method, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
604
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go
generated
vendored
Normal file
604
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go
generated
vendored
Normal file
|
@ -0,0 +1,604 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/dynamodb"
|
||||||
|
"github.com/aws/aws-sdk-go/service/route53"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Use DynamoDB methods for simplicity
|
||||||
|
func TestPaginationQueryPage(t *testing.T) {
|
||||||
|
db := dynamodb.New(unit.Session)
|
||||||
|
tokens, pages, numPages, gotToEnd := []map[string]*dynamodb.AttributeValue{}, []map[string]*dynamodb.AttributeValue{}, 0, false
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*dynamodb.QueryOutput{
|
||||||
|
{
|
||||||
|
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key1")}},
|
||||||
|
Count: aws.Int64(1),
|
||||||
|
Items: []map[string]*dynamodb.AttributeValue{
|
||||||
|
{
|
||||||
|
"key": {S: aws.String("key1")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{"key": {S: aws.String("key2")}},
|
||||||
|
Count: aws.Int64(1),
|
||||||
|
Items: []map[string]*dynamodb.AttributeValue{
|
||||||
|
{
|
||||||
|
"key": {S: aws.String("key2")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
LastEvaluatedKey: map[string]*dynamodb.AttributeValue{},
|
||||||
|
Count: aws.Int64(1),
|
||||||
|
Items: []map[string]*dynamodb.AttributeValue{
|
||||||
|
{
|
||||||
|
"key": {S: aws.String("key3")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Handlers.Send.Clear() // mock sending
|
||||||
|
db.Handlers.Unmarshal.Clear()
|
||||||
|
db.Handlers.UnmarshalMeta.Clear()
|
||||||
|
db.Handlers.ValidateResponse.Clear()
|
||||||
|
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
in := r.Params.(*dynamodb.QueryInput)
|
||||||
|
if in == nil {
|
||||||
|
tokens = append(tokens, nil)
|
||||||
|
} else if len(in.ExclusiveStartKey) != 0 {
|
||||||
|
tokens = append(tokens, in.ExclusiveStartKey)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &dynamodb.QueryInput{
|
||||||
|
Limit: aws.Int64(2),
|
||||||
|
TableName: aws.String("tablename"),
|
||||||
|
}
|
||||||
|
err := db.QueryPages(params, func(p *dynamodb.QueryOutput, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
for _, item := range p.Items {
|
||||||
|
pages = append(pages, item)
|
||||||
|
}
|
||||||
|
if last {
|
||||||
|
if gotToEnd {
|
||||||
|
assert.Fail(t, "last=true happened twice")
|
||||||
|
}
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t,
|
||||||
|
[]map[string]*dynamodb.AttributeValue{
|
||||||
|
{"key": {S: aws.String("key1")}},
|
||||||
|
{"key": {S: aws.String("key2")}},
|
||||||
|
}, tokens)
|
||||||
|
assert.Equal(t,
|
||||||
|
[]map[string]*dynamodb.AttributeValue{
|
||||||
|
{"key": {S: aws.String("key1")}},
|
||||||
|
{"key": {S: aws.String("key2")}},
|
||||||
|
{"key": {S: aws.String("key3")}},
|
||||||
|
}, pages)
|
||||||
|
assert.Equal(t, 3, numPages)
|
||||||
|
assert.True(t, gotToEnd)
|
||||||
|
assert.Nil(t, params.ExclusiveStartKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use DynamoDB methods for simplicity
|
||||||
|
func TestPagination(t *testing.T) {
|
||||||
|
db := dynamodb.New(unit.Session)
|
||||||
|
tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*dynamodb.ListTablesOutput{
|
||||||
|
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||||
|
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||||
|
{TableNames: []*string{aws.String("Table5")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Handlers.Send.Clear() // mock sending
|
||||||
|
db.Handlers.Unmarshal.Clear()
|
||||||
|
db.Handlers.UnmarshalMeta.Clear()
|
||||||
|
db.Handlers.ValidateResponse.Clear()
|
||||||
|
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
in := r.Params.(*dynamodb.ListTablesInput)
|
||||||
|
if in == nil {
|
||||||
|
tokens = append(tokens, "")
|
||||||
|
} else if in.ExclusiveStartTableName != nil {
|
||||||
|
tokens = append(tokens, *in.ExclusiveStartTableName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||||
|
err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
for _, t := range p.TableNames {
|
||||||
|
pages = append(pages, *t)
|
||||||
|
}
|
||||||
|
if last {
|
||||||
|
if gotToEnd {
|
||||||
|
assert.Fail(t, "last=true happened twice")
|
||||||
|
}
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Table2", "Table4"}, tokens)
|
||||||
|
assert.Equal(t, []string{"Table1", "Table2", "Table3", "Table4", "Table5"}, pages)
|
||||||
|
assert.Equal(t, 3, numPages)
|
||||||
|
assert.True(t, gotToEnd)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Nil(t, params.ExclusiveStartTableName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use DynamoDB methods for simplicity
|
||||||
|
func TestPaginationEachPage(t *testing.T) {
|
||||||
|
db := dynamodb.New(unit.Session)
|
||||||
|
tokens, pages, numPages, gotToEnd := []string{}, []string{}, 0, false
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*dynamodb.ListTablesOutput{
|
||||||
|
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||||
|
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||||
|
{TableNames: []*string{aws.String("Table5")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Handlers.Send.Clear() // mock sending
|
||||||
|
db.Handlers.Unmarshal.Clear()
|
||||||
|
db.Handlers.UnmarshalMeta.Clear()
|
||||||
|
db.Handlers.ValidateResponse.Clear()
|
||||||
|
db.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
in := r.Params.(*dynamodb.ListTablesInput)
|
||||||
|
if in == nil {
|
||||||
|
tokens = append(tokens, "")
|
||||||
|
} else if in.ExclusiveStartTableName != nil {
|
||||||
|
tokens = append(tokens, *in.ExclusiveStartTableName)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||||
|
req, _ := db.ListTablesRequest(params)
|
||||||
|
err := req.EachPage(func(p interface{}, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
for _, t := range p.(*dynamodb.ListTablesOutput).TableNames {
|
||||||
|
pages = append(pages, *t)
|
||||||
|
}
|
||||||
|
if last {
|
||||||
|
if gotToEnd {
|
||||||
|
assert.Fail(t, "last=true happened twice")
|
||||||
|
}
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Table2", "Table4"}, tokens)
|
||||||
|
assert.Equal(t, []string{"Table1", "Table2", "Table3", "Table4", "Table5"}, pages)
|
||||||
|
assert.Equal(t, 3, numPages)
|
||||||
|
assert.True(t, gotToEnd)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use DynamoDB methods for simplicity
|
||||||
|
func TestPaginationEarlyExit(t *testing.T) {
|
||||||
|
db := dynamodb.New(unit.Session)
|
||||||
|
numPages, gotToEnd := 0, false
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*dynamodb.ListTablesOutput{
|
||||||
|
{TableNames: []*string{aws.String("Table1"), aws.String("Table2")}, LastEvaluatedTableName: aws.String("Table2")},
|
||||||
|
{TableNames: []*string{aws.String("Table3"), aws.String("Table4")}, LastEvaluatedTableName: aws.String("Table4")},
|
||||||
|
{TableNames: []*string{aws.String("Table5")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
db.Handlers.Send.Clear() // mock sending
|
||||||
|
db.Handlers.Unmarshal.Clear()
|
||||||
|
db.Handlers.UnmarshalMeta.Clear()
|
||||||
|
db.Handlers.ValidateResponse.Clear()
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||||
|
err := db.ListTablesPages(params, func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
if numPages == 2 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if last {
|
||||||
|
if gotToEnd {
|
||||||
|
assert.Fail(t, "last=true happened twice")
|
||||||
|
}
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, 2, numPages)
|
||||||
|
assert.False(t, gotToEnd)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSkipPagination(t *testing.T) {
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = &s3.HeadBucketOutput{}
|
||||||
|
})
|
||||||
|
|
||||||
|
req, _ := client.HeadBucketRequest(&s3.HeadBucketInput{Bucket: aws.String("bucket")})
|
||||||
|
|
||||||
|
numPages, gotToEnd := 0, false
|
||||||
|
req.EachPage(func(p interface{}, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
if last {
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
assert.Equal(t, 1, numPages)
|
||||||
|
assert.True(t, gotToEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use S3 for simplicity
|
||||||
|
func TestPaginationTruncation(t *testing.T) {
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*s3.ListObjectsOutput{
|
||||||
|
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key1")}}},
|
||||||
|
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key2")}}},
|
||||||
|
{IsTruncated: aws.Bool(false), Contents: []*s3.Object{{Key: aws.String("Key3")}}},
|
||||||
|
{IsTruncated: aws.Bool(true), Contents: []*s3.Object{{Key: aws.String("Key4")}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &s3.ListObjectsInput{Bucket: aws.String("bucket")}
|
||||||
|
|
||||||
|
results := []string{}
|
||||||
|
err := client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||||
|
results = append(results, *p.Contents[0].Key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Key1", "Key2", "Key3"}, results)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
// Try again without truncation token at all
|
||||||
|
reqNum = 0
|
||||||
|
resps[1].IsTruncated = nil
|
||||||
|
resps[2].IsTruncated = aws.Bool(true)
|
||||||
|
results = []string{}
|
||||||
|
err = client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||||
|
results = append(results, *p.Contents[0].Key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Equal(t, []string{"Key1", "Key2"}, results)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPaginationNilToken(t *testing.T) {
|
||||||
|
client := route53.New(unit.Session)
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*route53.ListResourceRecordSetsOutput{
|
||||||
|
{
|
||||||
|
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||||
|
{Name: aws.String("first.example.com.")},
|
||||||
|
},
|
||||||
|
IsTruncated: aws.Bool(true),
|
||||||
|
NextRecordName: aws.String("second.example.com."),
|
||||||
|
NextRecordType: aws.String("MX"),
|
||||||
|
NextRecordIdentifier: aws.String("second"),
|
||||||
|
MaxItems: aws.String("1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||||
|
{Name: aws.String("second.example.com.")},
|
||||||
|
},
|
||||||
|
IsTruncated: aws.Bool(true),
|
||||||
|
NextRecordName: aws.String("third.example.com."),
|
||||||
|
NextRecordType: aws.String("MX"),
|
||||||
|
MaxItems: aws.String("1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceRecordSets: []*route53.ResourceRecordSet{
|
||||||
|
{Name: aws.String("third.example.com.")},
|
||||||
|
},
|
||||||
|
IsTruncated: aws.Bool(false),
|
||||||
|
MaxItems: aws.String("1"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
idents := []string{}
|
||||||
|
client.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
p := r.Params.(*route53.ListResourceRecordSetsInput)
|
||||||
|
idents = append(idents, aws.StringValue(p.StartRecordIdentifier))
|
||||||
|
|
||||||
|
})
|
||||||
|
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
params := &route53.ListResourceRecordSetsInput{
|
||||||
|
HostedZoneId: aws.String("id-zone"),
|
||||||
|
}
|
||||||
|
|
||||||
|
results := []string{}
|
||||||
|
err := client.ListResourceRecordSetsPages(params, func(p *route53.ListResourceRecordSetsOutput, last bool) bool {
|
||||||
|
results = append(results, *p.ResourceRecordSets[0].Name)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, []string{"", "second", ""}, idents)
|
||||||
|
assert.Equal(t, []string{"first.example.com.", "second.example.com.", "third.example.com."}, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPaginationNilInput(t *testing.T) {
|
||||||
|
// Code generation doesn't have a great way to verify the code is correct
|
||||||
|
// other than being run via unit tests in the SDK. This should be fixed
|
||||||
|
// So code generation can be validated independently.
|
||||||
|
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
client.Handlers.Validate.Clear()
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = &s3.ListObjectsOutput{}
|
||||||
|
})
|
||||||
|
|
||||||
|
gotToEnd := false
|
||||||
|
numPages := 0
|
||||||
|
err := client.ListObjectsPages(nil, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
if last {
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, numPages; e != a {
|
||||||
|
t.Errorf("expect %d number pages but got %d", e, a)
|
||||||
|
}
|
||||||
|
if !gotToEnd {
|
||||||
|
t.Errorf("expect to of gotten to end, did not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPaginationWithContextNilInput(t *testing.T) {
|
||||||
|
// Code generation doesn't have a great way to verify the code is correct
|
||||||
|
// other than being run via unit tests in the SDK. This should be fixed
|
||||||
|
// So code generation can be validated independently.
|
||||||
|
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
client.Handlers.Validate.Clear()
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
client.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = &s3.ListObjectsOutput{}
|
||||||
|
})
|
||||||
|
|
||||||
|
gotToEnd := false
|
||||||
|
numPages := 0
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
err := client.ListObjectsPagesWithContext(ctx, nil, func(p *s3.ListObjectsOutput, last bool) bool {
|
||||||
|
numPages++
|
||||||
|
if last {
|
||||||
|
gotToEnd = true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, numPages; e != a {
|
||||||
|
t.Errorf("expect %d number pages but got %d", e, a)
|
||||||
|
}
|
||||||
|
if !gotToEnd {
|
||||||
|
t.Errorf("expect to of gotten to end, did not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testPageInput struct {
|
||||||
|
NextToken string
|
||||||
|
}
|
||||||
|
type testPageOutput struct {
|
||||||
|
Value string
|
||||||
|
NextToken *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPagination_Standalone(t *testing.T) {
|
||||||
|
expect := []struct {
|
||||||
|
Value, PrevToken, NextToken string
|
||||||
|
}{
|
||||||
|
{"FirstValue", "InitalToken", "FirstToken"},
|
||||||
|
{"SecondValue", "FirstToken", "SecondToken"},
|
||||||
|
{"ThirdValue", "SecondToken", ""},
|
||||||
|
}
|
||||||
|
input := testPageInput{
|
||||||
|
NextToken: expect[0].PrevToken,
|
||||||
|
}
|
||||||
|
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
i := 0
|
||||||
|
p := request.Pagination{
|
||||||
|
NewRequest: func() (*request.Request, error) {
|
||||||
|
r := c.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "Operation",
|
||||||
|
Paginator: &request.Paginator{
|
||||||
|
InputTokens: []string{"NextToken"},
|
||||||
|
OutputTokens: []string{"NextToken"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&input, &testPageOutput{},
|
||||||
|
)
|
||||||
|
// Setup handlers for testing
|
||||||
|
r.Handlers.Clear()
|
||||||
|
r.Handlers.Build.PushBack(func(req *request.Request) {
|
||||||
|
in := req.Params.(*testPageInput)
|
||||||
|
if e, a := expect[i].PrevToken, in.NextToken; e != a {
|
||||||
|
t.Errorf("%d, expect NextToken input %q, got %q", i, e, a)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
r.Handlers.Unmarshal.PushBack(func(req *request.Request) {
|
||||||
|
out := &testPageOutput{
|
||||||
|
Value: expect[i].Value,
|
||||||
|
}
|
||||||
|
if len(expect[i].NextToken) > 0 {
|
||||||
|
out.NextToken = aws.String(expect[i].NextToken)
|
||||||
|
}
|
||||||
|
req.Data = out
|
||||||
|
})
|
||||||
|
return r, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for p.Next() {
|
||||||
|
data := p.Page().(*testPageOutput)
|
||||||
|
|
||||||
|
if e, a := expect[i].Value, data.Value; e != a {
|
||||||
|
t.Errorf("%d, expect Value to be %q, got %q", i, e, a)
|
||||||
|
}
|
||||||
|
if e, a := expect[i].NextToken, aws.StringValue(data.NextToken); e != a {
|
||||||
|
t.Errorf("%d, expect NextToken to be %q, got %q", i, e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if e, a := len(expect), i; e != a {
|
||||||
|
t.Errorf("expected to process %d pages, did %d", e, a)
|
||||||
|
}
|
||||||
|
if err := p.Err(); err != nil {
|
||||||
|
t.Fatalf("%d, expected no error, got %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmarks
|
||||||
|
var benchResps = []*dynamodb.ListTablesOutput{
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")},
|
||||||
|
{TableNames: []*string{aws.String("TABLE")}},
|
||||||
|
}
|
||||||
|
|
||||||
|
var benchDb = func() *dynamodb.DynamoDB {
|
||||||
|
db := dynamodb.New(unit.Session)
|
||||||
|
db.Handlers.Send.Clear() // mock sending
|
||||||
|
db.Handlers.Unmarshal.Clear()
|
||||||
|
db.Handlers.UnmarshalMeta.Clear()
|
||||||
|
db.Handlers.ValidateResponse.Clear()
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCodegenIterator(b *testing.B) {
|
||||||
|
reqNum := 0
|
||||||
|
db := benchDb()
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = benchResps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||||
|
iter := func(fn func(*dynamodb.ListTablesOutput, bool) bool) error {
|
||||||
|
page, _ := db.ListTablesRequest(input)
|
||||||
|
for ; page != nil; page = page.NextPage() {
|
||||||
|
page.Send()
|
||||||
|
out := page.Data.(*dynamodb.ListTablesOutput)
|
||||||
|
if result := fn(out, !page.HasNextPage()); page.Error != nil || !result {
|
||||||
|
return page.Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
reqNum = 0
|
||||||
|
iter(func(p *dynamodb.ListTablesOutput, last bool) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkEachPageIterator(b *testing.B) {
|
||||||
|
reqNum := 0
|
||||||
|
db := benchDb()
|
||||||
|
db.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
r.Data = benchResps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
input := &dynamodb.ListTablesInput{Limit: aws.Int64(2)}
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
reqNum = 0
|
||||||
|
req, _ := db.ListTablesRequest(input)
|
||||||
|
req.EachPage(func(p interface{}, last bool) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
58
vendor/github.com/aws/aws-sdk-go/aws/request/request_resetbody_test.go
generated
vendored
Normal file
58
vendor/github.com/aws/aws-sdk-go/aws/request/request_resetbody_test.go
generated
vendored
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResetBody_WithBodyContents(t *testing.T) {
|
||||||
|
r := Request{
|
||||||
|
HTTPRequest: &http.Request{},
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := strings.NewReader("abc")
|
||||||
|
r.Body = reader
|
||||||
|
|
||||||
|
r.ResetBody()
|
||||||
|
|
||||||
|
if v, ok := r.HTTPRequest.Body.(*offsetReader); !ok || v == nil {
|
||||||
|
t.Errorf("expected request body to be set to reader, got %#v",
|
||||||
|
r.HTTPRequest.Body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResetBody_ExcludeUnseekableBodyByMethod(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Method string
|
||||||
|
IsNoBody bool
|
||||||
|
}{
|
||||||
|
{"GET", true},
|
||||||
|
{"HEAD", true},
|
||||||
|
{"DELETE", true},
|
||||||
|
{"PUT", false},
|
||||||
|
{"PATCH", false},
|
||||||
|
{"POST", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
reader := aws.ReadSeekCloser(bytes.NewBuffer([]byte("abc")))
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
r := Request{
|
||||||
|
HTTPRequest: &http.Request{},
|
||||||
|
Operation: &Operation{
|
||||||
|
HTTPMethod: c.Method,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
r.SetReaderBody(reader)
|
||||||
|
|
||||||
|
if a, e := r.HTTPRequest.Body == NoBody, c.IsNoBody; a != e {
|
||||||
|
t.Errorf("%d, expect body to be set to noBody(%t), but was %t", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
962
vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go
generated
vendored
Normal file
962
vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go
generated
vendored
Normal file
|
@ -0,0 +1,962 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||||
|
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testData struct {
|
||||||
|
Data string
|
||||||
|
}
|
||||||
|
|
||||||
|
func body(str string) io.ReadCloser {
|
||||||
|
return ioutil.NopCloser(bytes.NewReader([]byte(str)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshal(req *request.Request) {
|
||||||
|
defer req.HTTPResponse.Body.Close()
|
||||||
|
if req.Data != nil {
|
||||||
|
json.NewDecoder(req.HTTPResponse.Body).Decode(req.Data)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalError(req *request.Request) {
|
||||||
|
bodyBytes, err := ioutil.ReadAll(req.HTTPResponse.Body)
|
||||||
|
if err != nil {
|
||||||
|
req.Error = awserr.New("UnmarshaleError", req.HTTPResponse.Status, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(bodyBytes) == 0 {
|
||||||
|
req.Error = awserr.NewRequestFailure(
|
||||||
|
awserr.New("UnmarshaleError", req.HTTPResponse.Status, fmt.Errorf("empty body")),
|
||||||
|
req.HTTPResponse.StatusCode,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var jsonErr jsonErrorResponse
|
||||||
|
if err := json.Unmarshal(bodyBytes, &jsonErr); err != nil {
|
||||||
|
req.Error = awserr.New("UnmarshaleError", "JSON unmarshal", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
req.Error = awserr.NewRequestFailure(
|
||||||
|
awserr.New(jsonErr.Code, jsonErr.Message, nil),
|
||||||
|
req.HTTPResponse.StatusCode,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
type jsonErrorResponse struct {
|
||||||
|
Code string `json:"__type"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that retries occur for 5xx status codes
|
||||||
|
func TestRequestRecoverRetry5xx(t *testing.T) {
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []http.Response{
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 501, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &reqs[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 2, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "valid", out.Data; e != a {
|
||||||
|
t.Errorf("expect %q output got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that retries occur for 4xx status codes with a response type that can be retried - see `shouldRetry`
|
||||||
|
func TestRequestRecoverRetry4xxRetryable(t *testing.T) {
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []http.Response{
|
||||||
|
{StatusCode: 400, Body: body(`{"__type":"Throttling","message":"Rate exceeded."}`)},
|
||||||
|
{StatusCode: 400, Body: body(`{"__type":"ProvisionedThroughputExceededException","message":"Rate exceeded."}`)},
|
||||||
|
{StatusCode: 429, Body: body(`{"__type":"FooException","message":"Rate exceeded."}`)},
|
||||||
|
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &reqs[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 3, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "valid", out.Data; e != a {
|
||||||
|
t.Errorf("expect %q output got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that retries don't occur for 4xx status codes with a response type that can't be retried
|
||||||
|
func TestRequest4xxUnretryable(t *testing.T) {
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{StatusCode: 401, Body: body(`{"__type":"SignatureDoesNotMatch","message":"Signature does not match."}`)}
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, but did not get one")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.RequestFailure)
|
||||||
|
if e, a := 401, aerr.StatusCode(); e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "SignatureDoesNotMatch", aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "Signature does not match.", aerr.Message(); e != a {
|
||||||
|
t.Errorf("expect %q error message, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 0, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestExhaustRetries(t *testing.T) {
|
||||||
|
delays := []time.Duration{}
|
||||||
|
sleepDelay := func(delay time.Duration) {
|
||||||
|
delays = append(delays, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []http.Response{
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"UnknownError","message":"An error occurred."}`)},
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithSleepDelay(sleepDelay))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &reqs[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
err := r.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, but did not get one")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.RequestFailure)
|
||||||
|
if e, a := 500, aerr.StatusCode(); e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "UnknownError", aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "An error occurred.", aerr.Message(); e != a {
|
||||||
|
t.Errorf("expect %q error message, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 3, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectDelays := []struct{ min, max time.Duration }{{30, 59}, {60, 118}, {120, 236}}
|
||||||
|
for i, v := range delays {
|
||||||
|
min := expectDelays[i].min * time.Millisecond
|
||||||
|
max := expectDelays[i].max * time.Millisecond
|
||||||
|
if !(min <= v && v <= max) {
|
||||||
|
t.Errorf("Expect delay to be within range, i:%d, v:%s, min:%s, max:%s",
|
||||||
|
i, v, min, max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that the request is retried after the credentials are expired.
|
||||||
|
func TestRequestRecoverExpiredCreds(t *testing.T) {
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []http.Response{
|
||||||
|
{StatusCode: 400, Body: body(`{"__type":"ExpiredTokenException","message":"expired token"}`)},
|
||||||
|
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(&aws.Config{MaxRetries: aws.Int(10), Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "")})
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
|
||||||
|
credExpiredBeforeRetry := false
|
||||||
|
credExpiredAfterRetry := false
|
||||||
|
|
||||||
|
s.Handlers.AfterRetry.PushBack(func(r *request.Request) {
|
||||||
|
credExpiredAfterRetry = r.Config.Credentials.IsExpired()
|
||||||
|
})
|
||||||
|
|
||||||
|
s.Handlers.Sign.Clear()
|
||||||
|
s.Handlers.Sign.PushBack(func(r *request.Request) {
|
||||||
|
r.Config.Credentials.Get()
|
||||||
|
})
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &reqs[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if credExpiredBeforeRetry {
|
||||||
|
t.Errorf("Expect valid creds before retry check")
|
||||||
|
}
|
||||||
|
if !credExpiredAfterRetry {
|
||||||
|
t.Errorf("Expect expired creds after retry check")
|
||||||
|
}
|
||||||
|
if s.Config.Credentials.IsExpired() {
|
||||||
|
t.Errorf("Expect valid creds after cred expired recovery")
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := 1, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "valid", out.Data; e != a {
|
||||||
|
t.Errorf("expect %q output got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMakeAddtoUserAgentHandler(t *testing.T) {
|
||||||
|
fn := request.MakeAddToUserAgentHandler("name", "version", "extra1", "extra2")
|
||||||
|
r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
|
||||||
|
r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||||
|
fn(r)
|
||||||
|
|
||||||
|
if e, a := "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"); e != a {
|
||||||
|
t.Errorf("expect %q user agent, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMakeAddtoUserAgentFreeFormHandler(t *testing.T) {
|
||||||
|
fn := request.MakeAddToUserAgentFreeFormHandler("name/version (extra1; extra2)")
|
||||||
|
r := &request.Request{HTTPRequest: &http.Request{Header: http.Header{}}}
|
||||||
|
r.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||||
|
fn(r)
|
||||||
|
|
||||||
|
if e, a := "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"); e != a {
|
||||||
|
t.Errorf("expect %q user agent, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestUserAgent(t *testing.T) {
|
||||||
|
s := awstesting.NewClient(&aws.Config{Region: aws.String("us-east-1")})
|
||||||
|
// s.Handlers.Validate.Clear()
|
||||||
|
|
||||||
|
req := s.NewRequest(&request.Operation{Name: "Operation"}, nil, &testData{})
|
||||||
|
req.HTTPRequest.Header.Set("User-Agent", "foo/bar")
|
||||||
|
if err := req.Build(); err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectUA := fmt.Sprintf("foo/bar %s/%s (%s; %s; %s)",
|
||||||
|
aws.SDKName, aws.SDKVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||||
|
if e, a := expectUA, req.HTTPRequest.Header.Get("User-Agent"); e != a {
|
||||||
|
t.Errorf("expect %q user agent, got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestThrottleRetries(t *testing.T) {
|
||||||
|
delays := []time.Duration{}
|
||||||
|
sleepDelay := func(delay time.Duration) {
|
||||||
|
delays = append(delays, delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []http.Response{
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"Throttling","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"Throttling","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"Throttling","message":"An error occurred."}`)},
|
||||||
|
{StatusCode: 500, Body: body(`{"__type":"Throttling","message":"An error occurred."}`)},
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithSleepDelay(sleepDelay))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &reqs[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
err := r.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, but did not get one")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.RequestFailure)
|
||||||
|
if e, a := 500, aerr.StatusCode(); e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "Throttling", aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "An error occurred.", aerr.Message(); e != a {
|
||||||
|
t.Errorf("expect %q error message, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 3, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectDelays := []struct{ min, max time.Duration }{{500, 999}, {1000, 1998}, {2000, 3996}}
|
||||||
|
for i, v := range delays {
|
||||||
|
min := expectDelays[i].min * time.Millisecond
|
||||||
|
max := expectDelays[i].max * time.Millisecond
|
||||||
|
if !(min <= v && v <= max) {
|
||||||
|
t.Errorf("Expect delay to be within range, i:%d, v:%s, min:%s, max:%s",
|
||||||
|
i, v, min, max)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// test that retries occur for request timeouts when response.Body can be nil
|
||||||
|
func TestRequestRecoverTimeoutWithNilBody(t *testing.T) {
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []*http.Response{
|
||||||
|
{StatusCode: 0, Body: nil}, // body can be nil when requests time out
|
||||||
|
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||||
|
}
|
||||||
|
errors := []error{
|
||||||
|
errTimeout, nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.AfterRetry.Clear() // force retry on all errors
|
||||||
|
s.Handlers.AfterRetry.PushBack(func(r *request.Request) {
|
||||||
|
if r.Error != nil {
|
||||||
|
r.Error = nil
|
||||||
|
r.Retryable = aws.Bool(true)
|
||||||
|
r.RetryCount++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = reqs[reqNum]
|
||||||
|
r.Error = errors[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "valid", out.Data; e != a {
|
||||||
|
t.Errorf("expect %q output got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestRecoverTimeoutWithNilResponse(t *testing.T) {
|
||||||
|
reqNum := 0
|
||||||
|
reqs := []*http.Response{
|
||||||
|
nil,
|
||||||
|
{StatusCode: 200, Body: body(`{"data":"valid"}`)},
|
||||||
|
}
|
||||||
|
errors := []error{
|
||||||
|
errTimeout,
|
||||||
|
nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
s := awstesting.NewClient(aws.NewConfig().WithMaxRetries(10))
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
s.Handlers.AfterRetry.Clear() // force retry on all errors
|
||||||
|
s.Handlers.AfterRetry.PushBack(func(r *request.Request) {
|
||||||
|
if r.Error != nil {
|
||||||
|
r.Error = nil
|
||||||
|
r.Retryable = aws.Bool(true)
|
||||||
|
r.RetryCount++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
s.Handlers.Send.Clear() // mock sending
|
||||||
|
s.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = reqs[reqNum]
|
||||||
|
r.Error = errors[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "valid", out.Data; e != a {
|
||||||
|
t.Errorf("expect %q output got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequest_NoBody(t *testing.T) {
|
||||||
|
cases := []string{
|
||||||
|
"GET", "HEAD", "DELETE",
|
||||||
|
"PUT", "POST", "PATCH",
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if v := r.TransferEncoding; len(v) > 0 {
|
||||||
|
t.Errorf("%d, expect no body sent with Transfer-Encoding, %v", i, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
outMsg := []byte(`{"Value": "abc"}`)
|
||||||
|
|
||||||
|
if b, err := ioutil.ReadAll(r.Body); err != nil {
|
||||||
|
t.Fatalf("%d, expect no error reading request body, got %v", i, err)
|
||||||
|
} else if n := len(b); n > 0 {
|
||||||
|
t.Errorf("%d, expect no request body, got %d bytes", i, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Length", strconv.Itoa(len(outMsg)))
|
||||||
|
if _, err := w.Write(outMsg); err != nil {
|
||||||
|
t.Fatalf("%d, expect no error writing server response, got %v", i, err)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
s := awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
MaxRetries: aws.Int(0),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
})
|
||||||
|
s.Handlers.Build.PushBack(rest.Build)
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
|
||||||
|
in := struct {
|
||||||
|
Bucket *string `location:"uri" locationName:"bucket"`
|
||||||
|
Key *string `location:"uri" locationName:"key"`
|
||||||
|
}{
|
||||||
|
Bucket: aws.String("mybucket"), Key: aws.String("myKey"),
|
||||||
|
}
|
||||||
|
|
||||||
|
out := struct {
|
||||||
|
Value *string
|
||||||
|
}{}
|
||||||
|
|
||||||
|
r := s.NewRequest(&request.Operation{
|
||||||
|
Name: "OpName", HTTPMethod: c, HTTPPath: "/{bucket}/{key+}",
|
||||||
|
}, &in, &out)
|
||||||
|
|
||||||
|
if err := r.Send(); err != nil {
|
||||||
|
t.Fatalf("%d, expect no error sending request, got %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsSerializationErrorRetryable(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
err error
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
err: awserr.New(request.ErrCodeSerialization, "foo error", nil),
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: awserr.New("ErrFoo", "foo error", nil),
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: nil,
|
||||||
|
expected: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
err: awserr.New(request.ErrCodeSerialization, "foo error", stubConnectionResetError),
|
||||||
|
expected: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range testCases {
|
||||||
|
r := &request.Request{
|
||||||
|
Error: c.err,
|
||||||
|
}
|
||||||
|
if r.IsErrorRetryable() != c.expected {
|
||||||
|
t.Errorf("Case %d: Expected %v, but received %v", i+1, c.expected, !c.expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithLogLevel(t *testing.T) {
|
||||||
|
r := &request.Request{}
|
||||||
|
|
||||||
|
opt := request.WithLogLevel(aws.LogDebugWithHTTPBody)
|
||||||
|
r.ApplyOptions(opt)
|
||||||
|
|
||||||
|
if !r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) {
|
||||||
|
t.Errorf("expect log level to be set, but was not, %v",
|
||||||
|
r.Config.LogLevel.Value())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithGetResponseHeader(t *testing.T) {
|
||||||
|
r := &request.Request{}
|
||||||
|
|
||||||
|
var val, val2 string
|
||||||
|
r.ApplyOptions(
|
||||||
|
request.WithGetResponseHeader("x-a-header", &val),
|
||||||
|
request.WithGetResponseHeader("x-second-header", &val2),
|
||||||
|
)
|
||||||
|
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
Header: func() http.Header {
|
||||||
|
h := http.Header{}
|
||||||
|
h.Set("x-a-header", "first")
|
||||||
|
h.Set("x-second-header", "second")
|
||||||
|
return h
|
||||||
|
}(),
|
||||||
|
}
|
||||||
|
r.Handlers.Complete.Run(r)
|
||||||
|
|
||||||
|
if e, a := "first", val; e != a {
|
||||||
|
t.Errorf("expect %q header value got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "second", val2; e != a {
|
||||||
|
t.Errorf("expect %q header value got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithGetResponseHeaders(t *testing.T) {
|
||||||
|
r := &request.Request{}
|
||||||
|
|
||||||
|
var headers http.Header
|
||||||
|
opt := request.WithGetResponseHeaders(&headers)
|
||||||
|
|
||||||
|
r.ApplyOptions(opt)
|
||||||
|
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
Header: func() http.Header {
|
||||||
|
h := http.Header{}
|
||||||
|
h.Set("x-a-header", "headerValue")
|
||||||
|
return h
|
||||||
|
}(),
|
||||||
|
}
|
||||||
|
r.Handlers.Complete.Run(r)
|
||||||
|
|
||||||
|
if e, a := "headerValue", headers.Get("x-a-header"); e != a {
|
||||||
|
t.Errorf("expect %q header value got %q", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type connResetCloser struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *connResetCloser) Read(b []byte) (int, error) {
|
||||||
|
return 0, stubConnectionResetError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rc *connResetCloser) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSerializationErrConnectionReset(t *testing.T) {
|
||||||
|
count := 0
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
count++
|
||||||
|
r.HTTPResponse = &http.Response{}
|
||||||
|
r.HTTPResponse.Body = &connResetCloser{}
|
||||||
|
})
|
||||||
|
|
||||||
|
handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||||
|
handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||||
|
handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||||
|
handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||||
|
handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
|
||||||
|
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||||
|
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "op",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
meta := metadata.ClientInfo{
|
||||||
|
ServiceName: "fooService",
|
||||||
|
SigningName: "foo",
|
||||||
|
SigningRegion: "foo",
|
||||||
|
Endpoint: "localhost",
|
||||||
|
APIVersion: "2001-01-01",
|
||||||
|
JSONVersion: "1.1",
|
||||||
|
TargetPrefix: "Foo",
|
||||||
|
}
|
||||||
|
cfg := unit.Session.Config.Copy()
|
||||||
|
cfg.MaxRetries = aws.Int(5)
|
||||||
|
|
||||||
|
req := request.New(
|
||||||
|
*cfg,
|
||||||
|
meta,
|
||||||
|
handlers,
|
||||||
|
client.DefaultRetryer{NumMaxRetries: 5},
|
||||||
|
op,
|
||||||
|
&struct {
|
||||||
|
}{},
|
||||||
|
&struct {
|
||||||
|
}{},
|
||||||
|
)
|
||||||
|
|
||||||
|
osErr := stubConnectionResetError
|
||||||
|
req.ApplyOptions(request.WithResponseReadTimeout(time.Second))
|
||||||
|
err := req.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("Expected rror 'SerializationError', but received nil")
|
||||||
|
}
|
||||||
|
if aerr, ok := err.(awserr.Error); ok && aerr.Code() != "SerializationError" {
|
||||||
|
t.Errorf("Expected 'SerializationError', but received %q", aerr.Code())
|
||||||
|
} else if !ok {
|
||||||
|
t.Errorf("Expected 'awserr.Error', but received %v", reflect.TypeOf(err))
|
||||||
|
} else if aerr.OrigErr().Error() != osErr.Error() {
|
||||||
|
t.Errorf("Expected %q, but received %q", osErr.Error(), aerr.OrigErr().Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if count != 6 {
|
||||||
|
t.Errorf("Expected '6', but received %d", count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testRetryer struct {
|
||||||
|
shouldRetry bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *testRetryer) MaxRetries() int {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetryRules returns the delay duration before retrying this request again
|
||||||
|
func (d *testRetryer) RetryRules(r *request.Request) time.Duration {
|
||||||
|
return time.Duration(time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *testRetryer) ShouldRetry(r *request.Request) bool {
|
||||||
|
d.shouldRetry = true
|
||||||
|
if r.Retryable != nil {
|
||||||
|
return *r.Retryable
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.HTTPResponse.StatusCode >= 500 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return r.IsErrorRetryable()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnforceShouldRetryCheck(t *testing.T) {
|
||||||
|
tp := &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
ResponseHeaderTimeout: 1 * time.Millisecond,
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{Transport: tp}
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// This server should wait forever. Requests will timeout and the SDK should
|
||||||
|
// attempt to retry.
|
||||||
|
select {}
|
||||||
|
}))
|
||||||
|
|
||||||
|
retryer := &testRetryer{}
|
||||||
|
s := awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
MaxRetries: aws.Int(0),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
Retryer: retryer,
|
||||||
|
HTTPClient: client,
|
||||||
|
EnforceShouldRetryCheck: aws.Bool(true),
|
||||||
|
})
|
||||||
|
|
||||||
|
s.Handlers.Validate.Clear()
|
||||||
|
s.Handlers.Unmarshal.PushBack(unmarshal)
|
||||||
|
s.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
|
||||||
|
out := &testData{}
|
||||||
|
r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out)
|
||||||
|
err := r.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, but got nil")
|
||||||
|
}
|
||||||
|
if e, a := 3, int(r.RetryCount); e != a {
|
||||||
|
t.Errorf("expect %d retry count, got %d", e, a)
|
||||||
|
}
|
||||||
|
if !retryer.shouldRetry {
|
||||||
|
t.Errorf("expect 'true' for ShouldRetry, but got %v", retryer.shouldRetry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type errReader struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (reader *errReader) Read(b []byte) (int, error) {
|
||||||
|
return 0, reader.err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (reader *errReader) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsNoBodyReader(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
reader io.ReadCloser
|
||||||
|
expect bool
|
||||||
|
}{
|
||||||
|
{ioutil.NopCloser(bytes.NewReader([]byte("abc"))), false},
|
||||||
|
{ioutil.NopCloser(bytes.NewReader(nil)), false},
|
||||||
|
{nil, false},
|
||||||
|
{request.NoBody, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
if e, a := c.expect, request.NoBody == c.reader; e != a {
|
||||||
|
t.Errorf("%d, expect %t match, but was %t", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequest_TemporaryRetry(t *testing.T) {
|
||||||
|
done := make(chan struct{})
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Header().Set("Content-Length", "1024")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
w.Write(make([]byte, 100))
|
||||||
|
|
||||||
|
f := w.(http.Flusher)
|
||||||
|
f.Flush()
|
||||||
|
|
||||||
|
<-done
|
||||||
|
}))
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 100 * time.Millisecond,
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
Region: unit.Session.Config.Region,
|
||||||
|
MaxRetries: aws.Int(1),
|
||||||
|
HTTPClient: client,
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
})
|
||||||
|
|
||||||
|
req := svc.NewRequest(&request.Operation{
|
||||||
|
Name: "name", HTTPMethod: "GET", HTTPPath: "/path",
|
||||||
|
}, &struct{}{}, &struct{}{})
|
||||||
|
|
||||||
|
req.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
defer req.HTTPResponse.Body.Close()
|
||||||
|
_, err := io.Copy(ioutil.Discard, req.HTTPResponse.Body)
|
||||||
|
r.Error = awserr.New(request.ErrCodeSerialization, "error", err)
|
||||||
|
})
|
||||||
|
|
||||||
|
err := req.Send()
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("expect error, got none")
|
||||||
|
}
|
||||||
|
close(done)
|
||||||
|
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := request.ErrCodeSerialization, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := 1, req.RetryCount; e != a {
|
||||||
|
t.Errorf("expect %d retries, got %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
type temporary interface {
|
||||||
|
Temporary() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
terr := aerr.OrigErr().(temporary)
|
||||||
|
if !terr.Temporary() {
|
||||||
|
t.Errorf("expect temporary error, was not")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequest_Presign(t *testing.T) {
|
||||||
|
presign := func(r *request.Request, expire time.Duration) (string, http.Header, error) {
|
||||||
|
u, err := r.Presign(expire)
|
||||||
|
return u, nil, err
|
||||||
|
}
|
||||||
|
presignRequest := func(r *request.Request, expire time.Duration) (string, http.Header, error) {
|
||||||
|
return r.PresignRequest(expire)
|
||||||
|
}
|
||||||
|
mustParseURL := func(v string) *url.URL {
|
||||||
|
u, err := url.Parse(v)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
Expire time.Duration
|
||||||
|
PresignFn func(*request.Request, time.Duration) (string, http.Header, error)
|
||||||
|
SignerFn func(*request.Request)
|
||||||
|
URL string
|
||||||
|
Header http.Header
|
||||||
|
Err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
PresignFn: presign,
|
||||||
|
Err: request.ErrCodeInvalidPresignExpire,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PresignFn: presignRequest,
|
||||||
|
Err: request.ErrCodeInvalidPresignExpire,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Expire: -1,
|
||||||
|
PresignFn: presign,
|
||||||
|
Err: request.ErrCodeInvalidPresignExpire,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Presign clear NotHoist
|
||||||
|
Expire: 1 * time.Minute,
|
||||||
|
PresignFn: func(r *request.Request, dur time.Duration) (string, http.Header, error) {
|
||||||
|
r.NotHoist = true
|
||||||
|
return presign(r, dur)
|
||||||
|
},
|
||||||
|
SignerFn: func(r *request.Request) {
|
||||||
|
r.HTTPRequest.URL = mustParseURL("https://endpoint/presignedURL")
|
||||||
|
fmt.Println("url", r.HTTPRequest.URL.String())
|
||||||
|
if r.NotHoist {
|
||||||
|
r.Error = fmt.Errorf("expect NotHoist to be cleared")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
URL: "https://endpoint/presignedURL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// PresignRequest does not clear NotHoist
|
||||||
|
Expire: 1 * time.Minute,
|
||||||
|
PresignFn: func(r *request.Request, dur time.Duration) (string, http.Header, error) {
|
||||||
|
r.NotHoist = true
|
||||||
|
return presignRequest(r, dur)
|
||||||
|
},
|
||||||
|
SignerFn: func(r *request.Request) {
|
||||||
|
r.HTTPRequest.URL = mustParseURL("https://endpoint/presignedURL")
|
||||||
|
if !r.NotHoist {
|
||||||
|
r.Error = fmt.Errorf("expect NotHoist not to be cleared")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
URL: "https://endpoint/presignedURL",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// PresignRequest returns signed headers
|
||||||
|
Expire: 1 * time.Minute,
|
||||||
|
PresignFn: presignRequest,
|
||||||
|
SignerFn: func(r *request.Request) {
|
||||||
|
r.HTTPRequest.URL = mustParseURL("https://endpoint/presignedURL")
|
||||||
|
r.HTTPRequest.Header.Set("UnsigndHeader", "abc")
|
||||||
|
r.SignedHeaderVals = http.Header{
|
||||||
|
"X-Amzn-Header": []string{"abc", "123"},
|
||||||
|
"X-Amzn-Header2": []string{"efg", "456"},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
URL: "https://endpoint/presignedURL",
|
||||||
|
Header: http.Header{
|
||||||
|
"X-Amzn-Header": []string{"abc", "123"},
|
||||||
|
"X-Amzn-Header2": []string{"efg", "456"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc := awstesting.NewClient()
|
||||||
|
svc.Handlers.Clear()
|
||||||
|
for i, c := range cases {
|
||||||
|
req := svc.NewRequest(&request.Operation{
|
||||||
|
Name: "name", HTTPMethod: "GET", HTTPPath: "/path",
|
||||||
|
}, &struct{}{}, &struct{}{})
|
||||||
|
req.Handlers.Sign.PushBack(c.SignerFn)
|
||||||
|
|
||||||
|
u, h, err := c.PresignFn(req, c.Expire)
|
||||||
|
if len(c.Err) != 0 {
|
||||||
|
if e, a := c.Err, err.Error(); !strings.Contains(a, e) {
|
||||||
|
t.Errorf("%d, expect %v to be in %v", i, e, a)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
} else if err != nil {
|
||||||
|
t.Errorf("%d, expect no error, got %v", i, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if e, a := c.URL, u; e != a {
|
||||||
|
t.Errorf("%d, expect %v URL, got %v", i, e, a)
|
||||||
|
}
|
||||||
|
if e, a := c.Header, h; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("%d, expect %v header got %v", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Retryer is an interface to control retry logic for a given service.
|
// Retryer is an interface to control retry logic for a given service.
|
||||||
// The default implementation used by most services is the service.DefaultRetryer
|
// The default implementation used by most services is the client.DefaultRetryer
|
||||||
// structure, which contains basic retry logic using exponential backoff.
|
// structure, which contains basic retry logic using exponential backoff.
|
||||||
type Retryer interface {
|
type Retryer interface {
|
||||||
RetryRules(*Request) time.Duration
|
RetryRules(*Request) time.Duration
|
||||||
|
@ -70,8 +70,8 @@ func isCodeExpiredCreds(code string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
var validParentCodes = map[string]struct{}{
|
var validParentCodes = map[string]struct{}{
|
||||||
ErrCodeSerialization: struct{}{},
|
ErrCodeSerialization: {},
|
||||||
ErrCodeRead: struct{}{},
|
ErrCodeRead: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
type temporaryError interface {
|
type temporaryError interface {
|
||||||
|
|
62
vendor/github.com/aws/aws-sdk-go/aws/request/retryer_test.go
generated
vendored
Normal file
62
vendor/github.com/aws/aws-sdk-go/aws/request/retryer_test.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRequestThrottling(t *testing.T) {
|
||||||
|
req := Request{}
|
||||||
|
|
||||||
|
req.Error = awserr.New("Throttling", "", nil)
|
||||||
|
if e, a := true, req.IsErrorThrottle(); e != a {
|
||||||
|
t.Errorf("expect %t to be throttled, was %t", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockTempError bool
|
||||||
|
|
||||||
|
func (e mockTempError) Error() string {
|
||||||
|
return fmt.Sprintf("mock temporary error: %t", e.Temporary())
|
||||||
|
}
|
||||||
|
func (e mockTempError) Temporary() bool {
|
||||||
|
return bool(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsErrorRetryable(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Err error
|
||||||
|
IsTemp bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Err: awserr.New(ErrCodeSerialization, "temporary error", mockTempError(true)),
|
||||||
|
IsTemp: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Err: awserr.New(ErrCodeSerialization, "temporary error", mockTempError(false)),
|
||||||
|
IsTemp: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Err: awserr.New(ErrCodeSerialization, "some error", errors.New("blah")),
|
||||||
|
IsTemp: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Err: awserr.New("SomeError", "some error", nil),
|
||||||
|
IsTemp: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Err: awserr.New("RequestError", "some error", nil),
|
||||||
|
IsTemp: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
retryable := IsErrorRetryable(c.Err)
|
||||||
|
if e, a := c.IsTemp, retryable; e != a {
|
||||||
|
t.Errorf("%d, expect %t temporary error, got %t", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go
generated
vendored
Normal file
76
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go
generated
vendored
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkTimeoutReadCloser(b *testing.B) {
|
||||||
|
resp := `
|
||||||
|
{
|
||||||
|
"Bar": "qux"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
handlers := request.Handlers{}
|
||||||
|
|
||||||
|
handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewBuffer([]byte(resp))),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||||
|
handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||||
|
handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||||
|
handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||||
|
handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler)
|
||||||
|
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "op",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
meta := metadata.ClientInfo{
|
||||||
|
ServiceName: "fooService",
|
||||||
|
SigningName: "foo",
|
||||||
|
SigningRegion: "foo",
|
||||||
|
Endpoint: "localhost",
|
||||||
|
APIVersion: "2001-01-01",
|
||||||
|
JSONVersion: "1.1",
|
||||||
|
TargetPrefix: "Foo",
|
||||||
|
}
|
||||||
|
|
||||||
|
req := request.New(
|
||||||
|
*unit.Session.Config,
|
||||||
|
meta,
|
||||||
|
handlers,
|
||||||
|
client.DefaultRetryer{NumMaxRetries: 5},
|
||||||
|
op,
|
||||||
|
&struct {
|
||||||
|
Foo *string
|
||||||
|
}{},
|
||||||
|
&struct {
|
||||||
|
Bar *string
|
||||||
|
}{},
|
||||||
|
)
|
||||||
|
|
||||||
|
req.ApplyOptions(request.WithResponseReadTimeout(15 * time.Second))
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
err := req.Send()
|
||||||
|
if err != nil {
|
||||||
|
b.Errorf("Expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
118
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go
generated
vendored
Normal file
118
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go
generated
vendored
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testReader struct {
|
||||||
|
duration time.Duration
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *testReader) Read(b []byte) (int, error) {
|
||||||
|
if r.count > 0 {
|
||||||
|
r.count--
|
||||||
|
return len(b), nil
|
||||||
|
}
|
||||||
|
time.Sleep(r.duration)
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *testReader) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeoutReadCloser(t *testing.T) {
|
||||||
|
reader := timeoutReadCloser{
|
||||||
|
reader: &testReader{
|
||||||
|
duration: time.Second,
|
||||||
|
count: 5,
|
||||||
|
},
|
||||||
|
duration: time.Millisecond,
|
||||||
|
}
|
||||||
|
b := make([]byte, 100)
|
||||||
|
_, err := reader.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTimeoutReadCloserSameDuration(t *testing.T) {
|
||||||
|
reader := timeoutReadCloser{
|
||||||
|
reader: &testReader{
|
||||||
|
duration: time.Millisecond,
|
||||||
|
count: 5,
|
||||||
|
},
|
||||||
|
duration: time.Millisecond,
|
||||||
|
}
|
||||||
|
b := make([]byte, 100)
|
||||||
|
_, err := reader.Read(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithResponseReadTimeout(t *testing.T) {
|
||||||
|
r := Request{
|
||||||
|
HTTPResponse: &http.Response{
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader(nil)),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r.ApplyOptions(WithResponseReadTimeout(time.Second))
|
||||||
|
err := r.Send()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
v, ok := r.HTTPResponse.Body.(*timeoutReadCloser)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Expected the body to be a timeoutReadCloser")
|
||||||
|
}
|
||||||
|
if v.duration != time.Second {
|
||||||
|
t.Errorf("Expected %v, but receive %v\n", time.Second, v.duration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAdaptToResponseTimeout(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
childErr error
|
||||||
|
r Request
|
||||||
|
expectedRootCode string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
childErr: awserr.New(ErrCodeResponseTimeout, "timeout!", nil),
|
||||||
|
r: Request{
|
||||||
|
Error: awserr.New("ErrTest", "FooBar", awserr.New(ErrCodeResponseTimeout, "timeout!", nil)),
|
||||||
|
},
|
||||||
|
expectedRootCode: ErrCodeResponseTimeout,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
childErr: awserr.New(ErrCodeResponseTimeout+"1", "timeout!", nil),
|
||||||
|
r: Request{
|
||||||
|
Error: awserr.New("ErrTest", "FooBar", awserr.New(ErrCodeResponseTimeout+"1", "timeout!", nil)),
|
||||||
|
},
|
||||||
|
expectedRootCode: "ErrTest",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
r: Request{
|
||||||
|
Error: awserr.New("ErrTest", "FooBar", nil),
|
||||||
|
},
|
||||||
|
expectedRootCode: "ErrTest",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range testCases {
|
||||||
|
adaptToResponseTimeoutError(&c.r)
|
||||||
|
if aerr, ok := c.r.Error.(awserr.Error); !ok {
|
||||||
|
t.Errorf("Case %d: Expected 'awserr', but received %v", i+1, c.r.Error)
|
||||||
|
} else if aerr.Code() != c.expectedRootCode {
|
||||||
|
t.Errorf("Case %d: Expected %q, but received %s", i+1, c.expectedRootCode, aerr.Code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
|
@ -220,7 +220,7 @@ type ErrParamMinLen struct {
|
||||||
func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
|
func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
|
||||||
return &ErrParamMinLen{
|
return &ErrParamMinLen{
|
||||||
errInvalidParam: errInvalidParam{
|
errInvalidParam: errInvalidParam{
|
||||||
code: ParamMinValueErrCode,
|
code: ParamMinLenErrCode,
|
||||||
field: field,
|
field: field,
|
||||||
msg: fmt.Sprintf("minimum field size of %v", min),
|
msg: fmt.Sprintf("minimum field size of %v", min),
|
||||||
},
|
},
|
||||||
|
|
10
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
10
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
|
@ -81,6 +81,7 @@ type Waiter struct {
|
||||||
|
|
||||||
RequestOptions []Option
|
RequestOptions []Option
|
||||||
NewRequest func([]Option) (*Request, error)
|
NewRequest func([]Option) (*Request, error)
|
||||||
|
SleepWithContext func(aws.Context, time.Duration) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ApplyOptions updates the waiter with the list of waiter options provided.
|
// ApplyOptions updates the waiter with the list of waiter options provided.
|
||||||
|
@ -195,10 +196,17 @@ func (w Waiter) WaitWithContext(ctx aws.Context) error {
|
||||||
if sleepFn := req.Config.SleepDelay; sleepFn != nil {
|
if sleepFn := req.Config.SleepDelay; sleepFn != nil {
|
||||||
// Support SleepDelay for backwards compatibility and testing
|
// Support SleepDelay for backwards compatibility and testing
|
||||||
sleepFn(delay)
|
sleepFn(delay)
|
||||||
} else if err := aws.SleepWithContext(ctx, delay); err != nil {
|
} else {
|
||||||
|
sleepCtxFn := w.SleepWithContext
|
||||||
|
if sleepCtxFn == nil {
|
||||||
|
sleepCtxFn = aws.SleepWithContext
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sleepCtxFn(ctx, delay); err != nil {
|
||||||
return awserr.New(CanceledErrorCode, "waiter context canceled", err)
|
return awserr.New(CanceledErrorCode, "waiter context canceled", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil)
|
return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil)
|
||||||
}
|
}
|
||||||
|
|
654
vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go
generated
vendored
Normal file
654
vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go
generated
vendored
Normal file
|
@ -0,0 +1,654 @@
|
||||||
|
package request_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockClient struct {
|
||||||
|
*client.Client
|
||||||
|
}
|
||||||
|
type MockInput struct{}
|
||||||
|
type MockOutput struct {
|
||||||
|
States []*MockState
|
||||||
|
}
|
||||||
|
type MockState struct {
|
||||||
|
State *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *mockClient) MockRequest(input *MockInput) (*request.Request, *MockOutput) {
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "Mock",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
if input == nil {
|
||||||
|
input = &MockInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
output := &MockOutput{}
|
||||||
|
req := c.NewRequest(op, input, output)
|
||||||
|
req.Data = output
|
||||||
|
return req, output
|
||||||
|
}
|
||||||
|
|
||||||
|
func BuildNewMockRequest(c *mockClient, in *MockInput) func([]request.Option) (*request.Request, error) {
|
||||||
|
return func(opts []request.Option) (*request.Request, error) {
|
||||||
|
req, _ := c.MockRequest(in)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterPathAll(t *testing.T) {
|
||||||
|
svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
})}
|
||||||
|
svc.Handlers.Send.Clear() // mock sending
|
||||||
|
svc.Handlers.Unmarshal.Clear()
|
||||||
|
svc.Handlers.UnmarshalMeta.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*MockOutput{
|
||||||
|
{ // Request 1
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 2
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 3
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("running")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
numBuiltReq := 0
|
||||||
|
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
numBuiltReq++
|
||||||
|
})
|
||||||
|
svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
if reqNum >= len(resps) {
|
||||||
|
assert.Fail(t, "too many polling requests made")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(0),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.PathAllWaiterMatch,
|
||||||
|
Argument: "States[].State",
|
||||||
|
Expected: "running",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewRequest: BuildNewMockRequest(svc, &MockInput{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(aws.BackgroundContext())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 3, numBuiltReq)
|
||||||
|
assert.Equal(t, 3, reqNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterPath(t *testing.T) {
|
||||||
|
svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
})}
|
||||||
|
svc.Handlers.Send.Clear() // mock sending
|
||||||
|
svc.Handlers.Unmarshal.Clear()
|
||||||
|
svc.Handlers.UnmarshalMeta.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*MockOutput{
|
||||||
|
{ // Request 1
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 2
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 3
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("running")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
numBuiltReq := 0
|
||||||
|
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
numBuiltReq++
|
||||||
|
})
|
||||||
|
svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
if reqNum >= len(resps) {
|
||||||
|
assert.Fail(t, "too many polling requests made")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(0),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.PathWaiterMatch,
|
||||||
|
Argument: "States[].State",
|
||||||
|
Expected: "running",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewRequest: BuildNewMockRequest(svc, &MockInput{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(aws.BackgroundContext())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 3, numBuiltReq)
|
||||||
|
assert.Equal(t, 3, reqNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterFailure(t *testing.T) {
|
||||||
|
svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
})}
|
||||||
|
svc.Handlers.Send.Clear() // mock sending
|
||||||
|
svc.Handlers.Unmarshal.Clear()
|
||||||
|
svc.Handlers.UnmarshalMeta.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*MockOutput{
|
||||||
|
{ // Request 1
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 2
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 3
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("stopping")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
numBuiltReq := 0
|
||||||
|
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
numBuiltReq++
|
||||||
|
})
|
||||||
|
svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
if reqNum >= len(resps) {
|
||||||
|
assert.Fail(t, "too many polling requests made")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(0),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.PathAllWaiterMatch,
|
||||||
|
Argument: "States[].State",
|
||||||
|
Expected: "running",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: request.FailureWaiterState,
|
||||||
|
Matcher: request.PathAnyWaiterMatch,
|
||||||
|
Argument: "States[].State",
|
||||||
|
Expected: "stopping",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewRequest: BuildNewMockRequest(svc, &MockInput{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(aws.BackgroundContext()).(awserr.Error)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t, request.WaiterResourceNotReadyErrorCode, err.Code())
|
||||||
|
assert.Equal(t, "failed waiting for successful resource state", err.Message())
|
||||||
|
assert.Equal(t, 3, numBuiltReq)
|
||||||
|
assert.Equal(t, 3, reqNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterError(t *testing.T) {
|
||||||
|
svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
})}
|
||||||
|
svc.Handlers.Send.Clear() // mock sending
|
||||||
|
svc.Handlers.Unmarshal.Clear()
|
||||||
|
svc.Handlers.UnmarshalMeta.Clear()
|
||||||
|
svc.Handlers.UnmarshalError.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
resps := []*MockOutput{
|
||||||
|
{ // Request 1
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
{State: aws.String("pending")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // Request 1, error case retry
|
||||||
|
},
|
||||||
|
{ // Request 2, error case failure
|
||||||
|
},
|
||||||
|
{ // Request 3
|
||||||
|
States: []*MockState{
|
||||||
|
{State: aws.String("running")},
|
||||||
|
{State: aws.String("running")},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
reqErrs := make([]error, len(resps))
|
||||||
|
reqErrs[1] = awserr.New("MockException", "mock exception message", nil)
|
||||||
|
reqErrs[2] = awserr.New("FailureException", "mock failure exception message", nil)
|
||||||
|
|
||||||
|
numBuiltReq := 0
|
||||||
|
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
numBuiltReq++
|
||||||
|
})
|
||||||
|
svc.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
code := 200
|
||||||
|
if reqNum == 1 {
|
||||||
|
code = 400
|
||||||
|
}
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: code,
|
||||||
|
Status: http.StatusText(code),
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
svc.Handlers.Unmarshal.PushBack(func(r *request.Request) {
|
||||||
|
if reqNum >= len(resps) {
|
||||||
|
assert.Fail(t, "too many polling requests made")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Data = resps[reqNum]
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
svc.Handlers.UnmarshalMeta.PushBack(func(r *request.Request) {
|
||||||
|
// If there was an error unmarshal error will be called instead of unmarshal
|
||||||
|
// need to increment count here also
|
||||||
|
if err := reqErrs[reqNum]; err != nil {
|
||||||
|
r.Error = err
|
||||||
|
reqNum++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(0),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.PathAllWaiterMatch,
|
||||||
|
Argument: "States[].State",
|
||||||
|
Expected: "running",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: request.RetryWaiterState,
|
||||||
|
Matcher: request.ErrorWaiterMatch,
|
||||||
|
Argument: "",
|
||||||
|
Expected: "MockException",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: request.FailureWaiterState,
|
||||||
|
Matcher: request.ErrorWaiterMatch,
|
||||||
|
Argument: "",
|
||||||
|
Expected: "FailureException",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewRequest: BuildNewMockRequest(svc, &MockInput{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(aws.BackgroundContext())
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected error, but did not get one")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := request.WaiterResourceNotReadyErrorCode, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 3, numBuiltReq; e != a {
|
||||||
|
t.Errorf("expect %d built requests got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 3, reqNum; e != a {
|
||||||
|
t.Errorf("expect %d reqNum got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterStatus(t *testing.T) {
|
||||||
|
svc := &mockClient{Client: awstesting.NewClient(&aws.Config{
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
})}
|
||||||
|
svc.Handlers.Send.Clear() // mock sending
|
||||||
|
svc.Handlers.Unmarshal.Clear()
|
||||||
|
svc.Handlers.UnmarshalMeta.Clear()
|
||||||
|
svc.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
reqNum := 0
|
||||||
|
svc.Handlers.Build.PushBack(func(r *request.Request) {
|
||||||
|
reqNum++
|
||||||
|
})
|
||||||
|
svc.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
code := 200
|
||||||
|
if reqNum == 3 {
|
||||||
|
code = 404
|
||||||
|
r.Error = awserr.New("NotFound", "Not Found", nil)
|
||||||
|
}
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: code,
|
||||||
|
Status: http.StatusText(code),
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(0),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.StatusWaiterMatch,
|
||||||
|
Argument: "",
|
||||||
|
Expected: 404,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
NewRequest: BuildNewMockRequest(svc, &MockInput{}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(aws.BackgroundContext())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 3, reqNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiter_ApplyOptions(t *testing.T) {
|
||||||
|
w := request.Waiter{}
|
||||||
|
|
||||||
|
logger := aws.NewDefaultLogger()
|
||||||
|
|
||||||
|
w.ApplyOptions(
|
||||||
|
request.WithWaiterLogger(logger),
|
||||||
|
request.WithWaiterRequestOptions(request.WithLogLevel(aws.LogDebug)),
|
||||||
|
request.WithWaiterMaxAttempts(2),
|
||||||
|
request.WithWaiterDelay(request.ConstantWaiterDelay(5*time.Second)),
|
||||||
|
)
|
||||||
|
|
||||||
|
if e, a := logger, w.Logger; e != a {
|
||||||
|
t.Errorf("expect logger to be set, and match, was not, %v, %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(w.RequestOptions) != 1 {
|
||||||
|
t.Fatalf("expect request options to be set to only a single option, %v", w.RequestOptions)
|
||||||
|
}
|
||||||
|
r := request.Request{}
|
||||||
|
r.ApplyOptions(w.RequestOptions...)
|
||||||
|
if e, a := aws.LogDebug, r.Config.LogLevel.Value(); e != a {
|
||||||
|
t.Errorf("expect %v loglevel got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := 2, w.MaxAttempts; e != a {
|
||||||
|
t.Errorf("expect %d retryer max attempts, got %d", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 5*time.Second, w.Delay(0); e != a {
|
||||||
|
t.Errorf("expect %d retryer delay, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiter_WithContextCanceled(t *testing.T) {
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
reqCount := 0
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "TestWaiter",
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(1 * time.Millisecond),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.StatusWaiterMatch,
|
||||||
|
Expected: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Logger: aws.NewDefaultLogger(),
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
req.HTTPResponse = &http.Response{StatusCode: http.StatusNotFound}
|
||||||
|
req.Handlers.Clear()
|
||||||
|
req.Data = struct{}{}
|
||||||
|
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
if reqCount == 1 {
|
||||||
|
ctx.Error = fmt.Errorf("context canceled")
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
}
|
||||||
|
reqCount++
|
||||||
|
})
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
w.SleepWithContext = func(c aws.Context, delay time.Duration) error {
|
||||||
|
context := c.(*awstesting.FakeContext)
|
||||||
|
select {
|
||||||
|
case <-context.DoneCh:
|
||||||
|
return context.Err()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(ctx)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect waiter to be canceled.")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := request.CanceledErrorCode, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 2, reqCount; e != a {
|
||||||
|
t.Errorf("expect %d requests, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiter_WithContext(t *testing.T) {
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
reqCount := 0
|
||||||
|
|
||||||
|
statuses := []int{http.StatusNotFound, http.StatusOK}
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "TestWaiter",
|
||||||
|
MaxAttempts: 10,
|
||||||
|
Delay: request.ConstantWaiterDelay(1 * time.Millisecond),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.StatusWaiterMatch,
|
||||||
|
Expected: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Logger: aws.NewDefaultLogger(),
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
req.HTTPResponse = &http.Response{StatusCode: statuses[reqCount]}
|
||||||
|
req.Handlers.Clear()
|
||||||
|
req.Data = struct{}{}
|
||||||
|
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
if reqCount == 1 {
|
||||||
|
ctx.Error = fmt.Errorf("context canceled")
|
||||||
|
close(ctx.DoneCh)
|
||||||
|
}
|
||||||
|
reqCount++
|
||||||
|
})
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 2, reqCount; e != a {
|
||||||
|
t.Errorf("expect %d requests, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiter_AttemptsExpires(t *testing.T) {
|
||||||
|
c := awstesting.NewClient()
|
||||||
|
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
reqCount := 0
|
||||||
|
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "TestWaiter",
|
||||||
|
MaxAttempts: 2,
|
||||||
|
Delay: request.ConstantWaiterDelay(1 * time.Millisecond),
|
||||||
|
SleepWithContext: aws.SleepWithContext,
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.StatusWaiterMatch,
|
||||||
|
Expected: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Logger: aws.NewDefaultLogger(),
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
|
||||||
|
req.HTTPResponse = &http.Response{StatusCode: http.StatusNotFound}
|
||||||
|
req.Handlers.Clear()
|
||||||
|
req.Data = struct{}{}
|
||||||
|
req.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
reqCount++
|
||||||
|
})
|
||||||
|
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.WaitWithContext(ctx)
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error did not get one")
|
||||||
|
}
|
||||||
|
aerr := err.(awserr.Error)
|
||||||
|
if e, a := request.WaiterResourceNotReadyErrorCode, aerr.Code(); e != a {
|
||||||
|
t.Errorf("expect %q error code, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := 2, reqCount; e != a {
|
||||||
|
t.Errorf("expect %d requests, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterNilInput(t *testing.T) {
|
||||||
|
// Code generation doesn't have a great way to verify the code is correct
|
||||||
|
// other than being run via unit tests in the SDK. This should be fixed
|
||||||
|
// So code generation can be validated independently.
|
||||||
|
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
client.Handlers.Validate.Clear()
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
client.Config.SleepDelay = func(dur time.Duration) {}
|
||||||
|
|
||||||
|
// Ensure waiters do not panic on nil input. It doesn't make sense to
|
||||||
|
// call a waiter without an input, Validation will
|
||||||
|
err := client.WaitUntilBucketExists(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWaiterWithContextNilInput(t *testing.T) {
|
||||||
|
// Code generation doesn't have a great way to verify the code is correct
|
||||||
|
// other than being run via unit tests in the SDK. This should be fixed
|
||||||
|
// So code generation can be validated independently.
|
||||||
|
|
||||||
|
client := s3.New(unit.Session)
|
||||||
|
client.Handlers.Validate.Clear()
|
||||||
|
client.Handlers.Send.Clear() // mock sending
|
||||||
|
client.Handlers.Send.PushBack(func(r *request.Request) {
|
||||||
|
r.HTTPResponse = &http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
client.Handlers.Unmarshal.Clear()
|
||||||
|
client.Handlers.UnmarshalMeta.Clear()
|
||||||
|
client.Handlers.ValidateResponse.Clear()
|
||||||
|
|
||||||
|
// Ensure waiters do not panic on nil input
|
||||||
|
ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})}
|
||||||
|
err := client.WaitUntilBucketExistsWithContext(ctx, nil,
|
||||||
|
request.WithWaiterDelay(request.ConstantWaiterDelay(0)),
|
||||||
|
request.WithWaiterMaxAttempts(1),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, but got %v", err)
|
||||||
|
}
|
||||||
|
}
|
243
vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go
generated
vendored
Normal file
243
vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go
generated
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
package session
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
)
|
||||||
|
|
||||||
|
var TLSBundleCertFile string
|
||||||
|
var TLSBundleKeyFile string
|
||||||
|
var TLSBundleCAFile string
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
TLSBundleCertFile, TLSBundleKeyFile, TLSBundleCAFile, err = awstesting.CreateTLSBundleFiles()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("TestMain", TLSBundleCertFile, TLSBundleKeyFile)
|
||||||
|
|
||||||
|
code := m.Run()
|
||||||
|
|
||||||
|
err = awstesting.CleanupTLSBundleFiles(TLSBundleCertFile, TLSBundleKeyFile, TLSBundleCAFile)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Exit(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_Env(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
endpoint, err := awstesting.CreateTLSServer(TLSBundleCertFile, TLSBundleKeyFile, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Setenv("AWS_CA_BUNDLE", TLSBundleCAFile)
|
||||||
|
|
||||||
|
s, err := NewSession(&aws.Config{
|
||||||
|
HTTPClient: &http.Client{},
|
||||||
|
Endpoint: aws.String(endpoint),
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("expect session to be created, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil)
|
||||||
|
resp, err := s.Config.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_EnvNotExists(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_CA_BUNDLE", "file-not-exists")
|
||||||
|
|
||||||
|
s, err := NewSession()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, got none")
|
||||||
|
}
|
||||||
|
if e, a := "LoadCustomCABundleError", err.(awserr.Error).Code(); e != a {
|
||||||
|
t.Errorf("expect %s error code, got %s", e, a)
|
||||||
|
}
|
||||||
|
if s != nil {
|
||||||
|
t.Errorf("expect nil session, got %v", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_Option(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
endpoint, err := awstesting.CreateTLSServer(TLSBundleCertFile, TLSBundleKeyFile, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Config: aws.Config{
|
||||||
|
HTTPClient: &http.Client{},
|
||||||
|
Endpoint: aws.String(endpoint),
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
},
|
||||||
|
CustomCABundle: bytes.NewReader(awstesting.TLSBundleCA),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("expect session to be created, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil)
|
||||||
|
resp, err := s.Config.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_OptionPriority(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
endpoint, err := awstesting.CreateTLSServer(TLSBundleCertFile, TLSBundleKeyFile, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
os.Setenv("AWS_CA_BUNDLE", "file-not-exists")
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Config: aws.Config{
|
||||||
|
HTTPClient: &http.Client{},
|
||||||
|
Endpoint: aws.String(endpoint),
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
},
|
||||||
|
CustomCABundle: bytes.NewReader(awstesting.TLSBundleCA),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("expect session to be created, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil)
|
||||||
|
resp, err := s.Config.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockRoundTripper struct{}
|
||||||
|
|
||||||
|
func (m *mockRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_UnsupportedTransport(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Config: aws.Config{
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Transport: &mockRoundTripper{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CustomCABundle: bytes.NewReader(awstesting.TLSBundleCA),
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expect error, got none")
|
||||||
|
}
|
||||||
|
if e, a := "LoadCustomCABundleError", err.(awserr.Error).Code(); e != a {
|
||||||
|
t.Errorf("expect %s error code, got %s", e, a)
|
||||||
|
}
|
||||||
|
if s != nil {
|
||||||
|
t.Errorf("expect nil session, got %v", s)
|
||||||
|
}
|
||||||
|
aerrMsg := err.(awserr.Error).Message()
|
||||||
|
if e, a := "transport unsupported type", aerrMsg; !strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %s to be in %s", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_WithCustomCABundle_TransportSet(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
endpoint, err := awstesting.CreateTLSServer(TLSBundleCertFile, TLSBundleKeyFile, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Config: aws.Config{
|
||||||
|
Endpoint: aws.String(endpoint),
|
||||||
|
Region: aws.String("mock-region"),
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
HTTPClient: &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
Dial: (&net.Dialer{
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
KeepAlive: 30 * time.Second,
|
||||||
|
DualStack: true,
|
||||||
|
}).Dial,
|
||||||
|
TLSHandshakeTimeout: 2 * time.Second,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CustomCABundle: bytes.NewReader(awstesting.TLSBundleCA),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("expect session to be created, got none")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil)
|
||||||
|
resp, err := s.Config.HTTPClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %d status code, got %d", e, a)
|
||||||
|
}
|
||||||
|
}
|
43
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
43
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
|
@ -2,12 +2,14 @@ package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EnvProviderName provides a name of the provider when config is loaded from environment.
|
||||||
|
const EnvProviderName = "EnvConfigCredentials"
|
||||||
|
|
||||||
// envConfig is a collection of environment values the SDK will read
|
// envConfig is a collection of environment values the SDK will read
|
||||||
// setup config from. All environment values are optional. But some values
|
// setup config from. All environment values are optional. But some values
|
||||||
// such as credentials require multiple values to be complete or the values
|
// such as credentials require multiple values to be complete or the values
|
||||||
|
@ -77,7 +79,7 @@ type envConfig struct {
|
||||||
SharedConfigFile string
|
SharedConfigFile string
|
||||||
|
|
||||||
// Sets the path to a custom Credentials Authroity (CA) Bundle PEM file
|
// Sets the path to a custom Credentials Authroity (CA) Bundle PEM file
|
||||||
// that the SDK will use instead of the the system's root CA bundle.
|
// that the SDK will use instead of the system's root CA bundle.
|
||||||
// Only use this if you want to configure the SDK to use a custom set
|
// Only use this if you want to configure the SDK to use a custom set
|
||||||
// of CAs.
|
// of CAs.
|
||||||
//
|
//
|
||||||
|
@ -116,6 +118,12 @@ var (
|
||||||
"AWS_PROFILE",
|
"AWS_PROFILE",
|
||||||
"AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
"AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
||||||
}
|
}
|
||||||
|
sharedCredsFileEnvKey = []string{
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE",
|
||||||
|
}
|
||||||
|
sharedConfigFileEnvKey = []string{
|
||||||
|
"AWS_CONFIG_FILE",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// loadEnvConfig retrieves the SDK's environment configuration.
|
// loadEnvConfig retrieves the SDK's environment configuration.
|
||||||
|
@ -152,7 +160,7 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||||
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
||||||
cfg.Creds = credentials.Value{}
|
cfg.Creds = credentials.Value{}
|
||||||
} else {
|
} else {
|
||||||
cfg.Creds.ProviderName = "EnvConfigCredentials"
|
cfg.Creds.ProviderName = EnvProviderName
|
||||||
}
|
}
|
||||||
|
|
||||||
regionKeys := regionEnvKeys
|
regionKeys := regionEnvKeys
|
||||||
|
@ -165,8 +173,8 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||||
setFromEnvVal(&cfg.Region, regionKeys)
|
setFromEnvVal(&cfg.Region, regionKeys)
|
||||||
setFromEnvVal(&cfg.Profile, profileKeys)
|
setFromEnvVal(&cfg.Profile, profileKeys)
|
||||||
|
|
||||||
cfg.SharedCredentialsFile = sharedCredentialsFilename()
|
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
|
||||||
cfg.SharedConfigFile = sharedConfigFilename()
|
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
|
||||||
|
|
||||||
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
||||||
|
|
||||||
|
@ -181,28 +189,3 @@ func setFromEnvVal(dst *string, keys []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sharedCredentialsFilename() string {
|
|
||||||
if name := os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(name) > 0 {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Join(userHomeDir(), ".aws", "credentials")
|
|
||||||
}
|
|
||||||
|
|
||||||
func sharedConfigFilename() string {
|
|
||||||
if name := os.Getenv("AWS_CONFIG_FILE"); len(name) > 0 {
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
||||||
return filepath.Join(userHomeDir(), ".aws", "config")
|
|
||||||
}
|
|
||||||
|
|
||||||
func userHomeDir() string {
|
|
||||||
homeDir := os.Getenv("HOME") // *nix
|
|
||||||
if len(homeDir) == 0 { // windows
|
|
||||||
homeDir = os.Getenv("USERPROFILE")
|
|
||||||
}
|
|
||||||
|
|
||||||
return homeDir
|
|
||||||
}
|
|
||||||
|
|
279
vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go
generated
vendored
Normal file
279
vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go
generated
vendored
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
package session
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoadEnvConfig_Creds(t *testing.T) {
|
||||||
|
env := awstesting.StashEnv()
|
||||||
|
defer awstesting.PopEnv(env)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
Env map[string]string
|
||||||
|
Val credentials.Value
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_ACCESS_KEY": "AKID",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_ACCESS_KEY_ID": "AKID",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_SECRET_KEY": "SECRET",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_SECRET_ACCESS_KEY": "SECRET",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_ACCESS_KEY_ID": "AKID",
|
||||||
|
"AWS_SECRET_ACCESS_KEY": "SECRET",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{
|
||||||
|
AccessKeyID: "AKID", SecretAccessKey: "SECRET",
|
||||||
|
ProviderName: "EnvConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_ACCESS_KEY": "AKID",
|
||||||
|
"AWS_SECRET_KEY": "SECRET",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{
|
||||||
|
AccessKeyID: "AKID", SecretAccessKey: "SECRET",
|
||||||
|
ProviderName: "EnvConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_ACCESS_KEY": "AKID",
|
||||||
|
"AWS_SECRET_KEY": "SECRET",
|
||||||
|
"AWS_SESSION_TOKEN": "TOKEN",
|
||||||
|
},
|
||||||
|
Val: credentials.Value{
|
||||||
|
AccessKeyID: "AKID", SecretAccessKey: "SECRET", SessionToken: "TOKEN",
|
||||||
|
ProviderName: "EnvConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
for k, v := range c.Env {
|
||||||
|
os.Setenv(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := loadEnvConfig()
|
||||||
|
if !reflect.DeepEqual(c.Val, cfg.Creds) {
|
||||||
|
t.Errorf("expect credentials to match.\n%s",
|
||||||
|
awstesting.SprintExpectActual(c.Val, cfg.Creds))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadEnvConfig(t *testing.T) {
|
||||||
|
env := awstesting.StashEnv()
|
||||||
|
defer awstesting.PopEnv(env)
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
Env map[string]string
|
||||||
|
UseSharedConfigCall bool
|
||||||
|
Config envConfig
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "1",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "1",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "default_region", Profile: "default_profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_REGION": "region",
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_PROFILE": "profile",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "1",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "region", Profile: "profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "default_region", Profile: "default_profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_DEFAULT_REGION": "default_region",
|
||||||
|
"AWS_DEFAULT_PROFILE": "default_profile",
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "1",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
Region: "default_region", Profile: "default_profile",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_CA_BUNDLE": "custom_ca_bundle",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
CustomCABundle: "custom_ca_bundle",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_CA_BUNDLE": "custom_ca_bundle",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
CustomCABundle: "custom_ca_bundle",
|
||||||
|
EnableSharedConfig: true,
|
||||||
|
},
|
||||||
|
UseSharedConfigCall: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Env: map[string]string{
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE": "/path/to/credentials/file",
|
||||||
|
"AWS_CONFIG_FILE": "/path/to/config/file",
|
||||||
|
},
|
||||||
|
Config: envConfig{
|
||||||
|
SharedCredentialsFile: "/path/to/credentials/file",
|
||||||
|
SharedConfigFile: "/path/to/config/file",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
os.Clearenv()
|
||||||
|
|
||||||
|
for k, v := range c.Env {
|
||||||
|
os.Setenv(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg envConfig
|
||||||
|
if c.UseSharedConfigCall {
|
||||||
|
cfg = loadSharedEnvConfig()
|
||||||
|
} else {
|
||||||
|
cfg = loadEnvConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(c.Config, cfg) {
|
||||||
|
t.Errorf("expect config to match.\n%s",
|
||||||
|
awstesting.SprintExpectActual(c.Config, cfg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetEnvValue(t *testing.T) {
|
||||||
|
env := awstesting.StashEnv()
|
||||||
|
defer awstesting.PopEnv(env)
|
||||||
|
|
||||||
|
os.Setenv("empty_key", "")
|
||||||
|
os.Setenv("second_key", "2")
|
||||||
|
os.Setenv("third_key", "3")
|
||||||
|
|
||||||
|
var dst string
|
||||||
|
setFromEnvVal(&dst, []string{
|
||||||
|
"empty_key", "first_key", "second_key", "third_key",
|
||||||
|
})
|
||||||
|
|
||||||
|
if e, a := "2", dst; e != a {
|
||||||
|
t.Errorf("expect %s value from environment, got %s", e, a)
|
||||||
|
}
|
||||||
|
}
|
7
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
7
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
|
@ -243,6 +243,13 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
|
||||||
envCfg.EnableSharedConfig = true
|
envCfg.EnableSharedConfig = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(envCfg.SharedCredentialsFile) == 0 {
|
||||||
|
envCfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
|
||||||
|
}
|
||||||
|
if len(envCfg.SharedConfigFile) == 0 {
|
||||||
|
envCfg.SharedConfigFile = defaults.SharedConfigFilename()
|
||||||
|
}
|
||||||
|
|
||||||
// Only use AWS_CA_BUNDLE if session option is not provided.
|
// Only use AWS_CA_BUNDLE if session option is not provided.
|
||||||
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
|
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
|
||||||
f, err := os.Open(envCfg.CustomCABundle)
|
f, err := os.Open(envCfg.CustomCABundle)
|
||||||
|
|
446
vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go
generated
vendored
Normal file
446
vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go
generated
vendored
Normal file
|
@ -0,0 +1,446 @@
|
||||||
|
package session
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewDefaultSession(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
s := New(&aws.Config{Region: aws.String("region")})
|
||||||
|
|
||||||
|
assert.Equal(t, "region", *s.Config.Region)
|
||||||
|
assert.Equal(t, http.DefaultClient, s.Config.HTTPClient)
|
||||||
|
assert.NotNil(t, s.Config.Logger)
|
||||||
|
assert.Equal(t, aws.LogOff, *s.Config.LogLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNew_WithCustomCreds(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
customCreds := credentials.NewStaticCredentials("AKID", "SECRET", "TOKEN")
|
||||||
|
s := New(&aws.Config{Credentials: customCreds})
|
||||||
|
|
||||||
|
assert.Equal(t, customCreds, s.Config.Credentials)
|
||||||
|
}
|
||||||
|
|
||||||
|
type mockLogger struct {
|
||||||
|
*bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w mockLogger) Log(args ...interface{}) {
|
||||||
|
fmt.Fprintln(w, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNew_WithSessionLoadError(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_CONFIG_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_invalid_source_profile")
|
||||||
|
|
||||||
|
logger := bytes.Buffer{}
|
||||||
|
s := New(&aws.Config{Logger: &mockLogger{&logger}})
|
||||||
|
|
||||||
|
assert.NotNil(t, s)
|
||||||
|
|
||||||
|
svc := s3.New(s)
|
||||||
|
_, err := svc.ListBuckets(&s3.ListBucketsInput{})
|
||||||
|
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, logger.String(), "ERROR: failed to create session with AWS_SDK_LOAD_CONFIG enabled")
|
||||||
|
assert.Contains(t, err.Error(), SharedConfigAssumeRoleError{
|
||||||
|
RoleARN: "assume_role_invalid_source_profile_role_arn",
|
||||||
|
}.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionCopy(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_REGION", "orig_region")
|
||||||
|
|
||||||
|
s := Session{
|
||||||
|
Config: defaults.Config(),
|
||||||
|
Handlers: defaults.Handlers(),
|
||||||
|
}
|
||||||
|
|
||||||
|
newSess := s.Copy(&aws.Config{Region: aws.String("new_region")})
|
||||||
|
|
||||||
|
assert.Equal(t, "orig_region", *s.Config.Region)
|
||||||
|
assert.Equal(t, "new_region", *newSess.Config.Region)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionClientConfig(t *testing.T) {
|
||||||
|
s, err := NewSession(&aws.Config{
|
||||||
|
Credentials: credentials.AnonymousCredentials,
|
||||||
|
Region: aws.String("orig_region"),
|
||||||
|
EndpointResolver: endpoints.ResolverFunc(
|
||||||
|
func(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
||||||
|
if e, a := "mock-service", service; e != a {
|
||||||
|
t.Errorf("expect %q service, got %q", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "other-region", region; e != a {
|
||||||
|
t.Errorf("expect %q region, got %q", e, a)
|
||||||
|
}
|
||||||
|
return endpoints.ResolvedEndpoint{
|
||||||
|
URL: "https://" + service + "." + region + ".amazonaws.com",
|
||||||
|
SigningRegion: region,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
cfg := s.ClientConfig("mock-service", &aws.Config{Region: aws.String("other-region")})
|
||||||
|
|
||||||
|
assert.Equal(t, "https://mock-service.other-region.amazonaws.com", cfg.Endpoint)
|
||||||
|
assert.Equal(t, "other-region", cfg.SigningRegion)
|
||||||
|
assert.Equal(t, "other-region", *cfg.Config.Region)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSession_NoCredentials(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
s, err := NewSession()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.NotNil(t, s.Config.Credentials)
|
||||||
|
assert.NotEqual(t, credentials.AnonymousCredentials, s.Config.Credentials)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSessionWithOptions_OverrideProfile(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "other_profile")
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Profile: "full_profile",
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "full_profile_region", *s.Config.Region)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "full_profile_akid", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "full_profile_secret", creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "SharedConfigCredentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSessionWithOptions_OverrideSharedConfigEnable(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "0")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "full_profile")
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
SharedConfigState: SharedConfigEnable,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "full_profile_region", *s.Config.Region)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "full_profile_akid", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "full_profile_secret", creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "SharedConfigCredentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSessionWithOptions_OverrideSharedConfigDisable(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "full_profile")
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
SharedConfigState: SharedConfigDisable,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Empty(t, *s.Config.Region)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "full_profile_akid", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "full_profile_secret", creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "SharedConfigCredentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSessionWithOptions_OverrideSharedConfigFiles(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "config_file_load_order")
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
SharedConfigFiles: []string{testConfigOtherFilename},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, "shared_config_other_region", *s.Config.Region)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "shared_config_other_akid", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "shared_config_other_secret", creds.SecretAccessKey)
|
||||||
|
assert.Empty(t, creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "SharedConfigCredentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewSessionWithOptions_Overrides(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
InEnvs map[string]string
|
||||||
|
InProfile string
|
||||||
|
OutRegion string
|
||||||
|
OutCreds credentials.Value
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
InEnvs: map[string]string{
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "0",
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
|
||||||
|
"AWS_PROFILE": "other_profile",
|
||||||
|
},
|
||||||
|
InProfile: "full_profile",
|
||||||
|
OutRegion: "full_profile_region",
|
||||||
|
OutCreds: credentials.Value{
|
||||||
|
AccessKeyID: "full_profile_akid",
|
||||||
|
SecretAccessKey: "full_profile_secret",
|
||||||
|
ProviderName: "SharedConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
InEnvs: map[string]string{
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "0",
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
|
||||||
|
"AWS_REGION": "env_region",
|
||||||
|
"AWS_ACCESS_KEY": "env_akid",
|
||||||
|
"AWS_SECRET_ACCESS_KEY": "env_secret",
|
||||||
|
"AWS_PROFILE": "other_profile",
|
||||||
|
},
|
||||||
|
InProfile: "full_profile",
|
||||||
|
OutRegion: "env_region",
|
||||||
|
OutCreds: credentials.Value{
|
||||||
|
AccessKeyID: "env_akid",
|
||||||
|
SecretAccessKey: "env_secret",
|
||||||
|
ProviderName: "EnvConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
InEnvs: map[string]string{
|
||||||
|
"AWS_SDK_LOAD_CONFIG": "0",
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE": testConfigFilename,
|
||||||
|
"AWS_CONFIG_FILE": testConfigOtherFilename,
|
||||||
|
"AWS_PROFILE": "shared_profile",
|
||||||
|
},
|
||||||
|
InProfile: "config_file_load_order",
|
||||||
|
OutRegion: "shared_config_region",
|
||||||
|
OutCreds: credentials.Value{
|
||||||
|
AccessKeyID: "shared_config_akid",
|
||||||
|
SecretAccessKey: "shared_config_secret",
|
||||||
|
ProviderName: "SharedConfigCredentials",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
for k, v := range c.InEnvs {
|
||||||
|
os.Setenv(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := NewSessionWithOptions(Options{
|
||||||
|
Profile: c.InProfile,
|
||||||
|
SharedConfigState: SharedConfigEnable,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, c.OutRegion, *s.Config.Region)
|
||||||
|
assert.Equal(t, c.OutCreds.AccessKeyID, creds.AccessKeyID)
|
||||||
|
assert.Equal(t, c.OutCreds.SecretAccessKey, creds.SecretAccessKey)
|
||||||
|
assert.Equal(t, c.OutCreds.SessionToken, creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, c.OutCreds.ProviderName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const assumeRoleRespMsg = `
|
||||||
|
<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
|
||||||
|
<AssumeRoleResult>
|
||||||
|
<AssumedRoleUser>
|
||||||
|
<Arn>arn:aws:sts::account_id:assumed-role/role/session_name</Arn>
|
||||||
|
<AssumedRoleId>AKID:session_name</AssumedRoleId>
|
||||||
|
</AssumedRoleUser>
|
||||||
|
<Credentials>
|
||||||
|
<AccessKeyId>AKID</AccessKeyId>
|
||||||
|
<SecretAccessKey>SECRET</SecretAccessKey>
|
||||||
|
<SessionToken>SESSION_TOKEN</SessionToken>
|
||||||
|
<Expiration>%s</Expiration>
|
||||||
|
</Credentials>
|
||||||
|
</AssumeRoleResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>request-id</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</AssumeRoleResponse>
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestSesisonAssumeRole(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_REGION", "us-east-1")
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_w_creds")
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte(fmt.Sprintf(assumeRoleRespMsg, time.Now().Add(15*time.Minute).Format("2006-01-02T15:04:05Z"))))
|
||||||
|
}))
|
||||||
|
|
||||||
|
s, err := NewSession(&aws.Config{Endpoint: aws.String(server.URL), DisableSSL: aws.Bool(true)})
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey)
|
||||||
|
assert.Equal(t, "SESSION_TOKEN", creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "AssumeRoleProvider")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionAssumeRole_WithMFA(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_REGION", "us-east-1")
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_w_creds")
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
assert.Equal(t, r.FormValue("SerialNumber"), "0123456789")
|
||||||
|
assert.Equal(t, r.FormValue("TokenCode"), "tokencode")
|
||||||
|
|
||||||
|
w.Write([]byte(fmt.Sprintf(assumeRoleRespMsg, time.Now().Add(15*time.Minute).Format("2006-01-02T15:04:05Z"))))
|
||||||
|
}))
|
||||||
|
|
||||||
|
customProviderCalled := false
|
||||||
|
sess, err := NewSessionWithOptions(Options{
|
||||||
|
Profile: "assume_role_w_mfa",
|
||||||
|
Config: aws.Config{
|
||||||
|
Region: aws.String("us-east-1"),
|
||||||
|
Endpoint: aws.String(server.URL),
|
||||||
|
DisableSSL: aws.Bool(true),
|
||||||
|
},
|
||||||
|
SharedConfigState: SharedConfigEnable,
|
||||||
|
AssumeRoleTokenProvider: func() (string, error) {
|
||||||
|
customProviderCalled = true
|
||||||
|
|
||||||
|
return "tokencode", nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
creds, err := sess.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, customProviderCalled)
|
||||||
|
|
||||||
|
assert.Equal(t, "AKID", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "SECRET", creds.SecretAccessKey)
|
||||||
|
assert.Equal(t, "SESSION_TOKEN", creds.SessionToken)
|
||||||
|
assert.Contains(t, creds.ProviderName, "AssumeRoleProvider")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionAssumeRole_WithMFA_NoTokenProvider(t *testing.T) {
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_REGION", "us-east-1")
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_w_creds")
|
||||||
|
|
||||||
|
_, err := NewSessionWithOptions(Options{
|
||||||
|
Profile: "assume_role_w_mfa",
|
||||||
|
SharedConfigState: SharedConfigEnable,
|
||||||
|
})
|
||||||
|
assert.Equal(t, err, AssumeRoleTokenProviderNotSetError{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionAssumeRole_DisableSharedConfig(t *testing.T) {
|
||||||
|
// Backwards compatibility with Shared config disabled
|
||||||
|
// assume role should not be built into the config.
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "0")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_w_creds")
|
||||||
|
|
||||||
|
s, err := NewSession()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
creds, err := s.Config.Credentials.Get()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, "assume_role_w_creds_akid", creds.AccessKeyID)
|
||||||
|
assert.Equal(t, "assume_role_w_creds_secret", creds.SecretAccessKey)
|
||||||
|
assert.Contains(t, creds.ProviderName, "SharedConfigCredentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSessionAssumeRole_InvalidSourceProfile(t *testing.T) {
|
||||||
|
// Backwards compatibility with Shared config disabled
|
||||||
|
// assume role should not be built into the config.
|
||||||
|
oldEnv := initSessionTestEnv()
|
||||||
|
defer awstesting.PopEnv(oldEnv)
|
||||||
|
|
||||||
|
os.Setenv("AWS_SDK_LOAD_CONFIG", "1")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename)
|
||||||
|
os.Setenv("AWS_PROFILE", "assume_role_invalid_source_profile")
|
||||||
|
|
||||||
|
s, err := NewSession()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "SharedConfigAssumeRoleError: failed to load assume role")
|
||||||
|
assert.Nil(t, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initSessionTestEnv() (oldEnv []string) {
|
||||||
|
oldEnv = awstesting.StashEnv()
|
||||||
|
os.Setenv("AWS_CONFIG_FILE", "file_not_exists")
|
||||||
|
os.Setenv("AWS_SHARED_CREDENTIALS_FILE", "file_not_exists")
|
||||||
|
|
||||||
|
return oldEnv
|
||||||
|
}
|
2
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
|
@ -113,7 +113,7 @@ func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
||||||
|
|
||||||
f, err := ini.Load(b)
|
f, err := ini.Load(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, SharedConfigLoadError{Filename: filename}
|
return nil, SharedConfigLoadError{Filename: filename, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
files = append(files, sharedConfigFile{
|
files = append(files, sharedConfigFile{
|
||||||
|
|
274
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go
generated
vendored
Normal file
274
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go
generated
vendored
Normal file
|
@ -0,0 +1,274 @@
|
||||||
|
package session
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/go-ini/ini"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
testConfigFilename = filepath.Join("testdata", "shared_config")
|
||||||
|
testConfigOtherFilename = filepath.Join("testdata", "shared_config_other")
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoadSharedConfig(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Filenames []string
|
||||||
|
Profile string
|
||||||
|
Expected sharedConfig
|
||||||
|
Err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Filenames: []string{"file_not_exists"},
|
||||||
|
Profile: "default",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigFilename},
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Region: "default_region",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigOtherFilename, testConfigFilename},
|
||||||
|
Profile: "config_file_load_order",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Region: "shared_config_region",
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "shared_config_akid",
|
||||||
|
SecretAccessKey: "shared_config_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigFilename, testConfigOtherFilename},
|
||||||
|
Profile: "config_file_load_order",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Region: "shared_config_other_region",
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "shared_config_other_akid",
|
||||||
|
SecretAccessKey: "shared_config_other_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigOtherFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigOtherFilename, testConfigFilename},
|
||||||
|
Profile: "assume_role",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_role_arn",
|
||||||
|
SourceProfile: "complete_creds",
|
||||||
|
},
|
||||||
|
AssumeRoleSource: &sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "complete_creds_akid",
|
||||||
|
SecretAccessKey: "complete_creds_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigOtherFilename, testConfigFilename},
|
||||||
|
Profile: "assume_role_invalid_source_profile",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_invalid_source_profile_role_arn",
|
||||||
|
SourceProfile: "profile_not_exists",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err: SharedConfigAssumeRoleError{RoleARN: "assume_role_invalid_source_profile_role_arn"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigOtherFilename, testConfigFilename},
|
||||||
|
Profile: "assume_role_w_creds",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "assume_role_w_creds_akid",
|
||||||
|
SecretAccessKey: "assume_role_w_creds_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_w_creds_role_arn",
|
||||||
|
SourceProfile: "assume_role_w_creds",
|
||||||
|
ExternalID: "1234",
|
||||||
|
RoleSessionName: "assume_role_w_creds_session_name",
|
||||||
|
},
|
||||||
|
AssumeRoleSource: &sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "assume_role_w_creds_akid",
|
||||||
|
SecretAccessKey: "assume_role_w_creds_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigOtherFilename, testConfigFilename},
|
||||||
|
Profile: "assume_role_wo_creds",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_wo_creds_role_arn",
|
||||||
|
SourceProfile: "assume_role_wo_creds",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err: SharedConfigAssumeRoleError{RoleARN: "assume_role_wo_creds_role_arn"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{filepath.Join("testdata", "shared_config_invalid_ini")},
|
||||||
|
Profile: "profile_name",
|
||||||
|
Err: SharedConfigLoadError{Filename: filepath.Join("testdata", "shared_config_invalid_ini")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
cfg, err := loadSharedConfig(c.Profile, c.Filenames)
|
||||||
|
if c.Err != nil {
|
||||||
|
assert.Contains(t, err.Error(), c.Err.Error(), "expected error, %d", i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, err, "unexpected error, %d", i)
|
||||||
|
assert.Equal(t, c.Expected, cfg, "not equal, %d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadSharedConfigFromFile(t *testing.T) {
|
||||||
|
filename := testConfigFilename
|
||||||
|
f, err := ini.Load(filename)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to load test config file, %s, %v", filename, err)
|
||||||
|
}
|
||||||
|
iniFile := sharedConfigFile{IniData: f, Filename: filename}
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
Profile string
|
||||||
|
Expected sharedConfig
|
||||||
|
Err error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Profile: "default",
|
||||||
|
Expected: sharedConfig{Region: "default_region"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "alt_profile_name",
|
||||||
|
Expected: sharedConfig{Region: "alt_profile_name_region"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "short_profile_name_first",
|
||||||
|
Expected: sharedConfig{Region: "short_profile_name_first_short"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "partial_creds",
|
||||||
|
Expected: sharedConfig{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "complete_creds",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "complete_creds_akid",
|
||||||
|
SecretAccessKey: "complete_creds_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "complete_creds_with_token",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "complete_creds_with_token_akid",
|
||||||
|
SecretAccessKey: "complete_creds_with_token_secret",
|
||||||
|
SessionToken: "complete_creds_with_token_token",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "full_profile",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
Creds: credentials.Value{
|
||||||
|
AccessKeyID: "full_profile_akid",
|
||||||
|
SecretAccessKey: "full_profile_secret",
|
||||||
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
|
||||||
|
},
|
||||||
|
Region: "full_profile_region",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "partial_assume_role",
|
||||||
|
Expected: sharedConfig{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "assume_role",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_role_arn",
|
||||||
|
SourceProfile: "complete_creds",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "assume_role_w_mfa",
|
||||||
|
Expected: sharedConfig{
|
||||||
|
AssumeRole: assumeRoleConfig{
|
||||||
|
RoleARN: "assume_role_role_arn",
|
||||||
|
SourceProfile: "complete_creds",
|
||||||
|
MFASerial: "0123456789",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Profile: "does_not_exists",
|
||||||
|
Err: SharedConfigProfileNotExistsError{Profile: "does_not_exists"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
cfg := sharedConfig{}
|
||||||
|
|
||||||
|
err := cfg.setFromIniFile(c.Profile, iniFile)
|
||||||
|
if c.Err != nil {
|
||||||
|
assert.Contains(t, err.Error(), c.Err.Error(), "expected error, %d", i)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, err, "unexpected error, %d", i)
|
||||||
|
assert.Equal(t, c.Expected, cfg, "not equal, %d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadSharedConfigIniFiles(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Filenames []string
|
||||||
|
Expected []sharedConfigFile
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Filenames: []string{"not_exists", testConfigFilename},
|
||||||
|
Expected: []sharedConfigFile{
|
||||||
|
{Filename: testConfigFilename},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Filenames: []string{testConfigFilename, testConfigOtherFilename},
|
||||||
|
Expected: []sharedConfigFile{
|
||||||
|
{Filename: testConfigFilename},
|
||||||
|
{Filename: testConfigOtherFilename},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range cases {
|
||||||
|
files, err := loadSharedConfigIniFiles(c.Filenames)
|
||||||
|
assert.NoError(t, err, "unexpected error, %d", i)
|
||||||
|
assert.Equal(t, len(c.Expected), len(files), "expected num files, %d", i)
|
||||||
|
|
||||||
|
for i, expectedFile := range c.Expected {
|
||||||
|
assert.Equal(t, expectedFile.Filename, files[i].Filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config
generated
vendored
Normal file
65
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
[default]
|
||||||
|
s3 =
|
||||||
|
unsupported_key=123
|
||||||
|
other_unsupported=abc
|
||||||
|
|
||||||
|
region = default_region
|
||||||
|
|
||||||
|
[profile alt_profile_name]
|
||||||
|
region = alt_profile_name_region
|
||||||
|
|
||||||
|
[short_profile_name_first]
|
||||||
|
region = short_profile_name_first_short
|
||||||
|
|
||||||
|
[profile short_profile_name_first]
|
||||||
|
region = short_profile_name_first_alt
|
||||||
|
|
||||||
|
[partial_creds]
|
||||||
|
aws_access_key_id = partial_creds_akid
|
||||||
|
|
||||||
|
[complete_creds]
|
||||||
|
aws_access_key_id = complete_creds_akid
|
||||||
|
aws_secret_access_key = complete_creds_secret
|
||||||
|
|
||||||
|
[complete_creds_with_token]
|
||||||
|
aws_access_key_id = complete_creds_with_token_akid
|
||||||
|
aws_secret_access_key = complete_creds_with_token_secret
|
||||||
|
aws_session_token = complete_creds_with_token_token
|
||||||
|
|
||||||
|
[full_profile]
|
||||||
|
aws_access_key_id = full_profile_akid
|
||||||
|
aws_secret_access_key = full_profile_secret
|
||||||
|
region = full_profile_region
|
||||||
|
|
||||||
|
[config_file_load_order]
|
||||||
|
region = shared_config_region
|
||||||
|
aws_access_key_id = shared_config_akid
|
||||||
|
aws_secret_access_key = shared_config_secret
|
||||||
|
|
||||||
|
[partial_assume_role]
|
||||||
|
role_arn = partial_assume_role_role_arn
|
||||||
|
|
||||||
|
[assume_role]
|
||||||
|
role_arn = assume_role_role_arn
|
||||||
|
source_profile = complete_creds
|
||||||
|
|
||||||
|
[assume_role_w_mfa]
|
||||||
|
role_arn = assume_role_role_arn
|
||||||
|
source_profile = complete_creds
|
||||||
|
mfa_serial = 0123456789
|
||||||
|
|
||||||
|
[assume_role_invalid_source_profile]
|
||||||
|
role_arn = assume_role_invalid_source_profile_role_arn
|
||||||
|
source_profile = profile_not_exists
|
||||||
|
|
||||||
|
[assume_role_w_creds]
|
||||||
|
role_arn = assume_role_w_creds_role_arn
|
||||||
|
source_profile = assume_role_w_creds
|
||||||
|
external_id = 1234
|
||||||
|
role_session_name = assume_role_w_creds_session_name
|
||||||
|
aws_access_key_id = assume_role_w_creds_akid
|
||||||
|
aws_secret_access_key = assume_role_w_creds_secret
|
||||||
|
|
||||||
|
[assume_role_wo_creds]
|
||||||
|
role_arn = assume_role_wo_creds_role_arn
|
||||||
|
source_profile = assume_role_wo_creds
|
1
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config_invalid_ini
generated
vendored
Normal file
1
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config_invalid_ini
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
[profile_nam
|
17
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config_other
generated
vendored
Normal file
17
vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config_other
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
[default]
|
||||||
|
region = default_region
|
||||||
|
|
||||||
|
[partial_creds]
|
||||||
|
aws_access_key_id = AKID
|
||||||
|
|
||||||
|
[profile alt_profile_name]
|
||||||
|
region = alt_profile_name_region
|
||||||
|
|
||||||
|
[creds_from_credentials]
|
||||||
|
aws_access_key_id = creds_from_config_akid
|
||||||
|
aws_secret_access_key = creds_from_config_secret
|
||||||
|
|
||||||
|
[config_file_load_order]
|
||||||
|
region = shared_config_other_region
|
||||||
|
aws_access_key_id = shared_config_other_akid
|
||||||
|
aws_secret_access_key = shared_config_other_secret
|
86
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/functional_1_5_test.go
generated
vendored
Normal file
86
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/functional_1_5_test.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
// +build go1.5
|
||||||
|
|
||||||
|
package v4_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStandaloneSign(t *testing.T) {
|
||||||
|
creds := unit.Session.Config.Credentials
|
||||||
|
signer := v4.NewSigner(creds)
|
||||||
|
|
||||||
|
for _, c := range standaloneSignCases {
|
||||||
|
host := fmt.Sprintf("https://%s.%s.%s.amazonaws.com",
|
||||||
|
c.SubDomain, c.Region, c.Service)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", host, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL.EscapedPath() will be used by the signer to get the
|
||||||
|
// escaped form of the request's URI path.
|
||||||
|
req.URL.Path = c.OrigURI
|
||||||
|
req.URL.RawQuery = c.OrigQuery
|
||||||
|
|
||||||
|
_, err = signer.Sign(req, nil, c.Service, c.Region, time.Unix(0, 0))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := req.Header.Get("Authorization")
|
||||||
|
if e, a := c.ExpSig, actual; e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := c.OrigURI, req.URL.Path; e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := c.EscapedURI, req.URL.EscapedPath(); e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStandaloneSign_RawPath(t *testing.T) {
|
||||||
|
creds := unit.Session.Config.Credentials
|
||||||
|
signer := v4.NewSigner(creds)
|
||||||
|
|
||||||
|
for _, c := range standaloneSignCases {
|
||||||
|
host := fmt.Sprintf("https://%s.%s.%s.amazonaws.com",
|
||||||
|
c.SubDomain, c.Region, c.Service)
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", host, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL.EscapedPath() will be used by the signer to get the
|
||||||
|
// escaped form of the request's URI path.
|
||||||
|
req.URL.Path = c.OrigURI
|
||||||
|
req.URL.RawPath = c.EscapedURI
|
||||||
|
req.URL.RawQuery = c.OrigQuery
|
||||||
|
|
||||||
|
_, err = signer.Sign(req, nil, c.Service, c.Region, time.Unix(0, 0))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := req.Header.Get("Authorization")
|
||||||
|
if e, a := c.ExpSig, actual; e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := c.OrigURI, req.URL.Path; e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := c.EscapedURI, req.URL.EscapedPath(); e != a {
|
||||||
|
t.Errorf("expected %v, but recieved %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
166
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/functional_test.go
generated
vendored
Normal file
166
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/functional_test.go
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
package v4_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting/unit"
|
||||||
|
"github.com/aws/aws-sdk-go/service/s3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var standaloneSignCases = []struct {
|
||||||
|
OrigURI string
|
||||||
|
OrigQuery string
|
||||||
|
Region, Service, SubDomain string
|
||||||
|
ExpSig string
|
||||||
|
EscapedURI string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
OrigURI: `/logs-*/_search`,
|
||||||
|
OrigQuery: `pretty=true`,
|
||||||
|
Region: "us-west-2", Service: "es", SubDomain: "hostname-clusterkey",
|
||||||
|
EscapedURI: `/logs-%2A/_search`,
|
||||||
|
ExpSig: `AWS4-HMAC-SHA256 Credential=AKID/19700101/us-west-2/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=79d0760751907af16f64a537c1242416dacf51204a7dd5284492d15577973b91`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPresignHandler(t *testing.T) {
|
||||||
|
svc := s3.New(unit.Session)
|
||||||
|
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
|
||||||
|
Bucket: aws.String("bucket"),
|
||||||
|
Key: aws.String("key"),
|
||||||
|
ContentDisposition: aws.String("a+b c$d"),
|
||||||
|
ACL: aws.String("public-read"),
|
||||||
|
})
|
||||||
|
req.Time = time.Unix(0, 0)
|
||||||
|
urlstr, err := req.Presign(5 * time.Minute)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedHost := "bucket.s3.mock-region.amazonaws.com"
|
||||||
|
expectedDate := "19700101T000000Z"
|
||||||
|
expectedHeaders := "content-disposition;host;x-amz-acl"
|
||||||
|
expectedSig := "a46583256431b09eb45ba4af2e6286d96a9835ed13721023dc8076dfdcb90fcb"
|
||||||
|
expectedCred := "AKID/19700101/mock-region/s3/aws4_request"
|
||||||
|
|
||||||
|
u, _ := url.Parse(urlstr)
|
||||||
|
urlQ := u.Query()
|
||||||
|
if e, a := expectedHost, u.Host; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20
|
||||||
|
t.Errorf("expect %v not to be in %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPresignRequest(t *testing.T) {
|
||||||
|
svc := s3.New(unit.Session)
|
||||||
|
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
|
||||||
|
Bucket: aws.String("bucket"),
|
||||||
|
Key: aws.String("key"),
|
||||||
|
ContentDisposition: aws.String("a+b c$d"),
|
||||||
|
ACL: aws.String("public-read"),
|
||||||
|
})
|
||||||
|
req.Time = time.Unix(0, 0)
|
||||||
|
urlstr, headers, err := req.PresignRequest(5 * time.Minute)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedHost := "bucket.s3.mock-region.amazonaws.com"
|
||||||
|
expectedDate := "19700101T000000Z"
|
||||||
|
expectedHeaders := "content-disposition;host;x-amz-acl"
|
||||||
|
expectedSig := "a46583256431b09eb45ba4af2e6286d96a9835ed13721023dc8076dfdcb90fcb"
|
||||||
|
expectedCred := "AKID/19700101/mock-region/s3/aws4_request"
|
||||||
|
expectedHeaderMap := http.Header{
|
||||||
|
"x-amz-acl": []string{"public-read"},
|
||||||
|
"content-disposition": []string{"a+b c$d"},
|
||||||
|
}
|
||||||
|
|
||||||
|
u, _ := url.Parse(urlstr)
|
||||||
|
urlQ := u.Query()
|
||||||
|
if e, a := expectedHost, u.Host; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedSig, urlQ.Get("X-Amz-Signature"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedCred, urlQ.Get("X-Amz-Credential"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedHeaders, urlQ.Get("X-Amz-SignedHeaders"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedDate, urlQ.Get("X-Amz-Date"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedHeaderMap, headers; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "300", urlQ.Get("X-Amz-Expires"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := "UNSIGNED-PAYLOAD", urlQ.Get("X-Amz-Content-Sha256"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, a := "+", urlstr; strings.Contains(a, e) { // + encoded as %20
|
||||||
|
t.Errorf("expect %v not to be in %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStandaloneSign_CustomURIEscape(t *testing.T) {
|
||||||
|
var expectSig = `AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/es/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=6601e883cc6d23871fd6c2a394c5677ea2b8c82b04a6446786d64cd74f520967`
|
||||||
|
|
||||||
|
creds := unit.Session.Config.Credentials
|
||||||
|
signer := v4.NewSigner(creds, func(s *v4.Signer) {
|
||||||
|
s.DisableURIPathEscaping = true
|
||||||
|
})
|
||||||
|
|
||||||
|
host := "https://subdomain.us-east-1.es.amazonaws.com"
|
||||||
|
req, err := http.NewRequest("GET", host, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.URL.Path = `/log-*/_search`
|
||||||
|
req.URL.Opaque = "//subdomain.us-east-1.es.amazonaws.com/log-%2A/_search"
|
||||||
|
|
||||||
|
_, err = signer.Sign(req, nil, "es", "us-east-1", time.Unix(0, 0))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := req.Header.Get("Authorization")
|
||||||
|
if e, a := expectSig, actual; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
77
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules_test.go
generated
vendored
Normal file
77
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules_test.go
generated
vendored
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package v4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRuleCheckWhitelist(t *testing.T) {
|
||||||
|
w := whitelist{
|
||||||
|
mapRule{
|
||||||
|
"Cache-Control": struct{}{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !w.IsValid("Cache-Control") {
|
||||||
|
t.Error("expected true value")
|
||||||
|
}
|
||||||
|
if w.IsValid("Cache-") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuleCheckBlacklist(t *testing.T) {
|
||||||
|
b := blacklist{
|
||||||
|
mapRule{
|
||||||
|
"Cache-Control": struct{}{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.IsValid("Cache-Control") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
if !b.IsValid("Cache-") {
|
||||||
|
t.Error("expected true value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuleCheckPattern(t *testing.T) {
|
||||||
|
p := patterns{"X-Amz-Meta-"}
|
||||||
|
|
||||||
|
if !p.IsValid("X-Amz-Meta-") {
|
||||||
|
t.Error("expected true value")
|
||||||
|
}
|
||||||
|
if !p.IsValid("X-Amz-Meta-Star") {
|
||||||
|
t.Error("expected true value")
|
||||||
|
}
|
||||||
|
if p.IsValid("Cache-") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRuleComplexWhitelist(t *testing.T) {
|
||||||
|
w := rules{
|
||||||
|
whitelist{
|
||||||
|
mapRule{
|
||||||
|
"Cache-Control": struct{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
patterns{"X-Amz-Meta-"},
|
||||||
|
}
|
||||||
|
|
||||||
|
r := rules{
|
||||||
|
inclusiveRules{patterns{"X-Amz-"}, blacklist{w}},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.IsValid("X-Amz-Blah") {
|
||||||
|
t.Error("expected true value")
|
||||||
|
}
|
||||||
|
if r.IsValid("X-Amz-Meta-") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
if r.IsValid("X-Amz-Meta-Star") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
if r.IsValid("Cache-Control") {
|
||||||
|
t.Error("expected false value")
|
||||||
|
}
|
||||||
|
}
|
89
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
89
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
|
@ -45,7 +45,7 @@
|
||||||
// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
|
// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
|
||||||
// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
|
// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
|
||||||
// request URL. https://github.com/golang/go/issues/16847 points to a bug in
|
// request URL. https://github.com/golang/go/issues/16847 points to a bug in
|
||||||
// Go pre 1.8 that failes to make HTTP2 requests using absolute URL in the HTTP
|
// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP
|
||||||
// message. URL.Opaque generally will force Go to make requests with absolute URL.
|
// message. URL.Opaque generally will force Go to make requests with absolute URL.
|
||||||
// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
|
// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
|
||||||
// or url.EscapedPath will ignore the RawPath escaping.
|
// or url.EscapedPath will ignore the RawPath escaping.
|
||||||
|
@ -55,7 +55,6 @@
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
@ -269,7 +268,7 @@ type signingCtx struct {
|
||||||
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
||||||
// only compute the hash if the request header value is empty.
|
// only compute the hash if the request header value is empty.
|
||||||
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
||||||
return v4.signWithBody(r, body, service, region, 0, signTime)
|
return v4.signWithBody(r, body, service, region, 0, false, signTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presign signs AWS v4 requests with the provided body, service name, region
|
// Presign signs AWS v4 requests with the provided body, service name, region
|
||||||
|
@ -303,10 +302,10 @@ func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region strin
|
||||||
// presigned request's signature you can set the "X-Amz-Content-Sha256"
|
// presigned request's signature you can set the "X-Amz-Content-Sha256"
|
||||||
// HTTP header and that will be included in the request's signature.
|
// HTTP header and that will be included in the request's signature.
|
||||||
func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
||||||
return v4.signWithBody(r, body, service, region, exp, signTime)
|
return v4.signWithBody(r, body, service, region, exp, true, signTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) {
|
||||||
currentTimeFn := v4.currentTimeFn
|
currentTimeFn := v4.currentTimeFn
|
||||||
if currentTimeFn == nil {
|
if currentTimeFn == nil {
|
||||||
currentTimeFn = time.Now
|
currentTimeFn = time.Now
|
||||||
|
@ -318,7 +317,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
|
||||||
Query: r.URL.Query(),
|
Query: r.URL.Query(),
|
||||||
Time: signTime,
|
Time: signTime,
|
||||||
ExpireTime: exp,
|
ExpireTime: exp,
|
||||||
isPresign: exp != 0,
|
isPresign: isPresign,
|
||||||
ServiceName: service,
|
ServiceName: service,
|
||||||
Region: region,
|
Region: region,
|
||||||
DisableURIPathEscaping: v4.DisableURIPathEscaping,
|
DisableURIPathEscaping: v4.DisableURIPathEscaping,
|
||||||
|
@ -402,7 +401,7 @@ var SignRequestHandler = request.NamedHandler{
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignSDKRequest signs an AWS request with the V4 signature. This
|
// SignSDKRequest signs an AWS request with the V4 signature. This
|
||||||
// request handler is bested used only with the SDK's built in service client's
|
// request handler should only be used with the SDK's built in service client's
|
||||||
// API operation requests.
|
// API operation requests.
|
||||||
//
|
//
|
||||||
// This function should not be used on its on its own, but in conjunction with
|
// This function should not be used on its on its own, but in conjunction with
|
||||||
|
@ -468,7 +467,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
||||||
name, region, req.ExpireTime, signingTime,
|
name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
req.Error = err
|
req.Error = err
|
||||||
|
@ -503,6 +502,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
||||||
ctx.buildTime() // no depends
|
ctx.buildTime() // no depends
|
||||||
ctx.buildCredentialString() // no depends
|
ctx.buildCredentialString() // no depends
|
||||||
|
|
||||||
|
ctx.buildBodyDigest()
|
||||||
|
|
||||||
unsignedHeaders := ctx.Request.Header
|
unsignedHeaders := ctx.Request.Header
|
||||||
if ctx.isPresign {
|
if ctx.isPresign {
|
||||||
if !disableHeaderHoisting {
|
if !disableHeaderHoisting {
|
||||||
|
@ -514,7 +515,6 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.buildBodyDigest()
|
|
||||||
ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
||||||
ctx.buildCanonicalString() // depends on canon headers / signed headers
|
ctx.buildCanonicalString() // depends on canon headers / signed headers
|
||||||
ctx.buildStringToSign() // depends on canon string
|
ctx.buildStringToSign() // depends on canon string
|
||||||
|
@ -604,14 +604,18 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
|
||||||
headerValues := make([]string, len(headers))
|
headerValues := make([]string, len(headers))
|
||||||
for i, k := range headers {
|
for i, k := range headers {
|
||||||
if k == "host" {
|
if k == "host" {
|
||||||
|
if ctx.Request.Host != "" {
|
||||||
|
headerValues[i] = "host:" + ctx.Request.Host
|
||||||
|
} else {
|
||||||
headerValues[i] = "host:" + ctx.Request.URL.Host
|
headerValues[i] = "host:" + ctx.Request.URL.Host
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
headerValues[i] = k + ":" +
|
headerValues[i] = k + ":" +
|
||||||
strings.Join(ctx.SignedHeaderVals[k], ",")
|
strings.Join(ctx.SignedHeaderVals[k], ",")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stripExcessSpaces(headerValues)
|
||||||
ctx.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n")
|
ctx.canonicalHeaders = strings.Join(headerValues, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *signingCtx) buildCanonicalString() {
|
func (ctx *signingCtx) buildCanonicalString() {
|
||||||
|
@ -713,49 +717,46 @@ func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||||
return hash.Sum(nil)
|
return hash.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
const doubleSpaces = " "
|
const doubleSpace = " "
|
||||||
|
|
||||||
var doubleSpaceBytes = []byte(doubleSpaces)
|
// stripExcessSpaces will rewrite the passed in slice's string values to not
|
||||||
|
// contain muliple side-by-side spaces.
|
||||||
func stripExcessSpaces(headerVals []string) []string {
|
func stripExcessSpaces(vals []string) {
|
||||||
vals := make([]string, len(headerVals))
|
var j, k, l, m, spaces int
|
||||||
for i, str := range headerVals {
|
for i, str := range vals {
|
||||||
// Trim leading and trailing spaces
|
// Trim trailing spaces
|
||||||
trimmed := strings.TrimSpace(str)
|
for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
|
||||||
|
|
||||||
idx := strings.Index(trimmed, doubleSpaces)
|
|
||||||
var buf []byte
|
|
||||||
for idx > -1 {
|
|
||||||
// Multiple adjacent spaces found
|
|
||||||
if buf == nil {
|
|
||||||
// first time create the buffer
|
|
||||||
buf = []byte(trimmed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stripToIdx := -1
|
// Trim leading spaces
|
||||||
for j := idx + 1; j < len(buf); j++ {
|
for k = 0; k < j && str[k] == ' '; k++ {
|
||||||
if buf[j] != ' ' {
|
|
||||||
buf = append(buf[:idx+1], buf[j:]...)
|
|
||||||
stripToIdx = j
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
str = str[k : j+1]
|
||||||
|
|
||||||
|
// Strip multiple spaces.
|
||||||
|
j = strings.Index(str, doubleSpace)
|
||||||
|
if j < 0 {
|
||||||
|
vals[i] = str
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if stripToIdx >= 0 {
|
buf := []byte(str)
|
||||||
idx = bytes.Index(buf[stripToIdx:], doubleSpaceBytes)
|
for k, m, l = j, j, len(buf); k < l; k++ {
|
||||||
if idx >= 0 {
|
if buf[k] == ' ' {
|
||||||
idx += stripToIdx
|
if spaces == 0 {
|
||||||
|
// First space.
|
||||||
|
buf[m] = buf[k]
|
||||||
|
m++
|
||||||
}
|
}
|
||||||
|
spaces++
|
||||||
} else {
|
} else {
|
||||||
idx = -1
|
// End of multiple spaces.
|
||||||
|
spaces = 0
|
||||||
|
buf[m] = buf[k]
|
||||||
|
m++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if buf != nil {
|
vals[i] = string(buf[:m])
|
||||||
vals[i] = string(buf)
|
|
||||||
} else {
|
|
||||||
vals[i] = trimmed
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return vals
|
|
||||||
}
|
}
|
||||||
|
|
644
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4_test.go
generated
vendored
Normal file
644
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4_test.go
generated
vendored
Normal file
|
@ -0,0 +1,644 @@
|
||||||
|
package v4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/awstesting"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStripExcessHeaders(t *testing.T) {
|
||||||
|
vals := []string{
|
||||||
|
"",
|
||||||
|
"123",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 3 ",
|
||||||
|
" 1 2 3",
|
||||||
|
"1 2 3",
|
||||||
|
"1 23",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 ",
|
||||||
|
" 1 2 ",
|
||||||
|
"12 3",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1abc123",
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []string{
|
||||||
|
"",
|
||||||
|
"123",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 3",
|
||||||
|
"1 23",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2",
|
||||||
|
"1 2",
|
||||||
|
"12 3",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1abc123",
|
||||||
|
}
|
||||||
|
|
||||||
|
stripExcessSpaces(vals)
|
||||||
|
for i := 0; i < len(vals); i++ {
|
||||||
|
if e, a := expected[i], vals[i]; e != a {
|
||||||
|
t.Errorf("%d, expect %v, got %v", i, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildRequest(serviceName, region, body string) (*http.Request, io.ReadSeeker) {
|
||||||
|
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
|
||||||
|
reader := strings.NewReader(body)
|
||||||
|
req, _ := http.NewRequest("POST", endpoint, reader)
|
||||||
|
req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()"
|
||||||
|
req.Header.Add("X-Amz-Target", "prefix.Operation")
|
||||||
|
req.Header.Add("Content-Type", "application/x-amz-json-1.0")
|
||||||
|
req.Header.Add("Content-Length", string(len(body)))
|
||||||
|
req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
|
||||||
|
req.Header.Add("X-Amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
|
||||||
|
req.Header.Add("X-amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
|
||||||
|
return req, reader
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSigner() Signer {
|
||||||
|
return Signer{
|
||||||
|
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeWS(text string) string {
|
||||||
|
text = strings.Replace(text, " ", "", -1)
|
||||||
|
text = strings.Replace(text, "\n", "", -1)
|
||||||
|
text = strings.Replace(text, "\t", "", -1)
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertEqual(t *testing.T, expected, given string) {
|
||||||
|
if removeWS(expected) != removeWS(given) {
|
||||||
|
t.Errorf("\nExpected: %s\nGiven: %s", expected, given)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPresignRequest(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Presign(req, body, "dynamodb", "us-east-1", 300*time.Second, time.Unix(0, 0))
|
||||||
|
|
||||||
|
expectedDate := "19700101T000000Z"
|
||||||
|
expectedHeaders := "content-length;content-type;host;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore"
|
||||||
|
expectedSig := "ea7856749041f727690c580569738282e99c79355fe0d8f125d3b5535d2ece83"
|
||||||
|
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
|
||||||
|
expectedTarget := "prefix.Operation"
|
||||||
|
|
||||||
|
q := req.URL.Query()
|
||||||
|
if e, a := expectedSig, q.Get("X-Amz-Signature"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedCred, q.Get("X-Amz-Credential"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedHeaders, q.Get("X-Amz-SignedHeaders"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedDate, q.Get("X-Amz-Date"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if a := q.Get("X-Amz-Meta-Other-Header"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty", a)
|
||||||
|
}
|
||||||
|
if e, a := expectedTarget, q.Get("X-Amz-Target"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPresignBodyWithArrayRequest(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a"
|
||||||
|
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Presign(req, body, "dynamodb", "us-east-1", 300*time.Second, time.Unix(0, 0))
|
||||||
|
|
||||||
|
expectedDate := "19700101T000000Z"
|
||||||
|
expectedHeaders := "content-length;content-type;host;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore"
|
||||||
|
expectedSig := "fef6002062400bbf526d70f1a6456abc0fb2e213fe1416012737eebd42a62924"
|
||||||
|
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
|
||||||
|
expectedTarget := "prefix.Operation"
|
||||||
|
|
||||||
|
q := req.URL.Query()
|
||||||
|
if e, a := expectedSig, q.Get("X-Amz-Signature"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedCred, q.Get("X-Amz-Credential"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedHeaders, q.Get("X-Amz-SignedHeaders"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedDate, q.Get("X-Amz-Date"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if a := q.Get("X-Amz-Meta-Other-Header"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
if e, a := expectedTarget, q.Get("X-Amz-Target"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignRequest(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Sign(req, body, "dynamodb", "us-east-1", time.Unix(0, 0))
|
||||||
|
|
||||||
|
expectedDate := "19700101T000000Z"
|
||||||
|
expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore;x-amz-security-token;x-amz-target, Signature=ea766cabd2ec977d955a3c2bae1ae54f4515d70752f2207618396f20aa85bd21"
|
||||||
|
|
||||||
|
q := req.Header
|
||||||
|
if e, a := expectedSig, q.Get("Authorization"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := expectedDate, q.Get("X-Amz-Date"); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignBodyS3(t *testing.T) {
|
||||||
|
req, body := buildRequest("s3", "us-east-1", "hello")
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Sign(req, body, "s3", "us-east-1", time.Now())
|
||||||
|
hash := req.Header.Get("X-Amz-Content-Sha256")
|
||||||
|
if e, a := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignBodyGlacier(t *testing.T) {
|
||||||
|
req, body := buildRequest("glacier", "us-east-1", "hello")
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Sign(req, body, "glacier", "us-east-1", time.Now())
|
||||||
|
hash := req.Header.Get("X-Amz-Content-Sha256")
|
||||||
|
if e, a := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824", hash; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPresignEmptyBodyS3(t *testing.T) {
|
||||||
|
req, body := buildRequest("s3", "us-east-1", "hello")
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Presign(req, body, "s3", "us-east-1", 5*time.Minute, time.Now())
|
||||||
|
hash := req.Header.Get("X-Amz-Content-Sha256")
|
||||||
|
if e, a := "UNSIGNED-PAYLOAD", hash; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignPrecomputedBodyChecksum(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "hello")
|
||||||
|
req.Header.Set("X-Amz-Content-Sha256", "PRECOMPUTED")
|
||||||
|
signer := buildSigner()
|
||||||
|
signer.Sign(req, body, "dynamodb", "us-east-1", time.Now())
|
||||||
|
hash := req.Header.Get("X-Amz-Content-Sha256")
|
||||||
|
if e, a := "PRECOMPUTED", hash; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnonymousCredentials(t *testing.T) {
|
||||||
|
svc := awstesting.NewClient(&aws.Config{Credentials: credentials.AnonymousCredentials})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
SignSDKRequest(r)
|
||||||
|
|
||||||
|
urlQ := r.HTTPRequest.URL.Query()
|
||||||
|
if a := urlQ.Get("X-Amz-Signature"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
if a := urlQ.Get("X-Amz-Credential"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
if a := urlQ.Get("X-Amz-SignedHeaders"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
if a := urlQ.Get("X-Amz-Date"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
|
||||||
|
hQ := r.HTTPRequest.Header
|
||||||
|
if a := hQ.Get("Authorization"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
if a := hQ.Get("X-Amz-Date"); len(a) != 0 {
|
||||||
|
t.Errorf("expect %v to be empty, was not", a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIgnoreResignRequestWithValidCreds(t *testing.T) {
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
|
||||||
|
Region: aws.String("us-west-2"),
|
||||||
|
})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
SignSDKRequest(r)
|
||||||
|
sig := r.HTTPRequest.Header.Get("Authorization")
|
||||||
|
|
||||||
|
signSDKRequestWithCurrTime(r, func() time.Time {
|
||||||
|
// Simulate one second has passed so that signature's date changes
|
||||||
|
// when it is resigned.
|
||||||
|
return time.Now().Add(1 * time.Second)
|
||||||
|
})
|
||||||
|
if e, a := sig, r.HTTPRequest.Header.Get("Authorization"); e == a {
|
||||||
|
t.Errorf("expect %v to be %v, but was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIgnorePreResignRequestWithValidCreds(t *testing.T) {
|
||||||
|
svc := awstesting.NewClient(&aws.Config{
|
||||||
|
Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
|
||||||
|
Region: aws.String("us-west-2"),
|
||||||
|
})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
r.ExpireTime = time.Minute * 10
|
||||||
|
|
||||||
|
SignSDKRequest(r)
|
||||||
|
sig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature")
|
||||||
|
|
||||||
|
signSDKRequestWithCurrTime(r, func() time.Time {
|
||||||
|
// Simulate one second has passed so that signature's date changes
|
||||||
|
// when it is resigned.
|
||||||
|
return time.Now().Add(1 * time.Second)
|
||||||
|
})
|
||||||
|
if e, a := sig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"); e == a {
|
||||||
|
t.Errorf("expect %v to be %v, but was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResignRequestExpiredCreds(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
svc := awstesting.NewClient(&aws.Config{Credentials: creds})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
SignSDKRequest(r)
|
||||||
|
querySig := r.HTTPRequest.Header.Get("Authorization")
|
||||||
|
var origSignedHeaders string
|
||||||
|
for _, p := range strings.Split(querySig, ", ") {
|
||||||
|
if strings.HasPrefix(p, "SignedHeaders=") {
|
||||||
|
origSignedHeaders = p[len("SignedHeaders="):]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if a := origSignedHeaders; len(a) == 0 {
|
||||||
|
t.Errorf("expect not to be empty, but was")
|
||||||
|
}
|
||||||
|
if e, a := origSignedHeaders, "authorization"; strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to not be in %v, but was", e, a)
|
||||||
|
}
|
||||||
|
origSignedAt := r.LastSignedAt
|
||||||
|
|
||||||
|
creds.Expire()
|
||||||
|
|
||||||
|
signSDKRequestWithCurrTime(r, func() time.Time {
|
||||||
|
// Simulate one second has passed so that signature's date changes
|
||||||
|
// when it is resigned.
|
||||||
|
return time.Now().Add(1 * time.Second)
|
||||||
|
})
|
||||||
|
updatedQuerySig := r.HTTPRequest.Header.Get("Authorization")
|
||||||
|
if e, a := querySig, updatedQuerySig; e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
var updatedSignedHeaders string
|
||||||
|
for _, p := range strings.Split(updatedQuerySig, ", ") {
|
||||||
|
if strings.HasPrefix(p, "SignedHeaders=") {
|
||||||
|
updatedSignedHeaders = p[len("SignedHeaders="):]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if a := updatedSignedHeaders; len(a) == 0 {
|
||||||
|
t.Errorf("expect not to be empty, but was")
|
||||||
|
}
|
||||||
|
if e, a := updatedQuerySig, "authorization"; strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to not be in %v, but was", e, a)
|
||||||
|
}
|
||||||
|
if e, a := origSignedAt, r.LastSignedAt; e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPreResignRequestExpiredCreds(t *testing.T) {
|
||||||
|
provider := &credentials.StaticProvider{Value: credentials.Value{
|
||||||
|
AccessKeyID: "AKID",
|
||||||
|
SecretAccessKey: "SECRET",
|
||||||
|
SessionToken: "SESSION",
|
||||||
|
}}
|
||||||
|
creds := credentials.NewCredentials(provider)
|
||||||
|
svc := awstesting.NewClient(&aws.Config{Credentials: creds})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
r.ExpireTime = time.Minute * 10
|
||||||
|
|
||||||
|
SignSDKRequest(r)
|
||||||
|
querySig := r.HTTPRequest.URL.Query().Get("X-Amz-Signature")
|
||||||
|
signedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders")
|
||||||
|
if a := signedHeaders; len(a) == 0 {
|
||||||
|
t.Errorf("expect not to be empty, but was")
|
||||||
|
}
|
||||||
|
origSignedAt := r.LastSignedAt
|
||||||
|
|
||||||
|
creds.Expire()
|
||||||
|
|
||||||
|
signSDKRequestWithCurrTime(r, func() time.Time {
|
||||||
|
// Simulate the request occurred 15 minutes in the past
|
||||||
|
return time.Now().Add(-48 * time.Hour)
|
||||||
|
})
|
||||||
|
if e, a := querySig, r.HTTPRequest.URL.Query().Get("X-Amz-Signature"); e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
resignedHeaders := r.HTTPRequest.URL.Query().Get("X-Amz-SignedHeaders")
|
||||||
|
if e, a := signedHeaders, resignedHeaders; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
if e, a := signedHeaders, "x-amz-signedHeaders"; strings.Contains(a, e) {
|
||||||
|
t.Errorf("expect %v to not be in %v, but was", e, a)
|
||||||
|
}
|
||||||
|
if e, a := origSignedAt, r.LastSignedAt; e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResignRequestExpiredRequest(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
svc := awstesting.NewClient(&aws.Config{Credentials: creds})
|
||||||
|
r := svc.NewRequest(
|
||||||
|
&request.Operation{
|
||||||
|
Name: "BatchGetItem",
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
SignSDKRequest(r)
|
||||||
|
querySig := r.HTTPRequest.Header.Get("Authorization")
|
||||||
|
origSignedAt := r.LastSignedAt
|
||||||
|
|
||||||
|
signSDKRequestWithCurrTime(r, func() time.Time {
|
||||||
|
// Simulate the request occurred 15 minutes in the past
|
||||||
|
return time.Now().Add(15 * time.Minute)
|
||||||
|
})
|
||||||
|
if e, a := querySig, r.HTTPRequest.Header.Get("Authorization"); e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
if e, a := origSignedAt, r.LastSignedAt; e == a {
|
||||||
|
t.Errorf("expect %v to be %v, was not", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignWithRequestBody(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
signer := NewSigner(creds)
|
||||||
|
|
||||||
|
expectBody := []byte("abc123")
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
r.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := expectBody, b; !reflect.DeepEqual(e, a) {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}))
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", server.URL, nil)
|
||||||
|
|
||||||
|
_, err = signer.Sign(req, bytes.NewReader(expectBody), "service", "region", time.Now())
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect not no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect not no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignWithRequestBody_Overwrite(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
signer := NewSigner(creds)
|
||||||
|
|
||||||
|
var expectBody []byte
|
||||||
|
|
||||||
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
b, err := ioutil.ReadAll(r.Body)
|
||||||
|
r.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect not no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := len(expectBody), len(b); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}))
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", server.URL, strings.NewReader("invalid body"))
|
||||||
|
|
||||||
|
_, err = signer.Sign(req, nil, "service", "region", time.Now())
|
||||||
|
req.ContentLength = 0
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect not no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expect not no error, got %v", err)
|
||||||
|
}
|
||||||
|
if e, a := http.StatusOK, resp.StatusCode; e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildCanonicalRequest(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a"
|
||||||
|
ctx := &signingCtx{
|
||||||
|
ServiceName: "dynamodb",
|
||||||
|
Region: "us-east-1",
|
||||||
|
Request: req,
|
||||||
|
Body: body,
|
||||||
|
Query: req.URL.Query(),
|
||||||
|
Time: time.Now(),
|
||||||
|
ExpireTime: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.buildCanonicalString()
|
||||||
|
expected := "https://example.org/bucket/key-._~,!@#$%^&*()?Foo=z&Foo=o&Foo=m&Foo=a"
|
||||||
|
if e, a := expected, ctx.Request.URL.String(); e != a {
|
||||||
|
t.Errorf("expect %v, got %v", e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignWithBody_ReplaceRequestBody(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
req, seekerBody := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
req.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||||
|
|
||||||
|
s := NewSigner(creds)
|
||||||
|
origBody := req.Body
|
||||||
|
|
||||||
|
_, err := s.Sign(req, seekerBody, "dynamodb", "us-east-1", time.Now())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Body == origBody {
|
||||||
|
t.Errorf("expeect request body to not be origBody")
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Body == nil {
|
||||||
|
t.Errorf("expect request body to be changed but was nil")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSignWithBody_NoReplaceRequestBody(t *testing.T) {
|
||||||
|
creds := credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
|
||||||
|
req, seekerBody := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
req.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))
|
||||||
|
|
||||||
|
s := NewSigner(creds, func(signer *Signer) {
|
||||||
|
signer.DisableRequestBodyOverwrite = true
|
||||||
|
})
|
||||||
|
|
||||||
|
origBody := req.Body
|
||||||
|
|
||||||
|
_, err := s.Sign(req, seekerBody, "dynamodb", "us-east-1", time.Now())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expect no error, got %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Body != origBody {
|
||||||
|
t.Errorf("expect request body to not be chagned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequestHost(t *testing.T) {
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
req.URL.RawQuery = "Foo=z&Foo=o&Foo=m&Foo=a"
|
||||||
|
req.Host = "myhost"
|
||||||
|
ctx := &signingCtx{
|
||||||
|
ServiceName: "dynamodb",
|
||||||
|
Region: "us-east-1",
|
||||||
|
Request: req,
|
||||||
|
Body: body,
|
||||||
|
Query: req.URL.Query(),
|
||||||
|
Time: time.Now(),
|
||||||
|
ExpireTime: 5 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.buildCanonicalHeaders(ignoredHeaders, ctx.Request.Header)
|
||||||
|
if !strings.Contains(ctx.canonicalHeaders, "host:"+req.Host) {
|
||||||
|
t.Errorf("canonical host header invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkPresignRequest(b *testing.B) {
|
||||||
|
signer := buildSigner()
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
signer.Presign(req, body, "dynamodb", "us-east-1", 300*time.Second, time.Now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSignRequest(b *testing.B) {
|
||||||
|
signer := buildSigner()
|
||||||
|
req, body := buildRequest("dynamodb", "us-east-1", "{}")
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
signer.Sign(req, body, "dynamodb", "us-east-1", time.Now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var stripExcessSpaceCases = []string{
|
||||||
|
`AWS4-HMAC-SHA256 Credential=AKIDFAKEIDFAKEID/20160628/us-west-2/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=1234567890abcdef1234567890abcdef1234567890abcdef`,
|
||||||
|
`123 321 123 321`,
|
||||||
|
` 123 321 123 321 `,
|
||||||
|
` 123 321 123 321 `,
|
||||||
|
"123",
|
||||||
|
"1 2 3",
|
||||||
|
" 1 2 3",
|
||||||
|
"1 2 3",
|
||||||
|
"1 23",
|
||||||
|
"1 2 3",
|
||||||
|
"1 2 ",
|
||||||
|
" 1 2 ",
|
||||||
|
"12 3",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1",
|
||||||
|
"12 3 1abc123",
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkStripExcessSpaces(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
// Make sure to start with a copy of the cases
|
||||||
|
cases := append([]string{}, stripExcessSpaceCases...)
|
||||||
|
stripExcessSpaces(cases)
|
||||||
|
}
|
||||||
|
}
|
92
vendor/github.com/aws/aws-sdk-go/aws/types_test.go
generated
vendored
Normal file
92
vendor/github.com/aws/aws-sdk-go/aws/types_test.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWriteAtBuffer(t *testing.T) {
|
||||||
|
b := &WriteAtBuffer{}
|
||||||
|
|
||||||
|
n, err := b.WriteAt([]byte{1}, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, n; e != a {
|
||||||
|
t.Errorf("expected %d, but recieved %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = b.WriteAt([]byte{1, 1, 1}, 5)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 3, n; e != a {
|
||||||
|
t.Errorf("expected %d, but recieved %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = b.WriteAt([]byte{2}, 1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, n; e != a {
|
||||||
|
t.Errorf("expected %d, but recieved %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err = b.WriteAt([]byte{3}, 2)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected no error, but received %v", err)
|
||||||
|
}
|
||||||
|
if e, a := 1, n; e != a {
|
||||||
|
t.Errorf("expected %d, but received %d", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal([]byte{1, 2, 3, 0, 0, 1, 1, 1}, b.Bytes()) {
|
||||||
|
t.Errorf("expected %v, but received %v", []byte{1, 2, 3, 0, 0, 1, 1, 1}, b.Bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkWriteAtBuffer(b *testing.B) {
|
||||||
|
buf := &WriteAtBuffer{}
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
to := r.Intn(10) * 4096
|
||||||
|
bs := make([]byte, to)
|
||||||
|
buf.WriteAt(bs, r.Int63n(10)*4096)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkWriteAtBufferOrderedWrites(b *testing.B) {
|
||||||
|
// test the performance of a WriteAtBuffer when written in an
|
||||||
|
// ordered fashion. This is similar to the behavior of the
|
||||||
|
// s3.Downloader, since downloads the first chunk of the file, then
|
||||||
|
// the second, and so on.
|
||||||
|
//
|
||||||
|
// This test simulates a 150MB file being written in 30 ordered 5MB chunks.
|
||||||
|
chunk := int64(5e6)
|
||||||
|
max := chunk * 30
|
||||||
|
// we'll write the same 5MB chunk every time
|
||||||
|
tmp := make([]byte, chunk)
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
buf := &WriteAtBuffer{}
|
||||||
|
for i := int64(0); i < max; i += chunk {
|
||||||
|
buf.WriteAt(tmp, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkWriteAtBufferParallel(b *testing.B) {
|
||||||
|
buf := &WriteAtBuffer{}
|
||||||
|
r := rand.New(rand.NewSource(1))
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
|
for pb.Next() {
|
||||||
|
to := r.Intn(10) * 4096
|
||||||
|
bs := make([]byte, to)
|
||||||
|
buf.WriteAt(bs, r.Int63n(10)*4096)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
|
@ -5,4 +5,4 @@ package aws
|
||||||
const SDKName = "aws-sdk-go"
|
const SDKName = "aws-sdk-go"
|
||||||
|
|
||||||
// SDKVersion is the version of this SDK
|
// SDKVersion is the version of this SDK
|
||||||
const SDKVersion = "1.8.30"
|
const SDKVersion = "1.12.26"
|
||||||
|
|
19
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/Godeps/Godeps.json
generated
vendored
Normal file
19
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/Godeps/Godeps.json
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer",
|
||||||
|
"GoVersion": "go1.6",
|
||||||
|
"GodepVersion": "v60",
|
||||||
|
"Deps": [
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/tools/go/ast/astutil",
|
||||||
|
"Rev": "b75b3f5cd5d50fbb1fb88ce784d2e7cca17bba8a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/tools/go/buildutil",
|
||||||
|
"Rev": "b75b3f5cd5d50fbb1fb88ce784d2e7cca17bba8a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "golang.org/x/tools/go/loader",
|
||||||
|
"Rev": "b75b3f5cd5d50fbb1fb88ce784d2e7cca17bba8a"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
200
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/gen/gen.go
generated
vendored
Normal file
200
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/gen/gen.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
// +build go1.5,deprecated
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"go/format"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/private/model/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pkg struct {
|
||||||
|
oldAPI *api.API
|
||||||
|
newAPI *api.API
|
||||||
|
shapes map[string]*shapentry
|
||||||
|
operations map[string]*opentry
|
||||||
|
}
|
||||||
|
|
||||||
|
type shapentry struct {
|
||||||
|
oldShape *api.Shape
|
||||||
|
newShape *api.Shape
|
||||||
|
}
|
||||||
|
|
||||||
|
type opentry struct {
|
||||||
|
oldName string
|
||||||
|
newName string
|
||||||
|
}
|
||||||
|
|
||||||
|
type packageRenames struct {
|
||||||
|
Shapes map[string]string
|
||||||
|
Operations map[string]string
|
||||||
|
Fields map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
var exportMap = map[string]*packageRenames{}
|
||||||
|
|
||||||
|
func generateRenames(w io.Writer) error {
|
||||||
|
tmpl, err := template.New("renames").Parse(t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := bytes.NewBuffer(nil)
|
||||||
|
if err = tmpl.Execute(out, exportMap); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := format.Source(bytes.TrimSpace(out.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(w, bytes.NewReader(b))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = `
|
||||||
|
package rename
|
||||||
|
|
||||||
|
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
||||||
|
|
||||||
|
var renamedPackages = map[string]*packageRenames{
|
||||||
|
{{ range $key, $entry := . }}"{{ $key }}": &packageRenames{
|
||||||
|
operations: map[string]string{
|
||||||
|
{{ range $old, $new := $entry.Operations }}"{{ $old }}": "{{ $new }}",
|
||||||
|
{{ end }}
|
||||||
|
},
|
||||||
|
shapes: map[string]string{
|
||||||
|
{{ range $old, $new := $entry.Shapes }}"{{ $old }}": "{{ $new }}",
|
||||||
|
{{ end }}
|
||||||
|
},
|
||||||
|
fields: map[string]string{
|
||||||
|
{{ range $old, $new := $entry.Fields }}"{{ $old }}": "{{ $new }}",
|
||||||
|
{{ end }}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func (p *pkg) buildRenames() {
|
||||||
|
pkgName := "github.com/aws/aws-sdk-go/service/" + p.oldAPI.PackageName()
|
||||||
|
if exportMap[pkgName] == nil {
|
||||||
|
exportMap[pkgName] = &packageRenames{map[string]string{}, map[string]string{}, map[string]string{}}
|
||||||
|
}
|
||||||
|
ifacename := "github.com/aws/aws-sdk-go/service/" + p.oldAPI.PackageName() + "/" +
|
||||||
|
p.oldAPI.InterfacePackageName()
|
||||||
|
if exportMap[ifacename] == nil {
|
||||||
|
exportMap[ifacename] = &packageRenames{map[string]string{}, map[string]string{}, map[string]string{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range p.operations {
|
||||||
|
if entry.oldName != entry.newName {
|
||||||
|
pkgNames := []string{pkgName, ifacename}
|
||||||
|
for _, p := range pkgNames {
|
||||||
|
exportMap[p].Operations[entry.oldName] = entry.newName
|
||||||
|
exportMap[p].Operations[entry.oldName+"Request"] = entry.newName + "Request"
|
||||||
|
exportMap[p].Operations[entry.oldName+"Pages"] = entry.newName + "Pages"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range p.shapes {
|
||||||
|
if entry.oldShape.Type == "structure" {
|
||||||
|
if entry.oldShape.ShapeName != entry.newShape.ShapeName {
|
||||||
|
exportMap[pkgName].Shapes[entry.oldShape.ShapeName] = entry.newShape.ShapeName
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range entry.oldShape.MemberNames() {
|
||||||
|
for _, m := range entry.newShape.MemberNames() {
|
||||||
|
if n != m && strings.ToLower(n) == strings.ToLower(m) {
|
||||||
|
exportMap[pkgName].Fields[n] = m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func load(file string) *pkg {
|
||||||
|
p := &pkg{&api.API{}, &api.API{}, map[string]*shapentry{}, map[string]*opentry{}}
|
||||||
|
|
||||||
|
p.oldAPI.Attach(file)
|
||||||
|
p.oldAPI.Setup()
|
||||||
|
|
||||||
|
p.newAPI.Attach(file)
|
||||||
|
p.newAPI.Setup()
|
||||||
|
|
||||||
|
for _, name := range p.oldAPI.OperationNames() {
|
||||||
|
p.operations[strings.ToLower(name)] = &opentry{oldName: name}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range p.newAPI.OperationNames() {
|
||||||
|
p.operations[strings.ToLower(name)].newName = name
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, shape := range p.oldAPI.ShapeList() {
|
||||||
|
p.shapes[strings.ToLower(shape.ShapeName)] = &shapentry{oldShape: shape}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, shape := range p.newAPI.ShapeList() {
|
||||||
|
if _, ok := p.shapes[strings.ToLower(shape.ShapeName)]; !ok {
|
||||||
|
panic("missing shape " + shape.ShapeName)
|
||||||
|
}
|
||||||
|
p.shapes[strings.ToLower(shape.ShapeName)].newShape = shape
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
var excludeServices = map[string]struct{}{
|
||||||
|
"simpledb": {},
|
||||||
|
"importexport": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
files, _ := filepath.Glob("../../apis/*/*/api-2.json")
|
||||||
|
|
||||||
|
sort.Strings(files)
|
||||||
|
|
||||||
|
// Remove old API versions from list
|
||||||
|
m := map[string]bool{}
|
||||||
|
for i := range files {
|
||||||
|
idx := len(files) - 1 - i
|
||||||
|
parts := strings.Split(files[idx], string(filepath.Separator))
|
||||||
|
svc := parts[len(parts)-3] // service name is 2nd-to-last component
|
||||||
|
|
||||||
|
if m[svc] {
|
||||||
|
files[idx] = "" // wipe this one out if we already saw the service
|
||||||
|
}
|
||||||
|
m[svc] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range files {
|
||||||
|
file := files[i]
|
||||||
|
if file == "" { // empty file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if g := load(file); g != nil {
|
||||||
|
if _, ok := excludeServices[g.oldAPI.PackageName()]; !ok {
|
||||||
|
g.buildRenames()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outfile, err := os.Create("rename/renames.go")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := generateRenames(outfile); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
116
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/rename/rename.go
generated
vendored
Normal file
116
vendor/github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/rename/rename.go
generated
vendored
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// +build go1.5,deprecated
|
||||||
|
|
||||||
|
package rename
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"go/parser"
|
||||||
|
"go/token"
|
||||||
|
"go/types"
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/loader"
|
||||||
|
)
|
||||||
|
|
||||||
|
var dryRun = flag.Bool("dryrun", false, "Dry run")
|
||||||
|
var verbose = flag.Bool("verbose", false, "Verbose")
|
||||||
|
|
||||||
|
type packageRenames struct {
|
||||||
|
operations map[string]string
|
||||||
|
shapes map[string]string
|
||||||
|
fields map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type renamer struct {
|
||||||
|
*loader.Program
|
||||||
|
files map[*token.File]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParsePathsFromArgs parses arguments from command line and looks at import
|
||||||
|
// paths to rename objects.
|
||||||
|
func ParsePathsFromArgs() {
|
||||||
|
flag.Parse()
|
||||||
|
for _, dir := range flag.Args() {
|
||||||
|
var conf loader.Config
|
||||||
|
conf.ParserMode = parser.ParseComments
|
||||||
|
conf.ImportWithTests(dir)
|
||||||
|
prog, err := conf.Load()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := renamer{prog, map[*token.File]bool{}}
|
||||||
|
r.parse()
|
||||||
|
if !*dryRun {
|
||||||
|
r.write()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renamer) dryInfo() string {
|
||||||
|
if *dryRun {
|
||||||
|
return "[DRY-RUN]"
|
||||||
|
}
|
||||||
|
return "[!]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renamer) printf(msg string, args ...interface{}) {
|
||||||
|
if *verbose {
|
||||||
|
fmt.Printf(msg, args...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renamer) parse() {
|
||||||
|
for _, pkg := range r.InitialPackages() {
|
||||||
|
r.parseUses(pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renamer) write() {
|
||||||
|
for _, pkg := range r.InitialPackages() {
|
||||||
|
for _, f := range pkg.Files {
|
||||||
|
tokenFile := r.Fset.File(f.Pos())
|
||||||
|
if r.files[tokenFile] {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
format.Node(&buf, r.Fset, f)
|
||||||
|
if err := ioutil.WriteFile(tokenFile.Name(), buf.Bytes(), 0644); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *renamer) parseUses(pkg *loader.PackageInfo) {
|
||||||
|
for k, v := range pkg.Uses {
|
||||||
|
if v.Pkg() != nil {
|
||||||
|
pkgPath := v.Pkg().Path()
|
||||||
|
if renames, ok := renamedPackages[pkgPath]; ok {
|
||||||
|
name := k.Name
|
||||||
|
switch t := v.(type) {
|
||||||
|
case *types.Func:
|
||||||
|
if newName, ok := renames.operations[t.Name()]; ok && newName != name {
|
||||||
|
r.printf("%s Rename [OPERATION]: %q -> %q\n", r.dryInfo(), name, newName)
|
||||||
|
r.files[r.Fset.File(k.Pos())] = true
|
||||||
|
k.Name = newName
|
||||||
|
}
|
||||||
|
case *types.TypeName:
|
||||||
|
if newName, ok := renames.shapes[name]; ok && newName != name {
|
||||||
|
r.printf("%s Rename [SHAPE]: %q -> %q\n", r.dryInfo(), t.Name(), newName)
|
||||||
|
r.files[r.Fset.File(k.Pos())] = true
|
||||||
|
k.Name = newName
|
||||||
|
}
|
||||||
|
case *types.Var:
|
||||||
|
if newName, ok := renames.fields[name]; ok && newName != name {
|
||||||
|
r.printf("%s Rename [FIELD]: %q -> %q\n", r.dryInfo(), t.Name(), newName)
|
||||||
|
r.files[r.Fset.File(k.Pos())] = true
|
||||||
|
k.Name = newName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue