func TestPresignHandler(t *testing.T) { svc := s3.New(nil) req, _ := svc.PutObjectRequest(&s3.PutObjectInput{ Bucket: aws.String("bucket"), Key: aws.String("key"), ContentDisposition: aws.String("a+b c$d"), ACL: aws.String("public-read"), }) req.Time = time.Unix(0, 0) urlstr, err := req.Presign(5 * time.Minute) assert.NoError(t, err) expectedDate := "19700101T000000Z" expectedHeaders := "host;x-amz-acl" expectedSig := "7edcb4e3a1bf12f4989018d75acbe3a7f03df24bd6f3112602d59fc551f0e4e2" expectedCred := "AKID/19700101/mock-region/s3/aws4_request" u, _ := url.Parse(urlstr) urlQ := u.Query() assert.Equal(t, expectedSig, urlQ.Get("X-Amz-Signature")) assert.Equal(t, expectedCred, urlQ.Get("X-Amz-Credential")) assert.Equal(t, expectedHeaders, urlQ.Get("X-Amz-SignedHeaders")) assert.Equal(t, expectedDate, urlQ.Get("X-Amz-Date")) assert.Equal(t, "300", urlQ.Get("X-Amz-Expires")) assert.NotContains(t, urlstr, "+") // + encoded as %20 }
func dlLoggingSvc(data []byte) (*s3.S3, *[]string, *[]string) { var m sync.Mutex names := []string{} ranges := []string{} svc := s3.New(nil) svc.Handlers.Send.Clear() svc.Handlers.Send.PushBack(func(r *aws.Request) { m.Lock() defer m.Unlock() names = append(names, r.Operation.Name) ranges = append(ranges, *r.Params.(*s3.GetObjectInput).Range) rerng := regexp.MustCompile(`bytes=(\d+)-(\d+)`) rng := rerng.FindStringSubmatch(r.HTTPRequest.Header.Get("Range")) start, _ := strconv.ParseInt(rng[1], 10, 64) fin, _ := strconv.ParseInt(rng[2], 10, 64) fin++ if fin > int64(len(data)) { fin = int64(len(data)) } r.HTTPResponse = &http.Response{ StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader(data[start:fin])), Header: http.Header{}, } r.HTTPResponse.Header.Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, fin, len(data))) }) return svc, &names, &ranges }
func loggingSvc() (*s3.S3, *[]string, *[]interface{}) { var m sync.Mutex partNum := 0 names := []string{} params := []interface{}{} svc := s3.New(nil) svc.Handlers.Unmarshal.Clear() svc.Handlers.UnmarshalMeta.Clear() svc.Handlers.UnmarshalError.Clear() svc.Handlers.Send.Clear() svc.Handlers.Send.PushBack(func(r *aws.Request) { m.Lock() defer m.Unlock() names = append(names, r.Operation.Name) params = append(params, r.Params) r.HTTPResponse = &http.Response{ StatusCode: 200, Body: ioutil.NopCloser(bytes.NewReader([]byte{})), } switch data := r.Data.(type) { case *s3.CreateMultipartUploadOutput: data.UploadID = aws.String("UPLOAD-ID") case *s3.UploadPartOutput: partNum++ data.ETag = aws.String(fmt.Sprintf("ETAG%d", partNum)) case *s3.CompleteMultipartUploadOutput: data.Location = aws.String("https://location") } }) return svc, &names, ¶ms }
func TestMD5InPutBucketPolicy(t *testing.T) { svc := s3.New(nil) req, _ := svc.PutBucketPolicyRequest(&s3.PutBucketPolicyInput{ Bucket: aws.String("bucketname"), Policy: aws.String("{}"), }) assertMD5(t, req) }
func TestNoPopulateLocationConstraintIfClassic(t *testing.T) { s := s3.New(&aws.Config{Region: "us-east-1"}) req, _ := s.CreateBucketRequest(&s3.CreateBucketInput{ Bucket: aws.String("bucket"), }) err := req.Build() assert.NoError(t, err) assert.Equal(t, 0, len(awsutil.ValuesAtPath(req.Params, "CreateBucketConfiguration.LocationConstraint"))) }
func TestNoPopulateLocationConstraintIfProvided(t *testing.T) { s := s3.New(nil) req, _ := s.CreateBucketRequest(&s3.CreateBucketInput{ Bucket: aws.String("bucket"), CreateBucketConfiguration: &s3.CreateBucketConfiguration{}, }) err := req.Build() assert.NoError(t, err) assert.Equal(t, 0, len(awsutil.ValuesAtPath(req.Params, "CreateBucketConfiguration.LocationConstraint"))) }
func TestPopulateLocationConstraint(t *testing.T) { s := s3.New(nil) in := &s3.CreateBucketInput{ Bucket: aws.String("bucket"), } req, _ := s.CreateBucketRequest(in) err := req.Build() assert.NoError(t, err) assert.Equal(t, "mock-region", awsutil.ValuesAtPath(req.Params, "CreateBucketConfiguration.LocationConstraint")[0]) assert.Nil(t, in.CreateBucketConfiguration) // don't modify original params }
func TestMD5InPutBucketCORS(t *testing.T) { svc := s3.New(nil) req, _ := svc.PutBucketCORSRequest(&s3.PutBucketCORSInput{ Bucket: aws.String("bucketname"), CORSConfiguration: &s3.CORSConfiguration{ CORSRules: []*s3.CORSRule{ {AllowedMethods: []*string{aws.String("GET")}}, }, }, }) assertMD5(t, req) }
func TestMD5InPutBucketTagging(t *testing.T) { svc := s3.New(nil) req, _ := svc.PutBucketTaggingRequest(&s3.PutBucketTaggingInput{ Bucket: aws.String("bucketname"), Tagging: &s3.Tagging{ TagSet: []*s3.Tag{ {Key: aws.String("KEY"), Value: aws.String("VALUE")}, }, }, }) assertMD5(t, req) }
func TestMD5InDeleteObjects(t *testing.T) { svc := s3.New(nil) req, _ := svc.DeleteObjectsRequest(&s3.DeleteObjectsInput{ Bucket: aws.String("bucketname"), Delete: &s3.Delete{ Objects: []*s3.ObjectIdentifier{ {Key: aws.String("key")}, }, }, }) assertMD5(t, req) }
// init will initialize all default options. func (u *uploader) init() { if u.opts.S3 == nil { u.opts.S3 = s3.New(nil) } if u.opts.Concurrency == 0 { u.opts.Concurrency = DefaultUploadConcurrency } if u.opts.PartSize == 0 { u.opts.PartSize = DefaultUploadPartSize } // Try to get the total size for some optimizations u.initSize() }
func TestCopySourceSSECustomerKeyOverHTTPError(t *testing.T) { s := s3.New(&aws.Config{DisableSSL: true}) req, _ := s.CopyObjectRequest(&s3.CopyObjectInput{ Bucket: aws.String("bucket"), CopySource: aws.String("bucket/source"), Key: aws.String("dest"), CopySourceSSECustomerKey: aws.String("key"), }) err := req.Build() assert.Error(t, err) assert.Equal(t, "ConfigError", err.(awserr.Error).Code()) assert.Contains(t, err.(awserr.Error).Message(), "cannot send SSE keys over HTTP") }
// init initializes the downloader with default options. func (d *downloader) init() { d.totalBytes = -1 if d.opts.Concurrency == 0 { d.opts.Concurrency = DefaultDownloadConcurrency } if d.opts.PartSize == 0 { d.opts.PartSize = DefaultDownloadPartSize } if d.opts.S3 == nil { d.opts.S3 = s3.New(nil) } }
func TestMD5InPutBucketLifecycle(t *testing.T) { svc := s3.New(nil) req, _ := svc.PutBucketLifecycleRequest(&s3.PutBucketLifecycleInput{ Bucket: aws.String("bucketname"), LifecycleConfiguration: &s3.LifecycleConfiguration{ Rules: []*s3.LifecycleRule{ { ID: aws.String("ID"), Prefix: aws.String("Prefix"), Status: aws.String("Enabled"), }, }, }, }) assertMD5(t, req) }
// Use S3 for simplicity func TestPaginationTruncation(t *testing.T) { count := 0 client := s3.New(nil) reqNum := &count resps := []*s3.ListObjectsOutput{ {IsTruncated: aws.Boolean(true), Contents: []*s3.Object{{Key: aws.String("Key1")}}}, {IsTruncated: aws.Boolean(true), Contents: []*s3.Object{{Key: aws.String("Key2")}}}, {IsTruncated: aws.Boolean(false), Contents: []*s3.Object{{Key: aws.String("Key3")}}}, {IsTruncated: aws.Boolean(true), Contents: []*s3.Object{{Key: aws.String("Key4")}}}, } client.Handlers.Send.Clear() // mock sending client.Handlers.Unmarshal.Clear() client.Handlers.UnmarshalMeta.Clear() client.Handlers.ValidateResponse.Clear() client.Handlers.Unmarshal.PushBack(func(r *aws.Request) { r.Data = resps[*reqNum] *reqNum++ }) params := &s3.ListObjectsInput{Bucket: aws.String("bucket")} results := []string{} err := client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool { results = append(results, *p.Contents[0].Key) return true }) assert.Equal(t, []string{"Key1", "Key2", "Key3"}, results) assert.Nil(t, err) // Try again without truncation token at all count = 0 resps[1].IsTruncated = nil resps[2].IsTruncated = aws.Boolean(true) results = []string{} err = client.ListObjectsPages(params, func(p *s3.ListObjectsOutput, last bool) bool { results = append(results, *p.Contents[0].Key) return true }) assert.Equal(t, []string{"Key1", "Key2"}, results) assert.Nil(t, err) }
func TestComputeSSEKeys(t *testing.T) { s := s3.New(nil) req, _ := s.CopyObjectRequest(&s3.CopyObjectInput{ Bucket: aws.String("bucket"), CopySource: aws.String("bucket/source"), Key: aws.String("dest"), SSECustomerKey: aws.String("key"), CopySourceSSECustomerKey: aws.String("key"), }) err := req.Build() assert.NoError(t, err) assert.Equal(t, "a2V5", req.HTTPRequest.Header.Get("x-amz-server-side-encryption-customer-key")) assert.Equal(t, "a2V5", req.HTTPRequest.Header.Get("x-amz-copy-source-server-side-encryption-customer-key")) assert.Equal(t, "PG4LipwVIkqCKLmpjKFTHQ==", req.HTTPRequest.Header.Get("x-amz-server-side-encryption-customer-key-md5")) assert.Equal(t, "PG4LipwVIkqCKLmpjKFTHQ==", req.HTTPRequest.Header.Get("x-amz-copy-source-server-side-encryption-customer-key-md5")) }
func TestGetBucketLocation(t *testing.T) { for _, test := range s3LocationTests { s := s3.New(nil) s.Handlers.Send.Clear() s.Handlers.Send.PushBack(func(r *aws.Request) { reader := ioutil.NopCloser(bytes.NewReader([]byte(test.body))) r.HTTPResponse = &http.Response{StatusCode: 200, Body: reader} }) resp, err := s.GetBucketLocation(&s3.GetBucketLocationInput{Bucket: aws.String("bucket")}) assert.NoError(t, err) if test.loc == "" { assert.Nil(t, resp.LocationConstraint) } else { assert.Equal(t, test.loc, *resp.LocationConstraint) } } }
func TestStatusCodeError(t *testing.T) { for _, test := range s3StatusCodeErrorTests { s := s3.New(nil) s.Handlers.Send.Clear() s.Handlers.Send.PushBack(func(r *aws.Request) { body := ioutil.NopCloser(bytes.NewReader([]byte(test.body))) r.HTTPResponse = &http.Response{ ContentLength: int64(len(test.body)), StatusCode: test.scode, Status: test.status, Body: body, } }) _, err := s.PutBucketACL(&s3.PutBucketACLInput{ Bucket: aws.String("bucket"), ACL: aws.String("public-read"), }) assert.Error(t, err) assert.Equal(t, test.code, err.(awserr.Error).Code()) assert.Equal(t, test.message, err.(awserr.Error).Message()) } }
func TestSkipPagination(t *testing.T) { client := s3.New(nil) client.Handlers.Send.Clear() // mock sending client.Handlers.Unmarshal.Clear() client.Handlers.UnmarshalMeta.Clear() client.Handlers.ValidateResponse.Clear() client.Handlers.Unmarshal.PushBack(func(r *aws.Request) { r.Data = &s3.HeadBucketOutput{} }) req, _ := client.HeadBucketRequest(&s3.HeadBucketInput{Bucket: aws.String("bucket")}) numPages, gotToEnd := 0, false req.EachPage(func(p interface{}, last bool) bool { numPages++ if last { gotToEnd = true } return true }) assert.Equal(t, 1, numPages) assert.True(t, gotToEnd) }
func cmdUninstall(c *cli.Context) { if !c.Bool("force") { apps := getApps() if len(*apps) != 0 { stdcli.Error(fmt.Errorf("Please delete all apps before uninstalling.")) } } fmt.Println(` ___ ___ ___ __ __ ___ __ _ /'___\ / __'\ /' _ '\/\ \/\ \ / __'\/\ \/'\ /\ \__//\ \_\ \/\ \/\ \ \ \_/ |/\ \_\ \/> </ \ \____\ \____/\ \_\ \_\ \___/ \ \____//\_/\_\ \/____/\/___/ \/_/\/_/\/__/ \/___/ \//\/_/ `) fmt.Println("This uninstaller needs AWS credentials to uninstall the Convox platform from") fmt.Println("your AWS account. These credentials will only be used to communicate") fmt.Println("between this uninstaller running on your computer and the AWS API.") fmt.Println("") fmt.Println("We recommend that you create a new set of credentials exclusively for this") fmt.Println("uninstall process and then delete them once the uninstaller has completed.") fmt.Println("") fmt.Println("To generate a new set of AWS credentials go to:") fmt.Println("https://console.aws.amazon.com/iam/home#security_credential") fmt.Println("") reader := bufio.NewReader(os.Stdin) access := os.Getenv("AWS_ACCESS_KEY_ID") secret := os.Getenv("AWS_SECRET_ACCESS_KEY") if access == "" || secret == "" { var err error fmt.Print("AWS Access Key: ") access, err = reader.ReadString('\n') if err != nil { stdcli.Error(err) } fmt.Print("AWS Secret Access Key: ") secret, err = reader.ReadString('\n') if err != nil { stdcli.Error(err) } } stackName := os.Getenv("STACK_NAME") if stackName == "" { stackName = "convox" } fmt.Println("") fmt.Println("Uninstalling Convox...") distinctId := randomString(10) access = strings.TrimSpace(access) secret = strings.TrimSpace(secret) CloudFormation := cloudformation.New(&aws.Config{ Region: c.String("region"), Credentials: credentials.NewStaticCredentials(access, secret, ""), }) res, err := CloudFormation.DescribeStackResources(&cloudformation.DescribeStackResourcesInput{ StackName: aws.String(stackName), }) if err != nil { handleError("uninstall", distinctId, err) return } stackId := "" bucket := "" for _, r := range res.StackResources { stackId = *r.StackID if *r.LogicalResourceID == "RegistryBucket" { bucket = *r.PhysicalResourceID } } _, err = CloudFormation.DeleteStack(&cloudformation.DeleteStackInput{ StackName: aws.String(stackName), }) if err != nil { handleError("uninstall", distinctId, err) return } sendMixpanelEvent("convox-uninstall-start") fmt.Printf("Cleaning up registry...\n") S3 := s3.New(&aws.Config{ Region: c.String("region"), Credentials: credentials.NewStaticCredentials(access, secret, ""), }) req := &s3.ListObjectVersionsInput{ Bucket: aws.String(bucket), } sres, err := S3.ListObjectVersions(req) if err != nil { if awsErr, ok := err.(awserr.Error); ok { // Don't block uninstall NoSuchBucket if awsErr.Code() != "NoSuchBucket" { handleError("uninstall", distinctId, err) } } } for _, v := range sres.Versions { req := &s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(*v.Key), VersionID: aws.String(*v.VersionID), } _, err := S3.DeleteObject(req) if err != nil { handleError("uninstall", distinctId, err) return } } host, err := waitForCompletion(stackId, CloudFormation, true) if err != nil { handleError("uninstall", distinctId, err) return } if configuredHost, _ := currentHost(); configuredHost == host { removeHost() } removeLogin(host) fmt.Println("Successfully uninstalled.") sendMixpanelEvent("convox-uninstall-success") }
func TestHostStyleBucketBuild(t *testing.T) { s := s3.New(nil) runTests(t, s, sslTests) }
func TestHostStyleBucketBuildNoSSL(t *testing.T) { s := s3.New(&aws.Config{DisableSSL: true}) runTests(t, s, nosslTests) }
func TestPathStyleBucketBuild(t *testing.T) { s := s3.New(&aws.Config{S3ForcePathStyle: true}) runTests(t, s, forcepathTests) }
func TestInterface(t *testing.T) { assert.Implements(t, (*s3iface.S3API)(nil), s3.New(nil)) }