Skip to content

Instantly share code, notes, and snippets.

@kamermans
Created February 25, 2020 03:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kamermans/6d84d3a35f5809e67c71f657cbb16e02 to your computer and use it in GitHub Desktop.
Save kamermans/6d84d3a35f5809e67c71f657cbb16e02 to your computer and use it in GitHub Desktop.
Thread-Safe AWS S3 Mock for Golang (works with GetObject, PutObject, DeleteObject, HeadBucket)
package something
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"net/url"
"path"
"sync"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"
)
type mockedS3Client struct {
s3iface.S3API
mu sync.Mutex
files map[string][]byte
tags map[string]map[string]string
}
func newMockedS3Client() *mockedS3Client {
return &mockedS3Client{
files: map[string][]byte{},
tags: map[string]map[string]string{},
}
}
func (m *mockedS3Client) HeadBucket(in *s3.HeadBucketInput) (*s3.HeadBucketOutput, error) {
return &s3.HeadBucketOutput{}, nil
}
func (m *mockedS3Client) PutObject(in *s3.PutObjectInput) (out *s3.PutObjectOutput, err error) {
m.mu.Lock()
defer m.mu.Unlock()
key := path.Join(*in.Bucket, *in.Key)
m.files[key], err = ioutil.ReadAll(in.Body)
m.tags[key] = map[string]string{}
if in.Tagging != nil {
u, err := url.Parse("/?" + *in.Tagging)
if err != nil {
panic(fmt.Errorf("Unable to parse AWS S3 Tagging string %q: %w", *in.Tagging, err))
}
q := u.Query()
for k := range q {
m.tags[key][k] = q.Get(k)
}
}
return &s3.PutObjectOutput{}, nil
}
func (m *mockedS3Client) GetObject(in *s3.GetObjectInput) (*s3.GetObjectOutput, error) {
m.mu.Lock()
defer m.mu.Unlock()
key := path.Join(*in.Bucket, *in.Key)
if _, ok := m.files[key]; !ok {
return nil, errors.New("Key does not exist")
}
return &s3.GetObjectOutput{
Body: ioutil.NopCloser(bytes.NewReader(m.files[key])),
}, nil
}
func (m *mockedS3Client) DeleteObject(in *s3.DeleteObjectInput) (*s3.DeleteObjectOutput, error) {
m.mu.Lock()
defer m.mu.Unlock()
if _, ok := m.files[*in.Key]; ok {
delete(m.files, *in.Key)
}
if _, ok := m.tags[*in.Key]; ok {
delete(m.tags, *in.Key)
}
return &s3.DeleteObjectOutput{}, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment