plugin/etcdv3: Add etcd v3 plugin (#1702)

* Update dependencies and add etcdv3 client

* Update etcd plugin to support etcd v3 clients

Fixes #341
This commit is contained in:
Nitish Tiwari 2018-06-30 20:49:13 +05:30 committed by Miek Gieben
parent f3afd70021
commit 6fe27d99be
10327 changed files with 4196998 additions and 82 deletions

View 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.

View 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.

86
vendor/github.com/aws/aws-sdk-go/aws/arn/arn.go generated vendored Normal file
View 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
View 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)
}
})
}
}

View 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

View 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
}

View 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)
}
}

View 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

View file

@ -0,0 +1 @@
[profile_nam

View 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

View 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"
}
]
}

View file

@ -0,0 +1,5 @@
This directory tree is generated automatically by godep.
Please do not edit.
See https://github.com/tools/godep for more information.

View 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)
}
}

View 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
}
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,45 @@
// +build go1.5,deprecated
package main
//go:generate go run -tags deprecated gen/gen.go
import (
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/aws/aws-sdk-go/awsmigrate/awsmigrate-renamer/rename"
)
var safeTag = "4e554f77f00d527b452c68a46f2e68595284121b"
func main() {
gopath := os.Getenv("GOPATH")
if gopath == "" {
panic("GOPATH not set!")
}
gopath = strings.Split(gopath, ":")[0]
// change directory to SDK
err := os.Chdir(filepath.Join(gopath, "src", "github.com", "aws", "aws-sdk-go"))
if err != nil {
panic("Cannot find SDK repository")
}
// store orig HEAD
head, err := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD").Output()
if err != nil {
panic("Cannot find SDK repository")
}
origHEAD := strings.Trim(string(head), " \r\n")
// checkout to safe tag and run conversion
exec.Command("git", "checkout", safeTag).Run()
defer func() {
exec.Command("git", "checkout", origHEAD).Run()
}()
rename.ParsePathsFromArgs()
}

212
vendor/github.com/aws/aws-sdk-go/awstesting/assert.go generated vendored Normal file
View file

