package s3 import ( "bytes" "net/http" "net/http/httptest" "os" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/s3" "github.com/johannesboyne/gofakes3" "github.com/johannesboyne/gofakes3/backend/s3mem" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" "github.com/imgproxy/imgproxy/v3/config" ) type S3TestSuite struct { suite.Suite server *httptest.Server transport http.RoundTripper etag string } func (s *S3TestSuite) SetupSuite() { backend := s3mem.New() faker := gofakes3.New(backend) s.server = httptest.NewServer(faker.Server()) config.S3Enabled = true config.S3Endpoint = s.server.URL os.Setenv("AWS_REGION", "eu-central-1") os.Setenv("AWS_ACCESS_KEY_ID", "Foo") os.Setenv("AWS_SECRET_ACCESS_KEY", "Bar") var err error s.transport, err = New() require.Nil(s.T(), err) svc := s.transport.(transport).svc _, err = svc.CreateBucket(&s3.CreateBucketInput{ Bucket: aws.String("test"), }) require.Nil(s.T(), err) _, err = svc.PutObject(&s3.PutObjectInput{ Body: bytes.NewReader(make([]byte, 32)), Bucket: aws.String("test"), Key: aws.String("foo/test.png"), }) require.Nil(s.T(), err) obj, err := svc.GetObject(&s3.GetObjectInput{ Bucket: aws.String("test"), Key: aws.String("foo/test.png"), }) require.Nil(s.T(), err) defer obj.Body.Close() s.etag = *obj.ETag } func (s *S3TestSuite) TearDownSuite() { s.server.Close() } func (s *S3TestSuite) TestRoundTripWithETagDisabledReturns200() { config.ETagEnabled = false request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil) response, err := s.transport.RoundTrip(request) require.Nil(s.T(), err) require.Equal(s.T(), 200, response.StatusCode) } func (s *S3TestSuite) TestRoundTripWithETagEnabled() { config.ETagEnabled = true request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil) response, err := s.transport.RoundTrip(request) require.Nil(s.T(), err) require.Equal(s.T(), 200, response.StatusCode) require.Equal(s.T(), s.etag, response.Header.Get("ETag")) } func (s *S3TestSuite) TestRoundTripWithIfNoneMatchReturns304() { config.ETagEnabled = true request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil) request.Header.Set("If-None-Match", s.etag) response, err := s.transport.RoundTrip(request) require.Nil(s.T(), err) require.Equal(s.T(), http.StatusNotModified, response.StatusCode) } func (s *S3TestSuite) TestRoundTripWithUpdatedETagReturns200() { config.ETagEnabled = true request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil) request.Header.Set("If-None-Match", s.etag+"_wrong") response, err := s.transport.RoundTrip(request) require.Nil(s.T(), err) require.Equal(s.T(), http.StatusOK, response.StatusCode) } func TestS3Transport(t *testing.T) { suite.Run(t, new(S3TestSuite)) }