1
0

s3_test.go 4.8 KB

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