@ -0,0 +1,212 @@
package awstesting
import (
"encoding/json"
"encoding/xml"
"fmt"
"net/url"
"reflect"
"regexp"
"sort"
"strings"
"testing"
)
// Match is a testing helper to test for testing error by comparing expected
// with a regular expression.
func Match(t *testing.T, regex, expected string) {
if !regexp.MustCompile(regex).Match([]byte(expected)) {
t.Errorf("%q\n\tdoes not match /%s/", expected, regex)
}
}
// AssertURL verifies the expected URL is matches the actual.
func AssertURL(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool {
expectURL, err := url.Parse(expect)
if err != nil {
t.Errorf(errMsg("unable to parse expected URL", err, msgAndArgs))
return false
}
actualURL, err := url.Parse(actual)
if err != nil {
t.Errorf(errMsg("unable to parse actual URL", err, msgAndArgs))
return false
}
equal(t, expectURL.Host, actualURL.Host, msgAndArgs...)
equal(t, expectURL.Scheme, actualURL.Scheme, msgAndArgs...)
equal(t, expectURL.Path, actualURL.Path, msgAndArgs...)
return AssertQuery(t, expectURL.Query().Encode(), actualURL.Query().Encode(), msgAndArgs...)
}
var queryMapKey = regexp.MustCompile("(.*?)\\.[0-9]+\\.key")
// AssertQuery verifies the expect HTTP query string matches the actual.
func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool {
expectQ, err := url.ParseQuery(expect)
if err != nil {
t.Errorf(errMsg("unable to parse expected Query", err, msgAndArgs))
return false
}
actualQ, err := url.ParseQuery(actual)
if err != nil {
t.Errorf(errMsg("unable to parse actual Query", err, msgAndArgs))
return false
}
// Make sure the keys are the same
if !equal(t, queryValueKeys(expectQ), queryValueKeys(actualQ), msgAndArgs...) {
return false
}
keys := map[string][]string{}
for key, v := range expectQ {
if queryMapKey.Match([]byte(key)) {
submatch := queryMapKey.FindStringSubmatch(key)
keys[submatch[1]] = append(keys[submatch[1]], v...)
}
}
for k, v := range keys {
// clear all keys that have prefix
for key := range expectQ {
if strings.HasPrefix(key, k) {
delete(expectQ, key)
}
}
sort.Strings(v)
for i, value := range v {
expectQ[fmt.Sprintf("%s.%d.key", k, i+1)] = []string{value}
}
}
for k, expectQVals := range expectQ {
sort.Strings(expectQVals)
actualQVals := actualQ[k]
sort.Strings(actualQVals)
if !equal(t, expectQVals, actualQVals, msgAndArgs...) {
return false
}
}
return true
}
// AssertJSON verifies that the expect json string matches the actual.
func AssertJSON(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool {
expectVal := map[string]interface{}{}
if err := json.Unmarshal([]byte(expect), &expectVal); err != nil {
t.Errorf(errMsg("unable to parse expected JSON", err, msgAndArgs...))
return false
}
actualVal := map[string]interface{}{}
if err := json.Unmarshal([]byte(actual), &actualVal); err != nil {
t.Errorf(errMsg("unable to parse actual JSON", err, msgAndArgs...))
return false
}
return equal(t, expectVal, actualVal, msgAndArgs...)
}
// AssertXML verifies that the expect xml string matches the actual.
func AssertXML(t *testing.T, expect, actual string, container interface{}, msgAndArgs ...interface{}) bool {
expectVal := container
if err := xml.Unmarshal([]byte(expect), &expectVal); err != nil {
t.Errorf(errMsg("unable to parse expected XML", err, msgAndArgs...))
}
actualVal := container
if err := xml.Unmarshal([]byte(actual), &actualVal); err != nil {
t.Errorf(errMsg("unable to parse actual XML", err, msgAndArgs...))
}
return equal(t, expectVal, actualVal, msgAndArgs...)
}
// DidPanic returns if the function paniced and returns true if the function paniced.
func DidPanic(fn func()) (bool, interface{}) {
var paniced bool
var msg interface{}
func() {
defer func() {
if msg = recover(); msg != nil {
paniced = true
}
}()
fn()
}()
return paniced, msg
}
// objectsAreEqual determines if two objects are considered equal.
//
// This function does no assertion of any kind.
//
// Based on github.com/stretchr/testify/assert.ObjectsAreEqual
// Copied locally to prevent non-test build dependencies on testify
func objectsAreEqual(expected, actual interface{}) bool {
if expected == nil || actual == nil {
return expected == actual
}
return reflect.DeepEqual(expected, actual)
}
// Equal asserts that two objects are equal.
//
// assert.Equal(t, 123, 123, "123 and 123 should be equal")
//
// Returns whether the assertion was successful (true) or not (false).
//
// Based on github.com/stretchr/testify/assert.Equal
// Copied locally to prevent non-test build dependencies on testify
func equal(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) bool {
if !objectsAreEqual(expected, actual) {
t.Errorf("%s\n%s", messageFromMsgAndArgs(msgAndArgs),
SprintExpectActual(expected, actual))
return false
}
return true
}
func errMsg(baseMsg string, err error, msgAndArgs ...interface{}) string {
message := messageFromMsgAndArgs(msgAndArgs)
if message != "" {
message += ", "
}
return fmt.Sprintf("%s%s, %v", message, baseMsg, err)
}
// Based on github.com/stretchr/testify/assert.messageFromMsgAndArgs
// Copied locally to prevent non-test build dependencies on testify
func messageFromMsgAndArgs(msgAndArgs []interface{}) string {
if len(msgAndArgs) == 0 || msgAndArgs == nil {
return ""
}
if len(msgAndArgs) == 1 {
return msgAndArgs[0].(string)
}
if len(msgAndArgs) > 1 {
return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
}
return ""
}
func queryValueKeys(v url.Values) []string {
keys := make([]string, 0, len(v))
for k := range v {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}
// SprintExpectActual returns a string for test failure cases when the actual
// value is not the same as the expected.
func SprintExpectActual(expect, actual interface{}) string {
return fmt.Sprintf("expect: %+v\nactual: %+v\n", expect, actual)
}

View file

@ -0,0 +1,89 @@
package awstesting_test
import (
"encoding/xml"
"testing"
"github.com/aws/aws-sdk-go/awstesting"
)
func TestAssertJSON(t *testing.T) {
cases := []struct {
e, a string
asserts bool
}{
{
e: `{"RecursiveStruct":{"RecursiveMap":{"foo":{"NoRecurse":"foo"},"bar":{"NoRecurse":"bar"}}}}`,
a: `{"RecursiveStruct":{"RecursiveMap":{"bar":{"NoRecurse":"bar"},"foo":{"NoRecurse":"foo"}}}}`,
asserts: true,
},
}
for i, c := range cases {
mockT := &testing.T{}
if awstesting.AssertJSON(mockT, c.e, c.a) != c.asserts {
t.Error("Assert JSON result was not expected.", i)
}
}
}
func TestAssertXML(t *testing.T) {
cases := []struct {
e, a string
asserts bool
container struct {
XMLName xml.Name `xml:"OperationRequest"`
NS string `xml:"xmlns,attr"`
RecursiveStruct struct {
RecursiveMap struct {
Entries []struct {
XMLName xml.Name `xml:"entries"`
Key string `xml:"key"`
Value struct {
XMLName xml.Name `xml:"value"`
NoRecurse string
}
}
}
}
}
}{
{
e: `<OperationRequest xmlns="https://foo/"><RecursiveStruct xmlns="https://foo/"><RecursiveMap xmlns="https://foo/"><entry xmlns="https://foo/"><key xmlns="https://foo/">foo</key><value xmlns="https://foo/"><NoRecurse xmlns="https://foo/">foo</NoRecurse></value></entry><entry xmlns="https://foo/"><key xmlns="https://foo/">bar</key><value xmlns="https://foo/"><NoRecurse xmlns="https://foo/">bar</NoRecurse></value></entry></RecursiveMap></RecursiveStruct></OperationRequest>`,
a: `<OperationRequest xmlns="https://foo/"><RecursiveStruct xmlns="https://foo/"><RecursiveMap xmlns="https://foo/"><entry xmlns="https://foo/"><key xmlns="https://foo/">bar</key><value xmlns="https://foo/"><NoRecurse xmlns="https://foo/">bar</NoRecurse></value></entry><entry xmlns="https://foo/"><key xmlns="https://foo/">foo</key><value xmlns="https://foo/"><NoRecurse xmlns="https://foo/">foo</NoRecurse></value></entry></RecursiveMap></RecursiveStruct></OperationRequest>`,
asserts: true,
},
}
for i, c := range cases {
// mockT := &testing.T{}
if awstesting.AssertXML(t, c.e, c.a, c.container) != c.asserts {
t.Error("Assert XML result was not expected.", i)
}
}
}
func TestAssertQuery(t *testing.T) {
cases := []struct {
e, a string
asserts bool
}{
{
e: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`,
a: `Action=OperationName&Version=2014-01-01&Foo=val2&Bar=val3`,
asserts: false,
},
{
e: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`,
a: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`,
asserts: true,
},
}
for i, c := range cases {
mockT := &testing.T{}
if awstesting.AssertQuery(mockT, c.e, c.a) != c.asserts {
t.Error("Assert Query result was not expected.", i)
}
}
}

24
vendor/github.com/aws/aws-sdk-go/awstesting/client.go generated vendored Normal file
View file

@ -0,0 +1,24 @@
package awstesting
import (
"github.com/aws/aws-sdk-go/aws"
"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"
)
// NewClient creates and initializes a generic service client for testing.
func NewClient(cfgs ...*aws.Config) *client.Client {
info := metadata.ClientInfo{
Endpoint: "http://endpoint",
SigningName: "",
}
def := defaults.Get()
def.Config.MergeIn(cfgs...)
if v := aws.StringValue(def.Config.Endpoint); len(v) > 0 {
info.Endpoint = v
}
return client.New(*def.Config, info, def.Handlers)
}

View file

@ -0,0 +1,94 @@
// +build integration
package main
import (
"fmt"
"os"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
// Searches the buckets of an account that match the prefix, and deletes
// those buckets, and all objects within. Before deleting will prompt user
// to confirm bucket should be deleted. Positive confirmation is required.
//
// Usage:
// go run deleteBuckets.go <bucketPrefix>
func main() {
sess := session.Must(session.NewSession())
svc := s3.New(sess)
buckets, err := svc.ListBuckets(&s3.ListBucketsInput{})
if err != nil {
panic(fmt.Sprintf("failed to list buckets, %v", err))
}
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "bucket prefix required")
os.Exit(1)
}
bucketPrefix := os.Args[1]
var failed bool
for _, b := range buckets.Buckets {
bucket := aws.StringValue(b.Name)
if !strings.HasPrefix(bucket, bucketPrefix) {
continue
}
fmt.Printf("Delete bucket %q? [y/N]: ", bucket)
var v string
if _, err := fmt.Scanln(&v); err != nil || !(v == "Y" || v == "y") {
fmt.Println("\tSkipping")
continue
}
fmt.Println("\tDeleting")
if err := deleteBucket(svc, bucket); err != nil {
fmt.Fprintf(os.Stderr, "failed to delete bucket %q, %v", bucket, err)
failed = true
}
}
if failed {
os.Exit(1)
}
}
func deleteBucket(svc *s3.S3, bucket string) error {
bucketName := &bucket
objs, err := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to list bucket %q objects, %v", bucketName, err)
}
for _, o := range objs.Contents {
svc.DeleteObject(&s3.DeleteObjectInput{Bucket: bucketName, Key: o.Key})
}
uploads, err := svc.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to list bucket %q multipart objects, %v", bucketName, err)
}
for _, u := range uploads.Uploads {
svc.AbortMultipartUpload(&s3.AbortMultipartUploadInput{
Bucket: bucketName,
Key: u.Key,
UploadId: u.UploadId,
})
}
_, err = svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to delete bucket %q, %v", bucketName, err)
}
return nil
}

View file

@ -0,0 +1,199 @@
package awstesting
import (
"io/ioutil"
"net"
"net/http"
"os"
"strings"
"time"
)
func availableLocalAddr(ip string) (string, error) {
l, err := net.Listen("tcp", ip+":0")
if err != nil {
return "", err
}
defer l.Close()
return l.Addr().String(), nil
}
// CreateTLSServer will create the TLS server on an open port using the
// certificate and key. The address will be returned that the server is running on.
func CreateTLSServer(cert, key string, mux *http.ServeMux) (string, error) {
addr, err := availableLocalAddr("127.0.0.1")
if err != nil {
return "", err
}
if mux == nil {
mux = http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {})
}
go func() {
if err := http.ListenAndServeTLS(addr, cert, key, mux); err != nil {
panic(err)
}
}()
for i := 0; i < 60; i++ {
if _, err := http.Get("https://" + addr); err != nil && !strings.Contains(err.Error(), "connection refused") {
break
}
time.Sleep(1 * time.Second)
}
return "https://" + addr, nil
}
// CreateTLSBundleFiles returns the temporary filenames for the certificate
// key, and CA PEM content. These files should be deleted when no longer
// needed. CleanupTLSBundleFiles can be used for this cleanup.
func CreateTLSBundleFiles() (cert, key, ca string, err error) {
cert, err = createTmpFile(TLSBundleCert)
if err != nil {
return "", "", "", err
}
key, err = createTmpFile(TLSBundleKey)
if err != nil {
return "", "", "", err
}
ca, err = createTmpFile(TLSBundleCA)
if err != nil {
return "", "", "", err
}
return cert, key, ca, nil
}
// CleanupTLSBundleFiles takes variadic list of files to be deleted.
func CleanupTLSBundleFiles(files ...string) error {
for _, file := range files {
if err := os.Remove(file); err != nil {
return err
}
}
return nil
}
func createTmpFile(b []byte) (string, error) {
bundleFile, err := ioutil.TempFile(os.TempDir(), "aws-sdk-go-session-test")
if err != nil {
return "", err
}
_, err = bundleFile.Write(b)
if err != nil {
return "", err
}
defer bundleFile.Close()
return bundleFile.Name(), nil
}
/* Cert generation steps
# Create the CA key
openssl genrsa -des3 -out ca.key 1024
# Create the CA Cert
openssl req -new -sha256 -x509 -days 3650 \
-subj "/C=GO/ST=Gopher/O=Testing ROOT CA" \
-key ca.key -out ca.crt
# Create config
cat > csr_details.txt <<-EOF
[req]
default_bits = 1024
prompt = no
default_md = sha256
req_extensions = SAN
distinguished_name = dn
[ dn ]
C=GO
ST=Gopher
O=Testing Certificate
OU=Testing IP
[SAN]
subjectAltName = IP:127.0.0.1
EOF
# Create certificate signing request
openssl req -new -sha256 -nodes -newkey rsa:1024 \
-config <( cat csr_details.txt ) \
-keyout ia.key -out ia.csr
# Create a signed certificate
openssl x509 -req -days 3650 \
-CAcreateserial \
-extfile <( cat csr_details.txt ) \
-extensions SAN \
-CA ca.crt -CAkey ca.key -in ia.csr -out ia.crt
# Verify
openssl req -noout -text -in ia.csr
openssl x509 -noout -text -in ia.crt
*/
var (
// TLSBundleCA ca.crt
TLSBundleCA = []byte(`-----BEGIN CERTIFICATE-----
MIICiTCCAfKgAwIBAgIJAJ5X1olt05XjMA0GCSqGSIb3DQEBCwUAMDgxCzAJBgNV
BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD
QTAeFw0xNzAzMDkwMDAyMDZaFw0yNzAzMDcwMDAyMDZaMDgxCzAJBgNVBAYTAkdP
MQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBDQTCBnzAN
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw/8DN+t9XQR60jx42rsQ2WE2Dx85rb3n
GQxnKZZLNddsT8rDyxJNP18aFalbRbFlyln5fxWxZIblu9Xkm/HRhOpbSimSqo1y
uDx21NVZ1YsOvXpHby71jx3gPrrhSc/t/zikhi++6D/C6m1CiIGuiJ0GBiJxtrub
UBMXT0QtI2ECAwEAAaOBmjCBlzAdBgNVHQ4EFgQU8XG3X/YHBA6T04kdEkq6+4GV
YykwaAYDVR0jBGEwX4AU8XG3X/YHBA6T04kdEkq6+4GVYymhPKQ6MDgxCzAJBgNV
BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD
QYIJAJ5X1olt05XjMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAeILv
z49+uxmPcfOZzonuOloRcpdvyjiXblYxbzz6ch8GsE7Q886FTZbvwbgLhzdwSVgG
G8WHkodDUsymVepdqAamS3f8PdCUk8xIk9mop8LgaB9Ns0/TssxDvMr3sOD2Grb3
xyWymTWMcj6uCiEBKtnUp4rPiefcvCRYZ17/hLE=
-----END CERTIFICATE-----
`)
// TLSBundleCert ai.crt
TLSBundleCert = []byte(`-----BEGIN CERTIFICATE-----
MIICGjCCAYOgAwIBAgIJAIIu+NOoxxM0MA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNV
BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD
QTAeFw0xNzAzMDkwMDAzMTRaFw0yNzAzMDcwMDAzMTRaMFExCzAJBgNVBAYTAkdP
MQ8wDQYDVQQIDAZHb3BoZXIxHDAaBgNVBAoME1Rlc3RpbmcgQ2VydGlmaWNhdGUx
EzARBgNVBAsMClRlc3RpbmcgSVAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
AN1hWHeioo/nASvbrjwCQzXCiWiEzGkw353NxsAB54/NqDL3LXNATtiSJu8kJBrm
Ah12IFLtWLGXjGjjYlHbQWnOR6awveeXnQZukJyRWh7m/Qlt9Ho0CgZE1U+832ac
5GWVldNxW1Lz4I+W9/ehzqe8I80RS6eLEKfUFXGiW+9RAgMBAAGjEzARMA8GA1Ud
EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEFBQADgYEAdF4WQHfVdPCbgv9sxgJjcR1H
Hgw9rZ47gO1IiIhzglnLXQ6QuemRiHeYFg4kjcYBk1DJguxzDTGnUwhUXOibAB+S
zssmrkdYYvn9aUhjc3XK3tjAoDpsPpeBeTBamuUKDHoH/dNRXxerZ8vu6uPR3Pgs
5v/KCV6IAEcvNyOXMPo=
-----END CERTIFICATE-----
`)
// TLSBundleKey ai.key
TLSBundleKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDdYVh3oqKP5wEr2648AkM1wolohMxpMN+dzcbAAeePzagy9y1z
QE7YkibvJCQa5gIddiBS7Vixl4xo42JR20FpzkemsL3nl50GbpCckVoe5v0JbfR6
NAoGRNVPvN9mnORllZXTcVtS8+CPlvf3oc6nvCPNEUunixCn1BVxolvvUQIDAQAB
AoGBAMISrcirddGrlLZLLrKC1ULS2T0cdkqdQtwHYn4+7S5+/z42vMx1iumHLsSk
rVY7X41OWkX4trFxhvEIrc/O48bo2zw78P7flTxHy14uxXnllU8cLThE29SlUU7j
AVBNxJZMsXMlS/DowwD4CjFe+x4Pu9wZcReF2Z9ntzMpySABAkEA+iWoJCPE2JpS
y78q3HYYgpNY3gF3JqQ0SI/zTNkb3YyEIUffEYq0Y9pK13HjKtdsSuX4osTIhQkS
+UgRp6tCAQJBAOKPYTfQ2FX8ijgUpHZRuEAVaxASAS0UATiLgzXxLvOh/VC2at5x
wjOX6sD65pPz/0D8Qj52Cq6Q1TQ+377SDVECQAIy0od+yPweXxvrUjUd1JlRMjbB
TIrKZqs8mKbUQapw0bh5KTy+O1elU4MRPS3jNtBxtP25PQnuSnxmZcFTgAECQFzg
DiiFcsn9FuRagfkHExMiNJuH5feGxeFaP9WzI144v9GAllrOI6Bm3JNzx2ZLlg4b
20Qju8lIEj6yr6JYFaECQHM1VSojGRKpOl9Ox/R4yYSA9RV5Gyn00/aJNxVYyPD5
i3acL2joQm2kLD/LO8paJ4+iQdRXCOMMIpjxSNjGQjQ=
-----END RSA PRIVATE KEY-----
`)
)

View file

@ -0,0 +1,98 @@
// +build integration
// Package s3 runs integration tests for S3
package s3
import (
"bytes"
"io/ioutil"
"net/http"
"reflect"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func TestWriteToObject(t *testing.T) {
_, err := svc.PutObject(&s3.PutObjectInput{
Bucket: bucketName,
Key: aws.String("key name"),
Body: bytes.NewReader([]byte("hello world")),
})
if err != nil {
t.Errorf("expect no error, got %v", err)
}
resp, err := svc.GetObject(&s3.GetObjectInput{
Bucket: bucketName,
Key: aws.String("key name"),
})
if err != nil {
t.Errorf("expect no error, got %v", err)
}
b, _ := ioutil.ReadAll(resp.Body)
if e, a := []byte("hello world"), b; !reflect.DeepEqual(e, a) {
t.Errorf("expect %v, got %v", e, a)
}
}
func TestPresignedGetPut(t *testing.T) {
putreq, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: bucketName,
Key: aws.String("presigned-key"),
})
var err error
// Presign a PUT request
var puturl string
puturl, err = putreq.Presign(300 * time.Second)
if err != nil {
t.Errorf("expect no error, got %v", err)
}
// PUT to the presigned URL with a body
var puthttpreq *http.Request
buf := bytes.NewReader([]byte("hello world"))
puthttpreq, err = http.NewRequest("PUT", puturl, buf)
if err != nil {
t.Errorf("expect no error, got %v", err)
}
var putresp *http.Response
putresp, err = http.DefaultClient.Do(puthttpreq)
if err != nil {
t.Errorf("expect put with presign url no error, got %v", err)
}
if e, a := 200, putresp.StatusCode; e != a {
t.Errorf("expect %v, got %v", e, a)
}
// Presign a GET on the same URL
getreq, _ := svc.GetObjectRequest(&s3.GetObjectInput{
Bucket: bucketName,
Key: aws.String("presigned-key"),
})
var geturl string
geturl, err = getreq.Presign(300 * time.Second)
if err != nil {
t.Errorf("expect no error, got %v", err)
}
// Get the body
var getresp *http.Response
getresp, err = http.Get(geturl)
if err != nil {
t.Errorf("expect no error, got %v", err)
}
var b []byte
defer getresp.Body.Close()
b, err = ioutil.ReadAll(getresp.Body)
if e, a := "hello world", string(b); e != a {
t.Errorf("expect %v, got %v", e, a)
}
}

View file

@ -0,0 +1,102 @@
// +build integration
package s3
import (
"bytes"
"crypto/md5"
"encoding/base64"
"fmt"
"io"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/s3"
)
func base64Sum(content []byte) string {
sum := md5.Sum(content)
return base64.StdEncoding.EncodeToString(sum[:])
}
func SkipTestContentMD5Validate(t *testing.T) {
body := []byte("really cool body content")
cases := []struct {
Name string
Body []byte
Sum64 string
RangeGet []int64
}{
{
Body: body,
Sum64: base64Sum(body),
Name: "contentMD5validation.pop",
},
{
Body: []byte{},
Sum64: base64Sum([]byte{}),
Name: "contentMD5validation.empty",
},
{
Body: body,
Sum64: base64Sum(body),
RangeGet: []int64{0, 9},
Name: "contentMD5validation.range",
},
}
for i, c := range cases {
keyName := aws.String(c.Name)
req, _ := svc.PutObjectRequest(&s3.PutObjectInput{
Bucket: bucketName,
Key: keyName,
Body: bytes.NewReader(c.Body),
})
req.Build()
if e, a := c.Sum64, req.HTTPRequest.Header.Get("Content-Md5"); e != a {
t.Errorf("%d, expect %v sum, got %v", i, e, a)
}
if err := req.Send(); err != nil {
t.Fatalf("%d, expect no error, got %v", i, err)
}
getObjIn := &s3.GetObjectInput{
Bucket: bucketName,
Key: keyName,
}
expectBody := c.Body
if c.RangeGet != nil {
getObjIn.Range = aws.String(fmt.Sprintf("bytes=%d-%d", c.RangeGet[0], c.RangeGet[1]-1))
expectBody = c.Body[c.RangeGet[0]:c.RangeGet[1]]
}
getReq, getOut := svc.GetObjectRequest(getObjIn)
getReq.Build()
if e, a := "append-md5", getReq.HTTPRequest.Header.Get("X-Amz-Te"); e != a {
t.Errorf("%d, expect %v encoding, got %v", i, e, a)
}
if err := getReq.Send(); err != nil {
t.Fatalf("%d, expect no error, got %v", i, err)
}
defer getOut.Body.Close()
if e, a := "append-md5", getReq.HTTPResponse.Header.Get("X-Amz-Transfer-Encoding"); e != a {
t.Fatalf("%d, expect response tx encoding header %v, got %v", i, e, a)
}
var readBody bytes.Buffer
_, err := io.Copy(&readBody, getOut.Body)
if err != nil {
t.Fatalf("%d, expect no error, got %v", i, err)
}
if e, a := expectBody, readBody.Bytes(); !bytes.Equal(e, a) {
t.Errorf("%d, expect %v body, got %v", i, e, a)
}
}
}

View file

@ -0,0 +1,29 @@
// +build integration
//Package s3crypto provides gucumber integration tests support.
package s3crypto
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3crypto"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@s3crypto", func() {
sess := session.New((&aws.Config{
Region: aws.String("us-west-2"),
}))
encryptionClient := s3crypto.NewEncryptionClient(sess, nil, func(c *s3crypto.EncryptionClient) {
})
gucumber.World["encryptionClient"] = encryptionClient
decryptionClient := s3crypto.NewDecryptionClient(sess)
gucumber.World["decryptionClient"] = decryptionClient
gucumber.World["client"] = s3.New(sess)
})
}

View file

@ -0,0 +1,33 @@
# language: en
@s3crypto @client
Feature: S3 Integration Crypto Tests
Scenario: Uploading Go's SDK fixtures
When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests"
Then I encrypt each fixture with "kms" "AWS_SDK_TEST_ALIAS" "us-west-2" and "aes_gcm"
And upload "Go" data with folder "version_2"
Scenario: Uploading Go's SDK fixtures
When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests"
Then I encrypt each fixture with "kms" "AWS_SDK_TEST_ALIAS" "us-west-2" and "aes_cbc"
And upload "Go" data with folder "version_2"
Scenario: Get all plaintext fixtures for symmetric masterkey aes gcm
When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests"
Then I decrypt each fixture against "Go" "version_2"
And I compare the decrypted ciphertext to the plaintext
Scenario: Get all plaintext fixtures for symmetric masterkey aes cbc
When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests"
Then I decrypt each fixture against "Go" "version_2"
And I compare the decrypted ciphertext to the plaintext
Scenario: Get all plaintext fixtures for symmetric masterkey aes gcm
When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests"
Then I decrypt each fixture against "Java" "version_2"
And I compare the decrypted ciphertext to the plaintext
Scenario: Get all plaintext fixtures for symmetric masterkey aes cbc
When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests"
Then I decrypt each fixture against "Java" "version_2"
And I compare the decrypted ciphertext to the plaintext

View file

@ -0,0 +1,211 @@
// +build integration
// Package s3crypto contains shared step definitions that are used across integration tests
package s3crypto
import (
"bytes"
"encoding/base64"
"errors"
"io/ioutil"
"strings"
"github.com/gucumber/gucumber"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kms"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3crypto"
)
func init() {
gucumber.When(`^I get all fixtures for "(.+?)" from "(.+?)"$`,
func(cekAlg, bucket string) {
prefix := "plaintext_test_case_"
baseFolder := "crypto_tests/" + cekAlg
s3Client := gucumber.World["client"].(*s3.S3)
out, err := s3Client.ListObjects(&s3.ListObjectsInput{
Bucket: aws.String(bucket),
Prefix: aws.String(baseFolder + "/" + prefix),
})
if err != nil {
gucumber.T.Errorf("expect no error, got %v", err)
}
plaintexts := make(map[string][]byte)
for _, obj := range out.Contents {
plaintextKey := obj.Key
ptObj, err := s3Client.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: plaintextKey,
})
if err != nil {
gucumber.T.Errorf("expect no error, got %v", err)
}
caseKey := strings.TrimPrefix(*plaintextKey, baseFolder+"/"+prefix)
plaintext, err := ioutil.ReadAll(ptObj.Body)
if err != nil {
gucumber.T.Errorf("expect no error, got %v", err)
}
plaintexts[caseKey] = plaintext
}
gucumber.World["baseFolder"] = baseFolder
gucumber.World["bucket"] = bucket
gucumber.World["plaintexts"] = plaintexts
})
gucumber.Then(`^I decrypt each fixture against "(.+?)" "(.+?)"$`, func(lang, version string) {
plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
baseFolder := gucumber.World["baseFolder"].(string)
bucket := gucumber.World["bucket"].(string)
prefix := "ciphertext_test_case_"
s3Client := gucumber.World["client"].(*s3.S3)
s3CryptoClient := gucumber.World["decryptionClient"].(*s3crypto.DecryptionClient)
language := "language_" + lang
ciphertexts := make(map[string][]byte)
for caseKey := range plaintexts {
cipherKey := baseFolder + "/" + version + "/" + language + "/" + prefix + caseKey
// To get metadata for encryption key
ctObj, err := s3Client.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: &cipherKey,
})
if err != nil {
continue
}
// We don't support wrap, so skip it
if ctObj.Metadata["X-Amz-Wrap-Alg"] == nil || *ctObj.Metadata["X-Amz-Wrap-Alg"] != "kms" {
continue
}
ctObj, err = s3CryptoClient.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: &cipherKey,
},
)
if err != nil {
gucumber.T.Errorf("expect no error, got %v", err)
}
ciphertext, err := ioutil.ReadAll(ctObj.Body)
if err != nil {
gucumber.T.Errorf("expect no error, got %v", err)
}
ciphertexts[caseKey] = ciphertext
}
gucumber.World["decrypted"] = ciphertexts
})
gucumber.And(`^I compare the decrypted ciphertext to the plaintext$`, func() {
plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
ciphertexts := gucumber.World["decrypted"].(map[string][]byte)
for caseKey, ciphertext := range ciphertexts {
if e, a := len(plaintexts[caseKey]), len(ciphertext); e != a {
gucumber.T.Errorf("expect %v, got %v", e, a)
}
if e, a := plaintexts[caseKey], ciphertext; !bytes.Equal(e, a) {
gucumber.T.Errorf("expect %v, got %v", e, a)
}
}
})
gucumber.Then(`^I encrypt each fixture with "(.+?)" "(.+?)" "(.+?)" and "(.+?)"$`, func(kek, v1, v2, cek string) {
var handler s3crypto.CipherDataGenerator
var builder s3crypto.ContentCipherBuilder
switch kek {
case "kms":
arn, err := getAliasInformation(v1, v2)
if err != nil {
gucumber.T.Errorf("expect nil, got %v", nil)
}
b64Arn := base64.StdEncoding.EncodeToString([]byte(arn))
if err != nil {
gucumber.T.Errorf("expect nil, got %v", nil)
}
gucumber.World["Masterkey"] = b64Arn
handler = s3crypto.NewKMSKeyGenerator(kms.New(session.New(&aws.Config{
Region: &v2,
})), arn)
if err != nil {
gucumber.T.Errorf("expect nil, got %v", nil)
}
default:
gucumber.T.Skip()
}
switch cek {
case "aes_gcm":
builder = s3crypto.AESGCMContentCipherBuilder(handler)
case "aes_cbc":
builder = s3crypto.AESCBCContentCipherBuilder(handler, s3crypto.AESCBCPadder)
default:
gucumber.T.Skip()
}
sess := session.New(&aws.Config{
Region: aws.String("us-west-2"),
})
c := s3crypto.NewEncryptionClient(sess, builder, func(c *s3crypto.EncryptionClient) {
})
gucumber.World["encryptionClient"] = c
gucumber.World["cek"] = cek
})
gucumber.And(`^upload "(.+?)" data with folder "(.+?)"$`, func(language, folder string) {
c := gucumber.World["encryptionClient"].(*s3crypto.EncryptionClient)
cek := gucumber.World["cek"].(string)
bucket := gucumber.World["bucket"].(string)
plaintexts := gucumber.World["plaintexts"].(map[string][]byte)
key := gucumber.World["Masterkey"].(string)
for caseKey, plaintext := range plaintexts {
input := &s3.PutObjectInput{
Bucket: &bucket,
Key: aws.String("crypto_tests/" + cek + "/" + folder + "/language_" + language + "/ciphertext_test_case_" + caseKey),
Body: bytes.NewReader(plaintext),
Metadata: map[string]*string{
"Masterkey": &key,
},
}
_, err := c.PutObject(input)
if err != nil {
gucumber.T.Errorf("expect nil, got %v", nil)
}
}
})
}
func getAliasInformation(alias, region string) (string, error) {
arn := ""
svc := kms.New(session.New(&aws.Config{
Region: &region,
}))
truncated := true
var marker *string
for truncated {
out, err := svc.ListAliases(&kms.ListAliasesInput{
Marker: marker,
})
if err != nil {
return arn, err
}
for _, aliasEntry := range out.Aliases {
if *aliasEntry.AliasName == "alias/"+alias {
return *aliasEntry.AliasArn, nil
}
}
truncated = *out.Truncated
marker = out.NextMarker
}
return "", errors.New("The alias " + alias + " does not exist in your account. Please add the proper alias to a key")
}

