s3_test.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package s3
  2. import (
  3. "bytes"
  4. "net/http"
  5. "net/http/httptest"
  6. "os"
  7. "testing"
  8. "time"
  9. "github.com/aws/aws-sdk-go/aws"
  10. "github.com/aws/aws-sdk-go/service/s3"
  11. "github.com/johannesboyne/gofakes3"
  12. "github.com/johannesboyne/gofakes3/backend/s3mem"
  13. "github.com/stretchr/testify/require"
  14. "github.com/stretchr/testify/suite"
  15. "github.com/imgproxy/imgproxy/v3/config"
  16. )
  17. type S3TestSuite struct {
  18. suite.Suite
  19. server *httptest.Server
  20. transport http.RoundTripper
  21. etag string
  22. lastModified time.Time
  23. }
  24. func (s *S3TestSuite) SetupSuite() {
  25. backend := s3mem.New()
  26. faker := gofakes3.New(backend)
  27. s.server = httptest.NewServer(faker.Server())
  28. config.S3Enabled = true
  29. config.S3Endpoint = s.server.URL
  30. os.Setenv("AWS_REGION", "eu-central-1")
  31. os.Setenv("AWS_ACCESS_KEY_ID", "Foo")
  32. os.Setenv("AWS_SECRET_ACCESS_KEY", "Bar")
  33. var err error
  34. s.transport, err = New()
  35. require.Nil(s.T(), err)
  36. svc := s.transport.(transport).svc
  37. _, err = svc.CreateBucket(&s3.CreateBucketInput{
  38. Bucket: aws.String("test"),
  39. })
  40. require.Nil(s.T(), err)
  41. _, err = svc.PutObject(&s3.PutObjectInput{
  42. Body: bytes.NewReader(make([]byte, 32)),
  43. Bucket: aws.String("test"),
  44. Key: aws.String("foo/test.png"),
  45. })
  46. require.Nil(s.T(), err)
  47. obj, err := svc.GetObject(&s3.GetObjectInput{
  48. Bucket: aws.String("test"),
  49. Key: aws.String("foo/test.png"),
  50. })
  51. require.Nil(s.T(), err)
  52. defer obj.Body.Close()
  53. s.etag = *obj.ETag
  54. s.lastModified = *obj.LastModified
  55. }
  56. func (s *S3TestSuite) TearDownSuite() {
  57. s.server.Close()
  58. }
  59. func (s *S3TestSuite) TestRoundTripWithETagDisabledReturns200() {
  60. config.ETagEnabled = false
  61. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  62. response, err := s.transport.RoundTrip(request)
  63. require.Nil(s.T(), err)
  64. require.Equal(s.T(), 200, response.StatusCode)
  65. }
  66. func (s *S3TestSuite) TestRoundTripWithETagEnabled() {
  67. config.ETagEnabled = true
  68. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  69. response, err := s.transport.RoundTrip(request)
  70. require.Nil(s.T(), err)
  71. require.Equal(s.T(), 200, response.StatusCode)
  72. require.Equal(s.T(), s.etag, response.Header.Get("ETag"))
  73. }
  74. func (s *S3TestSuite) TestRoundTripWithIfNoneMatchReturns304() {
  75. config.ETagEnabled = true
  76. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  77. request.Header.Set("If-None-Match", s.etag)
  78. response, err := s.transport.RoundTrip(request)
  79. require.Nil(s.T(), err)
  80. require.Equal(s.T(), http.StatusNotModified, response.StatusCode)
  81. }
  82. func (s *S3TestSuite) TestRoundTripWithUpdatedETagReturns200() {
  83. config.ETagEnabled = true
  84. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  85. request.Header.Set("If-None-Match", s.etag+"_wrong")
  86. response, err := s.transport.RoundTrip(request)
  87. require.Nil(s.T(), err)
  88. require.Equal(s.T(), http.StatusOK, response.StatusCode)
  89. }
  90. func (s *S3TestSuite) TestRoundTripWithLastModifiedDisabledReturns200() {
  91. config.LastModifiedEnabled = false
  92. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  93. response, err := s.transport.RoundTrip(request)
  94. require.Nil(s.T(), err)
  95. require.Equal(s.T(), 200, response.StatusCode)
  96. }
  97. func (s *S3TestSuite) TestRoundTripWithLastModifiedEnabled() {
  98. config.ETagEnabled = true
  99. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  100. response, err := s.transport.RoundTrip(request)
  101. require.Nil(s.T(), err)
  102. require.Equal(s.T(), 200, response.StatusCode)
  103. require.Equal(s.T(), s.lastModified.Format(http.TimeFormat), response.Header.Get("Last-Modified"))
  104. }
  105. // gofakes3 doesn't support If-Modified-Since (yet?)
  106. func (s *S3TestSuite) TestRoundTripWithIfModifiedSinceReturns304() {
  107. config.LastModifiedEnabled = true
  108. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  109. request.Header.Set("If-Modified-Since", s.lastModified.Format(http.TimeFormat))
  110. response, err := s.transport.RoundTrip(request)
  111. require.Nil(s.T(), err)
  112. require.Equal(s.T(), http.StatusNotModified, response.StatusCode)
  113. }
  114. func (s *S3TestSuite) TestRoundTripWithUpdatedLastModifiedReturns200() {
  115. config.LastModifiedEnabled = true
  116. request, _ := http.NewRequest("GET", "s3://test/foo/test.png", nil)
  117. request.Header.Set("If-Modified-Since", s.lastModified.Add(-24*time.Hour).Format(http.TimeFormat))
  118. response, err := s.transport.RoundTrip(request)
  119. require.Nil(s.T(), err)
  120. require.Equal(s.T(), http.StatusOK, response.StatusCode)
  121. }
  122. func TestS3Transport(t *testing.T) {
  123. suite.Run(t, new(S3TestSuite))
  124. }