123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- package swift
- import (
- "context"
- "net/http"
- "testing"
- "time"
- "github.com/ncw/swift/v2"
- "github.com/ncw/swift/v2/swifttest"
- "github.com/stretchr/testify/suite"
- "github.com/imgproxy/imgproxy/v3/config"
- )
- const (
- testContainer = "test"
- testObject = "foo/test.png"
- )
- type SwiftTestSuite struct {
- suite.Suite
- server *swifttest.SwiftServer
- transport http.RoundTripper
- etag string
- lastModified time.Time
- }
- func (s *SwiftTestSuite) SetupSuite() {
- s.server, _ = swifttest.NewSwiftServer("localhost")
- config.Reset()
- config.SwiftAuthURL = s.server.AuthURL
- config.SwiftUsername = swifttest.TEST_ACCOUNT
- config.SwiftAPIKey = swifttest.TEST_ACCOUNT
- config.SwiftAuthVersion = 1
- s.setupTestFile()
- var err error
- s.transport, err = New()
- s.Require().NoError(err, "failed to initialize swift transport")
- }
- func (s *SwiftTestSuite) setupTestFile() {
- c := &swift.Connection{
- UserName: config.SwiftUsername,
- ApiKey: config.SwiftAPIKey,
- AuthUrl: config.SwiftAuthURL,
- AuthVersion: config.SwiftAuthVersion,
- }
- ctx := context.Background()
- err := c.Authenticate(ctx)
- s.Require().NoError(err, "failed to authenticate with test server")
- err = c.ContainerCreate(ctx, testContainer, nil)
- s.Require().NoError(err, "failed to create container")
- f, err := c.ObjectCreate(ctx, testContainer, testObject, true, "", "image/png", nil)
- s.Require().NoError(err, "failed to create object")
- defer f.Close()
- data := make([]byte, 32)
- n, err := f.Write(data)
- s.Require().Len(data, n)
- s.Require().NoError(err)
- f.Close()
- // The Etag is written on file close; but Last-Modified is only available when we get the object again.
- _, h, err := c.Object(ctx, testContainer, testObject)
- s.Require().NoError(err)
- s.etag = h["Etag"]
- s.lastModified, err = time.Parse(http.TimeFormat, h["Date"])
- s.Require().NoError(err)
- }
- func (s *SwiftTestSuite) TearDownSuite() {
- s.server.Close()
- }
- func (s *SwiftTestSuite) TestRoundTripWithETagDisabledReturns200() {
- config.ETagEnabled = false
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(200, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripReturns404WhenObjectNotFound() {
- config.ETagEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/not-here.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(404, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripReturns404WhenContainerNotFound() {
- config.ETagEnabled = true
- request, _ := http.NewRequest("GET", "swift://invalid/foo/test.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(404, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripWithETagEnabled() {
- config.ETagEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(200, response.StatusCode)
- s.Require().Equal(s.etag, response.Header.Get("ETag"))
- }
- func (s *SwiftTestSuite) TestRoundTripWithIfNoneMatchReturns304() {
- config.ETagEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- request.Header.Set("If-None-Match", s.etag)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(http.StatusNotModified, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripWithUpdatedETagReturns200() {
- config.ETagEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- request.Header.Set("If-None-Match", s.etag+"_wrong")
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(http.StatusOK, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripWithLastModifiedDisabledReturns200() {
- config.LastModifiedEnabled = false
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(200, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripWithLastModifiedEnabled() {
- config.LastModifiedEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(200, response.StatusCode)
- s.Require().Equal(s.lastModified.Format(http.TimeFormat), response.Header.Get("Last-Modified"))
- }
- func (s *SwiftTestSuite) TestRoundTripWithIfModifiedSinceReturns304() {
- config.LastModifiedEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- request.Header.Set("If-Modified-Since", s.lastModified.Format(http.TimeFormat))
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(http.StatusNotModified, response.StatusCode)
- }
- func (s *SwiftTestSuite) TestRoundTripWithUpdatedLastModifiedReturns200() {
- config.LastModifiedEnabled = true
- request, _ := http.NewRequest("GET", "swift://test/foo/test.png", nil)
- request.Header.Set("If-Modified-Since", s.lastModified.Add(-24*time.Hour).Format(http.TimeFormat))
- response, err := s.transport.RoundTrip(request)
- s.Require().NoError(err)
- s.Require().Equal(http.StatusOK, response.StatusCode)
- }
- func TestSwiftTransport(t *testing.T) {
- suite.Run(t, new(SwiftTestSuite))
- }
|