View file

@ -0,0 +1,27 @@
// +build integration
package s3manager
import (
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
func TestGetBucketRegion(t *testing.T) {
expectRegion := aws.StringValue(integration.Session.Config.Region)
ctx := aws.BackgroundContext()
region, err := s3manager.GetBucketRegion(ctx, integration.Session,
aws.StringValue(bucketName), expectRegion)
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
if e, a := expectRegion, region; e != a {
t.Errorf("expect %s bucket region, got %s", e, a)
}
}

View file

@ -0,0 +1,209 @@
// +build integration
// Package s3manager provides integration tests for the service/s3/s3manager package
package s3manager
import (
"bytes"
"crypto/md5"
"fmt"
"io"
"os"
"regexp"
"strings"
"testing"
"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/awstesting/integration"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
)
var integBuf12MB = make([]byte, 1024*1024*12)
var integMD512MB = fmt.Sprintf("%x", md5.Sum(integBuf12MB))
var bucketName *string
func TestMain(m *testing.M) {
if err := setup(); err != nil {
panic(fmt.Sprintf("failed to setup integration test, %v", err))
}
var result int
defer func() {
if err := teardown(); err != nil {
fmt.Fprintf(os.Stderr, "teardown failed, %v", err)
}
if r := recover(); r != nil {
fmt.Println("S3Manager integration test hit a panic,", r)
result = 1
}
os.Exit(result)
}()
result = m.Run()
}
func setup() error {
svc := s3.New(integration.Session)
// Create a bucket for testing
bucketName = aws.String(
fmt.Sprintf("aws-sdk-go-integration-%s", integration.UniqueID()))
_, err := svc.CreateBucket(&s3.CreateBucketInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to create bucket %q, %v", *bucketName, err)
}
err = svc.WaitUntilBucketExists(&s3.HeadBucketInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to wait for bucket %q to exist, %v", bucketName, err)
}
return nil
}
// Delete the bucket
func teardown() error {
svc := s3.New(integration.Session)
objs, err := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to list bucket %q objects, %v", bucketName, err)
}
for _, o := range objs.Contents {
svc.DeleteObject(&s3.DeleteObjectInput{Bucket: bucketName, Key: o.Key})
}
uploads, err := svc.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to list bucket %q multipart objects, %v", bucketName, err)
}
for _, u := range uploads.Uploads {
svc.AbortMultipartUpload(&s3.AbortMultipartUploadInput{
Bucket: bucketName,
Key: u.Key,
UploadId: u.UploadId,
})
}
_, err = svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName})
if err != nil {
return fmt.Errorf("failed to delete bucket %q, %v", bucketName, err)
}
return nil
}
type dlwriter struct {
buf []byte
}
func newDLWriter(size int) *dlwriter {
return &dlwriter{buf: make([]byte, size)}
}
func (d dlwriter) WriteAt(p []byte, pos int64) (n int, err error) {
if pos > int64(len(d.buf)) {
return 0, io.EOF
}
written := 0
for i, b := range p {
if i >= len(d.buf) {
break
}
d.buf[pos+int64(i)] = b
written++
}
return written, nil
}
func validate(t *testing.T, key string, md5value string) {
mgr := s3manager.NewDownloader(integration.Session)
params := &s3.GetObjectInput{Bucket: bucketName, Key: &key}
w := newDLWriter(1024 * 1024 * 20)
n, err := mgr.Download(w, params)
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
if e, a := md5value, fmt.Sprintf("%x", md5.Sum(w.buf[0:n])); e != a {
t.Errorf("expect %s md5 value, got %s", e, a)
}
}
func TestUploadConcurrently(t *testing.T) {
key := "12mb-1"
mgr := s3manager.NewUploader(integration.Session)
out, err := mgr.Upload(&s3manager.UploadInput{
Bucket: bucketName,
Key: &key,
Body: bytes.NewReader(integBuf12MB),
})
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
if len(out.UploadID) == 0 {
t.Errorf("expect upload ID but was empty")
}
re := regexp.MustCompile(`^https?://.+/` + key + `$`)
if e, a := re.String(), out.Location; !re.MatchString(a) {
t.Errorf("expect %s to match URL regexp %q, did not", e, a)
}
validate(t, key, integMD512MB)
}
func TestUploadFailCleanup(t *testing.T) {
svc := s3.New(integration.Session)
// Break checksum on 2nd part so it fails
part := 0
svc.Handlers.Build.PushBack(func(r *request.Request) {
if r.Operation.Name == "UploadPart" {
if part == 1 {
r.HTTPRequest.Header.Set("X-Amz-Content-Sha256", "000")
}
part++
}
})
key := "12mb-leave"
mgr := s3manager.NewUploaderWithClient(svc, func(u *s3manager.Uploader) {
u.LeavePartsOnError = false
})
_, err := mgr.Upload(&s3manager.UploadInput{
Bucket: bucketName,
Key: &key,
Body: bytes.NewReader(integBuf12MB),
})
if err == nil {
t.Fatalf("expect error, but did not get one")
}
aerr := err.(awserr.Error)
if e, a := "MissingRegion", aerr.Code(); strings.Contains(a, e) {
t.Errorf("expect %q to not be in error code %q", e, a)
}
uploadID := ""
merr := err.(s3manager.MultiUploadFailure)
if uploadID = merr.UploadID(); len(uploadID) == 0 {
t.Errorf("expect upload ID to not be empty, but was")
}
_, err = svc.ListParts(&s3.ListPartsInput{
Bucket: bucketName, Key: &key, UploadId: &uploadID,
})
if err == nil {
t.Errorf("expect error for list parts, but got none")
}
}

View file

@ -0,0 +1 @@
package s3manager

View file

@ -0,0 +1,67 @@
// +build integration
package s3
import (
"fmt"
"os"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration"
"github.com/aws/aws-sdk-go/service/s3"
)
const integBucketPrefix = "aws-sdk-go-integration"
var bucketName *string
var svc *s3.S3
func TestMain(m *testing.M) {
setup()
defer teardown() // only called if we panic
result := m.Run()
teardown()
os.Exit(result)
}
// Create a bucket for testing
func setup() {
svc = s3.New(integration.Session)
bucketName = aws.String(
fmt.Sprintf("%s-%s",
integBucketPrefix, integration.UniqueID()))
_, err := svc.CreateBucket(&s3.CreateBucketInput{Bucket: bucketName})
if err != nil {
panic(fmt.Sprintf("failed to create bucket %s, %v", *bucketName, err))
}
err = svc.WaitUntilBucketExists(&s3.HeadBucketInput{Bucket: bucketName})
if err != nil {
panic(fmt.Sprintf("failed waiting for bucket %s to be created", *bucketName))
}
}
// Delete the bucket
func teardown() {
resp, err := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName})
if err != nil {
panic(fmt.Sprintf("failed to list s3 bucket %s objects, %v", *bucketName, err))
}
errs := []error{}
for _, o := range resp.Contents {
_, err = svc.DeleteObject(&s3.DeleteObjectInput{Bucket: bucketName, Key: o.Key})
if err != nil {
errs = append(errs, err)
}
}
if len(errs) != 0 {
panic(fmt.Sprintf("failed to delete objects, %s", errs))
}
svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName})
}

View file

@ -0,0 +1 @@
package s3

View file

@ -0,0 +1,44 @@
// +build integration
// Package integration performs initialization and validation for integration
// tests.
package integration
import (
"crypto/rand"
"fmt"
"io"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
)
// Session is a shared session for all integration tests to use.
var Session = session.Must(session.NewSession())
func init() {
logLevel := Session.Config.LogLevel
if os.Getenv("DEBUG") != "" {
logLevel = aws.LogLevel(aws.LogDebug)
}
if os.Getenv("DEBUG_SIGNING") != "" {
logLevel = aws.LogLevel(aws.LogDebugWithSigning)
}
if os.Getenv("DEBUG_BODY") != "" {
logLevel = aws.LogLevel(aws.LogDebugWithSigning | aws.LogDebugWithHTTPBody)
}
Session.Config.LogLevel = logLevel
if aws.StringValue(Session.Config.Region) == "" {
panic("AWS_REGION must be configured to run integration tests")
}
}
// UniqueID returns a unique UUID-like identifier for use in generating
// resources for integration tests.
func UniqueID() string {
uuid := make([]byte, 16)
io.ReadFull(rand.Reader, uuid)
return fmt.Sprintf("%x", uuid)
}

View file

@ -0,0 +1,14 @@
#language en
@acm @client
Feature: AWS Certificate Manager
Scenario: Making a request
When I call the "ListCertificates" API
Then the request should be successful
Scenario: Handling errors
When I attempt to call the "GetCertificate" API with:
| CertificateArn | arn:aws:acm:region:123456789012:certificate/12345678-1234-1234-1234-123456789012 |
Then I expect the response error code to be "ResourceNotFoundException"
And I expect the response error message not be empty

View file

@ -0,0 +1,16 @@
// +build integration
//Package acm provides gucumber integration tests support.
package acm
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/acm"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@acm", func() {
gucumber.World["client"] = acm.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@apigateway @client
Feature: Amazon API Gateway
Scenario: Making a request
When I call the "GetAccountRequest" API
Then the request should be successful
Scenario: Handing errors
When I attempt to call the "GetRestApi" API with:
| RestApiId | api123 |
Then I expect the response error code to be "NotFoundException"
And I expect the response error message to include:
"""
Invalid REST API identifier specified
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package apigateway provides gucumber integration tests support.
package apigateway
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@apigateway", func() {
gucumber.World["client"] = apigateway.New(smoke.Session)
})
}

View file

@ -0,0 +1,8 @@
#language en
@applicationdiscoveryservice @client
Feature: AWS Application Discovery Service
Scenario: Making a request
When I call the "DescribeAgents" API
Then the request should be successful

View file

@ -0,0 +1,19 @@
// +build integration
//Package applicationdiscoveryservice provides gucumber integration tests support.
package applicationdiscoveryservice
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/applicationdiscoveryservice"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@applicationdiscoveryservice", func() {
gucumber.World["client"] = applicationdiscoveryservice.New(
smoke.Session, &aws.Config{Region: aws.String("us-west-2")},
)
})
}

View file

@ -0,0 +1,18 @@
# language: en
@autoscaling @client
Feature: Auto Scaling
Scenario: Making a request
When I call the "DescribeScalingProcessTypes" API
Then the value at "Processes" should be a list
Scenario: Handing errors
When I attempt to call the "CreateLaunchConfiguration" API with:
| LaunchConfigurationName | |
| ImageId | ami-12345678 |
| InstanceType | m1.small |
Then I expect the response error code to be "InvalidParameter"
And I expect the response error message to include:
"""
LaunchConfigurationName
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package autoscaling provides gucumber integration tests support.
package autoscaling
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@autoscaling", func() {
gucumber.World["client"] = autoscaling.New(smoke.Session)
})
}

View file

@ -0,0 +1,7 @@
# language: en
@autoscalingplans @client
Feature: AWS Auto Scaling Plans
Scenario: Making a request
When I call the "DescribeScalingPlans" API
Then the request should be successful

View file

@ -0,0 +1,16 @@
// +build integration
//Package autoscalingplans provides gucumber integration tests support.
package autoscalingplans
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/autoscalingplans"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@autoscalingplans", func() {
gucumber.World["client"] = autoscalingplans.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudformation provides gucumber integration tests support.
package cloudformation
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudformation", func() {
gucumber.World["client"] = cloudformation.New(smoke.Session)
})
}

View file

@ -0,0 +1,17 @@
# language: en
@cloudformation @client
Feature: AWS CloudFormation
Scenario: Making a request
When I call the "ListStacks" API
Then the value at "StackSummaries" should be a list
Scenario: Handling errors
When I attempt to call the "CreateStack" API with:
| StackName | fakestack |
| TemplateURL | http://s3.amazonaws.com/foo/bar |
Then I expect the response error code to be "ValidationError"
And I expect the response error message to include:
"""
TemplateURL must reference a valid S3 object to which you have access.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudfront provides gucumber integration tests support.
package cloudfront
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudfront", func() {
gucumber.World["client"] = cloudfront.New(smoke.Session)
})
}

View file

@ -0,0 +1,17 @@
# language: en
@cloudfront @client
Feature: Amazon CloudFront
Scenario: Making a basic request
When I call the "ListDistributions" API with:
| MaxItems | 1 |
Then the value at "DistributionList.Items" should be a list
Scenario: Error handling
When I attempt to call the "GetDistribution" API with:
| Id | fake-id |
Then I expect the response error code to be "NoSuchDistribution"
And I expect the response error message to include:
"""
The specified distribution does not exist.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudhsm provides gucumber integration tests support.
package cloudhsm
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudhsm"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudhsm", func() {
gucumber.World["client"] = cloudhsm.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@cloudhsm @client
Feature: Amazon CloudHSM
Scenario: Making a request
When I call the "ListHapgs" API
Then the value at "HapgList" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeHapg" API with:
| HapgArn | bogus-arn |
Then I expect the response error code to be "ValidationException"
And I expect the response error message to include:
"""
Value 'bogus-arn' at 'hapgArn' failed to satisfy constraint
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudhsmv2 provides gucumber integration tests support.
package cloudhsmv2
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudhsmv2"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudhsmv2", func() {
gucumber.World["client"] = cloudhsmv2.New(smoke.Session)
})
}

View file

@ -0,0 +1,7 @@
# language: en
@cloudhsmv2 @client
Feature: Amazon CloudHSMv2
Scenario: Making a request
When I call the "DescribeBackups" API
Then the request should be successful

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudsearch provides gucumber integration tests support.
package cloudsearch
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudsearch"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudsearch", func() {
gucumber.World["client"] = cloudsearch.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@cloudsearch @client
Feature: Amazon CloudSearch
Scenario: Making a request
When I call the "DescribeDomains" API
Then the response should contain a "DomainStatusList"
Scenario: Handling errors
When I attempt to call the "DescribeIndexFields" API with:
| DomainName | fakedomain |
Then I expect the response error code to be "ResourceNotFound"
And I expect the response error message to include:
"""
Domain not found: fakedomain
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudtrail provides gucumber integration tests support.
package cloudtrail
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudtrail"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudtrail", func() {
gucumber.World["client"] = cloudtrail.New(smoke.Session)
})
}

View file

@ -0,0 +1,12 @@
# language: en
@cloudtrail @client
Feature: AWS CloudTrail
Scenario: Making a request
When I call the "DescribeTrails" API
Then the request should be successful
Scenario: Handling errors
When I attempt to call the "DeleteTrail" API with:
| Name | faketrail |
Then I expect the response error code to be "TrailNotFoundException"

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudwatch provides gucumber integration tests support.
package cloudwatch
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudwatch", func() {
gucumber.World["client"] = cloudwatch.New(smoke.Session)
})
}

View file

@ -0,0 +1,19 @@
# language: en
@cloudwatch @monitoring @client
Feature: Amazon CloudWatch
Scenario: Making a request
When I call the "ListMetrics" API with:
| Namespace | AWS/EC2 |
Then the value at "Metrics" should be a list
Scenario: Handling errors
When I attempt to call the "SetAlarmState" API with:
| AlarmName | abc |
| StateValue | mno |
| StateReason | xyz |
Then I expect the response error code to be "ValidationError"
And I expect the response error message to include:
"""
failed to satisfy constraint
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cloudwatchlogs provides gucumber integration tests support.
package cloudwatchlogs
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cloudwatchlogs", func() {
gucumber.World["client"] = cloudwatchlogs.New(smoke.Session)
})
}

View file

@ -0,0 +1,17 @@
# language: en
@cloudwatchlogs @logs
Feature: Amazon CloudWatch Logs
Scenario: Making a request
When I call the "DescribeLogGroups" API
Then the value at "logGroups" should be a list
Scenario: Handling errors
When I attempt to call the "GetLogEvents" API with:
| logGroupName | fakegroup |
| logStreamName | fakestream |
Then I expect the response error code to be "ResourceNotFoundException"
And I expect the response error message to include:
"""
The specified log group does not exist.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package codecommit provides gucumber integration tests support.
package codecommit
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/codecommit"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@codecommit", func() {
gucumber.World["client"] = codecommit.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@codecommit @client
Feature: Amazon CodeCommit
Scenario: Making a request
When I call the "ListRepositories" API
Then the value at "repositories" should be a list
Scenario: Handling errors
When I attempt to call the "ListBranches" API with:
| repositoryName | fake-repo |
Then I expect the response error code to be "RepositoryDoesNotExistException"
And I expect the response error message to include:
"""
fake-repo does not exist
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package codedeploy provides gucumber integration tests support.
package codedeploy
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/codedeploy"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@codedeploy", func() {
gucumber.World["client"] = codedeploy.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@codedeploy @client
Feature: Amazon CodeDeploy
Scenario: Making a request
When I call the "ListApplications" API
Then the value at "applications" should be a list
Scenario: Handling errors
When I attempt to call the "GetDeployment" API with:
| deploymentId | d-USUAELQEX |
Then I expect the response error code to be "DeploymentDoesNotExistException"
And I expect the response error message to include:
"""
The deployment d-USUAELQEX could not be found
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package codepipeline provides gucumber integration tests support.
package codepipeline
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/codepipeline"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@codepipeline", func() {
gucumber.World["client"] = codepipeline.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@codepipeline @client
Feature: Amazon CodePipeline
Scenario: Making a request
When I call the "ListPipelines" API
Then the value at "pipelines" should be a list
Scenario: Handling errors
When I attempt to call the "GetPipeline" API with:
| name | fake-pipeline |
Then I expect the response error code to be "PipelineNotFoundException"
And I expect the response error message to include:
"""
does not have a pipeline with name 'fake-pipeline'
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cognitoidentity provides gucumber integration tests support.
package cognitoidentity
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cognitoidentity"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cognitoidentity", func() {
gucumber.World["client"] = cognitoidentity.New(smoke.Session)
})
}

View file

@ -0,0 +1,19 @@
# language: en
@cognitoidentity @client
Feature: Amazon Cognito Idenity
Scenario: Making a request
When I call the "ListIdentityPools" API with JSON:
"""
{"MaxResults": 10}
"""
Then the value at "IdentityPools" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeIdentityPool" API with:
| IdentityPoolId | us-east-1:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee |
Then I expect the response error code to be "ResourceNotFoundException"
And I expect the response error message to include:
"""
IdentityPool 'us-east-1:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' not found
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package cognitosync provides gucumber integration tests support.
package cognitosync
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/cognitosync"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@cognitosync", func() {
gucumber.World["client"] = cognitosync.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@cognitosync @client
Feature: Amazon Cognito Sync
Scenario: Making a request
When I call the "ListIdentityPoolUsage" API
Then the value at "IdentityPoolUsages" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeIdentityPoolUsage" API with:
| IdentityPoolId | us-east-1:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee |
Then I expect the response error code to be "ResourceNotFoundException"
And I expect the response error message to include:
"""
IdentityPool 'us-east-1:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' not found
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package configservice provides gucumber integration tests support.
package configservice
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/configservice"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@configservice", func() {
gucumber.World["client"] = configservice.New(smoke.Session)
})
}

View file

@ -0,0 +1,17 @@
# language: en
@configservice @config @client
Feature: AWS Config
Scenario: Making a request
When I call the "DescribeConfigurationRecorders" API
Then the value at "ConfigurationRecorders" should be a list
Scenario: Handling errors
When I attempt to call the "GetResourceConfigHistory" API with:
| resourceType | fake-type |
| resourceId | fake-id |
Then I expect the response error code to be "ValidationException"
And I expect the response error message to include:
"""
failed to satisfy constraint
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package datapipeline provides gucumber integration tests support.
package datapipeline
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/datapipeline"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@datapipeline", func() {
gucumber.World["client"] = datapipeline.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@datapipeline @client
Feature: AWS Data Pipeline
Scenario: Making a request
When I call the "ListPipelines" API
Then the response should contain a "pipelineIdList"
Scenario: Handling errors
When I attempt to call the "GetPipelineDefinition" API with:
| pipelineId | fake-id |
Then I expect the response error code to be "PipelineNotFoundException"
And I expect the response error message to include:
"""
does not exist
"""

View file

@ -0,0 +1,19 @@
// +build integration
//Package devicefarm provides gucumber integration tests support.
package devicefarm
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/devicefarm"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@devicefarm", func() {
// FIXME remove custom region
gucumber.World["client"] = devicefarm.New(smoke.Session,
aws.NewConfig().WithRegion("us-west-2"))
})
}

View file

@ -0,0 +1,16 @@
# language: en
@devicefarm @client
Feature: AWS Device Farm
Scenario: Making a request
When I call the "ListDevices" API
Then the value at "devices" should be a list
Scenario: Handling errors
When I attempt to call the "GetDevice" API with:
| arn | arn:aws:devicefarm:us-west-2::device:000000000000000000000000fake-arn |
Then I expect the response error code to be "NotFoundException"
And I expect the response error message to include:
"""
No device was found for arn
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package directconnect provides gucumber integration tests support.
package directconnect
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/directconnect"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@directconnect", func() {
gucumber.World["client"] = directconnect.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@directconnect @client
Feature: AWS Direct Connect
Scenario: Making a request
When I call the "DescribeConnections" API
Then the value at "connections" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeConnections" API with:
| connectionId | fake-connection |
Then I expect the response error code to be "DirectConnectClientException"
And I expect the response error message to include:
"""
Connection ID fake-connection has an invalid format
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package directoryservice provides gucumber integration tests support.
package directoryservice
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/directoryservice"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@directoryservice", func() {
gucumber.World["client"] = directoryservice.New(smoke.Session)
})
}

View file

@ -0,0 +1,17 @@
# language: en
@directoryservice @ds @client
Feature: AWS Directory Service
I want to use AWS Directory Service
Scenario: Making a request
When I call the "DescribeDirectories" API
Then the value at "DirectoryDescriptions" should be a list
Scenario: Handling errors
When I attempt to call the "CreateDirectory" API with:
| Name | |
| Password | |
| Size | |
Then I expect the response error code to be "ValidationException"

View file

@ -0,0 +1,16 @@
// +build integration
//Package dynamodb provides gucumber integration tests support.
package dynamodb
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@dynamodb", func() {
gucumber.World["client"] = dynamodb.New(smoke.Session)
})
}

View file

@ -0,0 +1,19 @@
# language: en
@dynamodb @client
Feature: Amazon DynamoDB
Scenario: Making a request
When I call the "ListTables" API with JSON:
"""
{"Limit": 1}
"""
Then the value at "TableNames" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeTable" API with:
| TableName | fake-table |
Then I expect the response error code to be "ResourceNotFoundException"
And I expect the response error message to include:
"""
Requested resource not found: Table: fake-table not found
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package dynamodbstreams provides gucumber integration tests support.
package dynamodbstreams
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/dynamodbstreams"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@dynamodbstreams", func() {
gucumber.World["client"] = dynamodbstreams.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@dynamodbstreams @client
Feature: Amazon DynamoDB Streams
Scenario: Making a request
When I call the "ListStreams" API
Then the value at "Streams" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeStream" API with:
| StreamArn | fake-stream |
Then I expect the response error code to be "InvalidParameter"
And I expect the response error message to include:
"""
StreamArn
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package ec2 provides gucumber integration tests support.
package ec2
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@ec2", func() {
gucumber.World["client"] = ec2.New(smoke.Session)
})
}

View file

@ -0,0 +1,18 @@
# language: en
@ec2 @client
Feature: Amazon Elastic Compute Cloud
Scenario: Making a request
When I call the "DescribeRegions" API
Then the value at "Regions" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeInstances" API with JSON:
"""
{"InstanceIds": ["i-12345678"]}
"""
Then I expect the response error code to be "InvalidInstanceID.NotFound"
And I expect the response error message to include:
"""
The instance ID 'i-12345678' does not exist
"""

View file

@ -0,0 +1,19 @@
// +build integration
//Package ecs provides gucumber integration tests support.
package ecs
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/ecs"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@ecs", func() {
// FIXME remove custom region
gucumber.World["client"] = ecs.New(smoke.Session,
aws.NewConfig().WithRegion("us-west-2"))
})
}

View file

@ -0,0 +1,14 @@
# language: en
@ecs @client
Feature: Amazon ECS
I want to use Amazon ECS
Scenario: Making a request
When I call the "ListClusters" API
Then the value at "clusterArns" should be a list
Scenario: Handling errors
When I attempt to call the "StopTask" API with:
| task | xxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxx |
Then the error code should be "ClusterNotFoundException"

View file

@ -0,0 +1,19 @@
// +build integration
//Package efs provides gucumber integration tests support.
package efs
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/efs"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@efs", func() {
// FIXME remove custom region
gucumber.World["client"] = efs.New(smoke.Session,
aws.NewConfig().WithRegion("us-west-2"))
})
}

View file

@ -0,0 +1,14 @@
# language: en
@efs @elasticfilesystem @client
Feature: Amazon Elastic File System
I want to use Amazon Elastic File System
Scenario: Making a request
When I call the "DescribeFileSystems" API
Then the value at "FileSystems" should be a list
Scenario: Handling errors
When I attempt to call the "DeleteFileSystem" API with:
| FileSystemId | fake-id |
Then the error code should be "BadRequest"

View file

@ -0,0 +1,16 @@
// +build integration
//Package elasticache provides gucumber integration tests support.
package elasticache
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/elasticache"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@elasticache", func() {
gucumber.World["client"] = elasticache.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@elasticache @client
Feature: ElastiCache
Scenario: Making a request
When I call the "DescribeEvents" API
Then the value at "Events" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeCacheClusters" API with:
| CacheClusterId | fake_cluster |
Then I expect the response error code to be "InvalidParameterValue"
And I expect the response error message to include:
"""
The parameter CacheClusterIdentifier is not a valid identifier.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package elasticbeanstalk provides gucumber integration tests support.
package elasticbeanstalk
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/elasticbeanstalk"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@elasticbeanstalk", func() {
gucumber.World["client"] = elasticbeanstalk.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@elasticbeanstalk @client
Feature: AWS Elastic Beanstalk
Scenario: Making a request
When I call the "ListAvailableSolutionStacks" API
Then the value at "SolutionStacks" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeEnvironmentResources" API with:
| EnvironmentId | fake_environment |
Then I expect the response error code to be "InvalidParameterValue"
And I expect the response error message to include:
"""
No Environment found for EnvironmentId = 'fake_environment'.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package elasticloadbalancing provides gucumber integration tests support.
package elasticloadbalancing
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/elb"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@elasticloadbalancing", func() {
gucumber.World["client"] = elb.New(smoke.Session)
})
}

View file

@ -0,0 +1,18 @@
# language: en
@elasticloadbalancing @client
Feature: Elastic Load Balancing
Scenario: Making a request
When I call the "DescribeLoadBalancers" API
Then the value at "LoadBalancerDescriptions" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeLoadBalancers" API with JSON:
"""
{"LoadBalancerNames": ["fake_load_balancer"]}
"""
Then I expect the response error code to be "ValidationError"
And I expect the response error message to include:
"""
LoadBalancer name cannot contain characters that are not letters, or digits or the dash.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package elastictranscoder provides gucumber integration tests support.
package elastictranscoder
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/elastictranscoder"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@elastictranscoder", func() {
gucumber.World["client"] = elastictranscoder.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@elastictranscoder @client
Feature: Amazon Elastic Transcoder
Scenario: Making a request
When I call the "ListPresets" API
Then the value at "Presets" should be a list
Scenario: Handling errors
When I attempt to call the "ReadJob" API with:
| Id | fake_job |
Then I expect the response error code to be "ValidationException"
And I expect the response error message to include:
"""
Value 'fake_job' at 'id' failed to satisfy constraint
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package emr provides gucumber integration tests support.
package emr
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/emr"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@emr", func() {
gucumber.World["client"] = emr.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@emr @client @elasticmapreduce
Feature: Amazon EMR
Scenario: Making a request
When I call the "ListClusters" API
Then the value at "Clusters" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeCluster" API with:
| ClusterId | fake_cluster |
Then I expect the response error code to be "InvalidRequestException"
And I expect the response error message to include:
"""
Cluster id 'fake_cluster' is not valid.
"""

View file

@ -0,0 +1,16 @@
// +build integration
//Package es provides gucumber integration tests support.
package es
import (
"github.com/aws/aws-sdk-go/awstesting/integration/smoke"
"github.com/aws/aws-sdk-go/service/elasticsearchservice"
"github.com/gucumber/gucumber"
)
func init() {
gucumber.Before("@es", func() {
gucumber.World["client"] = elasticsearchservice.New(smoke.Session)
})
}

View file

@ -0,0 +1,16 @@
# language: en
@es @elasticsearchservice
Feature: Amazon ElasticsearchService
Scenario: Making a request
When I call the "ListDomainNames" API
Then the value at "DomainNames" should be a list
Scenario: Handling errors
When I attempt to call the "DescribeElasticsearchDomain" API with:
| DomainName | not-a-domain |
Then the error code should be "ResourceNotFoundException"
And I expect the response error message to include:
"""
Domain not found: not-a-domain
"""

Some files were not shown because too many files have changed in this diff Show more