gopkg.in/goose.v2@v2.0.1/testservices/swiftservice/service_http_test.go (about)

     1  // Swift double testing service - HTTP API tests
     2  
     3  package swiftservice
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/json"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"net/url"
    11  
    12  	gc "gopkg.in/check.v1"
    13  
    14  	"gopkg.in/goose.v2/swift"
    15  	"gopkg.in/goose.v2/testing/httpsuite"
    16  	"gopkg.in/goose.v2/testservices/identityservice"
    17  )
    18  
    19  type SwiftHTTPSuite struct {
    20  	httpsuite.HTTPSuite
    21  	service *Swift
    22  	token   string
    23  }
    24  
    25  var _ = gc.Suite(&SwiftHTTPSuite{})
    26  
    27  type SwiftHTTPSSuite struct {
    28  	httpsuite.HTTPSuite
    29  	service *Swift
    30  	token   string
    31  }
    32  
    33  var _ = gc.Suite(&SwiftHTTPSSuite{HTTPSuite: httpsuite.HTTPSuite{UseTLS: true}})
    34  
    35  func (s *SwiftHTTPSuite) SetUpSuite(c *gc.C) {
    36  	s.HTTPSuite.SetUpSuite(c)
    37  	identityDouble := identityservice.NewUserPass()
    38  	s.service = New(s.Server.URL, versionPath, tenantId, region, identityDouble, nil)
    39  	userInfo := identityDouble.AddUser("fred", "secret", "tenant", "default")
    40  	s.token = userInfo.Token
    41  }
    42  
    43  func (s *SwiftHTTPSuite) SetUpTest(c *gc.C) {
    44  	s.HTTPSuite.SetUpTest(c)
    45  	s.service.SetupHTTP(s.Mux)
    46  }
    47  
    48  func (s *SwiftHTTPSuite) TearDownTest(c *gc.C) {
    49  	s.HTTPSuite.TearDownTest(c)
    50  }
    51  
    52  func (s *SwiftHTTPSuite) TearDownSuite(c *gc.C) {
    53  	s.HTTPSuite.TearDownSuite(c)
    54  }
    55  
    56  func (s *SwiftHTTPSuite) sendRequest(c *gc.C, method, path string, body []byte,
    57  	expectedStatusCode int) (resp *http.Response) {
    58  	return s.sendRequestWithParams(c, method, path, nil, body, expectedStatusCode)
    59  }
    60  
    61  func (s *SwiftHTTPSuite) sendRequestWithParams(c *gc.C, method, path string, params map[string]string, body []byte,
    62  	expectedStatusCode int) (resp *http.Response) {
    63  	var req *http.Request
    64  	var err error
    65  	URL := s.service.endpointURL(path)
    66  	if len(params) > 0 {
    67  		urlParams := make(url.Values, len(params))
    68  		for k, v := range params {
    69  			urlParams.Set(k, v)
    70  		}
    71  		URL += "?" + urlParams.Encode()
    72  	}
    73  	if body != nil {
    74  		req, err = http.NewRequest(method, URL, bytes.NewBuffer(body))
    75  	} else {
    76  		req, err = http.NewRequest(method, URL, nil)
    77  	}
    78  	c.Assert(err, gc.IsNil)
    79  	if s.token != "" {
    80  		req.Header.Add("X-Auth-Token", s.token)
    81  	}
    82  	client := http.DefaultClient
    83  	resp, err = client.Do(req)
    84  	c.Assert(err, gc.IsNil)
    85  	c.Assert(resp.StatusCode, gc.Equals, expectedStatusCode)
    86  	return resp
    87  }
    88  
    89  func (s *SwiftHTTPSuite) ensureNotContainer(name string, c *gc.C) {
    90  	ok := s.service.HasContainer("test")
    91  	c.Assert(ok, gc.Equals, false)
    92  }
    93  
    94  func (s *SwiftHTTPSuite) ensureContainer(name string, c *gc.C) {
    95  	s.ensureNotContainer(name, c)
    96  	err := s.service.AddContainer("test")
    97  	c.Assert(err, gc.IsNil)
    98  }
    99  
   100  func (s *SwiftHTTPSuite) removeContainer(name string, c *gc.C) {
   101  	ok := s.service.HasContainer("test")
   102  	c.Assert(ok, gc.Equals, true)
   103  	err := s.service.RemoveContainer("test")
   104  	c.Assert(err, gc.IsNil)
   105  }
   106  
   107  func (s *SwiftHTTPSuite) ensureNotObject(container, object string, c *gc.C) {
   108  	_, err := s.service.GetObject(container, object)
   109  	c.Assert(err, gc.Not(gc.IsNil))
   110  }
   111  
   112  func (s *SwiftHTTPSuite) ensureObject(container, object string, data []byte, c *gc.C) {
   113  	s.ensureNotObject(container, object, c)
   114  	err := s.service.AddObject(container, object, data)
   115  	c.Assert(err, gc.IsNil)
   116  }
   117  
   118  func (s *SwiftHTTPSuite) ensureObjectData(container, object string, data []byte, c *gc.C) {
   119  	objdata, err := s.service.GetObject(container, object)
   120  	c.Assert(err, gc.IsNil)
   121  	c.Assert(objdata, gc.DeepEquals, data)
   122  }
   123  
   124  func (s *SwiftHTTPSuite) removeObject(container, object string, c *gc.C) {
   125  	err := s.service.RemoveObject(container, object)
   126  	c.Assert(err, gc.IsNil)
   127  	s.ensureNotObject(container, object, c)
   128  }
   129  
   130  func (s *SwiftHTTPSuite) TestPUTContainerMissingCreated(c *gc.C) {
   131  	s.ensureNotContainer("test", c)
   132  
   133  	s.sendRequest(c, "PUT", "test", nil, http.StatusCreated)
   134  
   135  	s.removeContainer("test", c)
   136  }
   137  
   138  func (s *SwiftHTTPSuite) TestPUTContainerExistsAccepted(c *gc.C) {
   139  	s.ensureContainer("test", c)
   140  
   141  	s.sendRequest(c, "PUT", "test", nil, http.StatusAccepted)
   142  
   143  	s.removeContainer("test", c)
   144  }
   145  
   146  func (s *SwiftHTTPSuite) TestGETContainerMissingNotFound(c *gc.C) {
   147  	s.ensureNotContainer("test", c)
   148  
   149  	s.sendRequest(c, "GET", "test", nil, http.StatusNotFound)
   150  
   151  	s.ensureNotContainer("test", c)
   152  }
   153  
   154  func (s *SwiftHTTPSuite) TestGETContainerExistsOK(c *gc.C) {
   155  	s.ensureContainer("test", c)
   156  	data := []byte("test data")
   157  	s.ensureObject("test", "obj", data, c)
   158  
   159  	resp := s.sendRequest(c, "GET", "test", nil, http.StatusOK)
   160  
   161  	defer resp.Body.Close()
   162  	body, err := ioutil.ReadAll(resp.Body)
   163  	c.Assert(err, gc.IsNil)
   164  	var containerData []swift.ContainerContents
   165  	err = json.Unmarshal(body, &containerData)
   166  	c.Assert(err, gc.IsNil)
   167  	c.Assert(len(containerData), gc.Equals, 1)
   168  	c.Assert(containerData[0].Name, gc.Equals, "obj")
   169  
   170  	s.removeContainer("test", c)
   171  }
   172  
   173  func (s *SwiftHTTPSuite) TestGETContainerWithPrefix(c *gc.C) {
   174  	s.ensureContainer("test", c)
   175  	data := []byte("test data")
   176  	s.ensureObject("test", "foo", data, c)
   177  	s.ensureObject("test", "foobar", data, c)
   178  
   179  	resp := s.sendRequestWithParams(c, "GET", "test", map[string]string{"prefix": "foob"}, nil, http.StatusOK)
   180  
   181  	defer resp.Body.Close()
   182  	body, err := ioutil.ReadAll(resp.Body)
   183  	c.Assert(err, gc.IsNil)
   184  	var containerData []swift.ContainerContents
   185  	err = json.Unmarshal(body, &containerData)
   186  	c.Assert(err, gc.IsNil)
   187  	c.Assert(len(containerData), gc.Equals, 1)
   188  	c.Assert(containerData[0].Name, gc.Equals, "foobar")
   189  
   190  	s.removeContainer("test", c)
   191  }
   192  
   193  func (s *SwiftHTTPSuite) TestDELETEContainerMissingNotFound(c *gc.C) {
   194  	s.ensureNotContainer("test", c)
   195  
   196  	s.sendRequest(c, "DELETE", "test", nil, http.StatusNotFound)
   197  }
   198  
   199  func (s *SwiftHTTPSuite) TestDELETEContainerExistsNoContent(c *gc.C) {
   200  	s.ensureContainer("test", c)
   201  
   202  	s.sendRequest(c, "DELETE", "test", nil, http.StatusNoContent)
   203  
   204  	s.ensureNotContainer("test", c)
   205  }
   206  
   207  func (s *SwiftHTTPSuite) TestPUTObjectMissingCreated(c *gc.C) {
   208  	s.ensureContainer("test", c)
   209  	s.ensureNotObject("test", "obj", c)
   210  
   211  	data := []byte("test data")
   212  	s.sendRequest(c, "PUT", "test/obj", data, http.StatusCreated)
   213  
   214  	s.ensureObjectData("test", "obj", data, c)
   215  	s.removeContainer("test", c)
   216  }
   217  
   218  func (s *SwiftHTTPSuite) TestPUTObjectExistsCreated(c *gc.C) {
   219  	data := []byte("test data")
   220  	s.ensureContainer("test", c)
   221  	s.ensureObject("test", "obj", data, c)
   222  
   223  	newdata := []byte("new test data")
   224  	s.sendRequest(c, "PUT", "test/obj", newdata, http.StatusCreated)
   225  
   226  	s.ensureObjectData("test", "obj", newdata, c)
   227  	s.removeContainer("test", c)
   228  }
   229  
   230  func (s *SwiftHTTPSuite) TestPUTObjectContainerMissingNotFound(c *gc.C) {
   231  	s.ensureNotContainer("test", c)
   232  
   233  	data := []byte("test data")
   234  	s.sendRequest(c, "PUT", "test/obj", data, http.StatusNotFound)
   235  
   236  	s.ensureNotContainer("test", c)
   237  }
   238  
   239  func (s *SwiftHTTPSuite) TestGETObjectMissingNotFound(c *gc.C) {
   240  	s.ensureContainer("test", c)
   241  	s.ensureNotObject("test", "obj", c)
   242  
   243  	s.sendRequest(c, "GET", "test/obj", nil, http.StatusNotFound)
   244  
   245  	s.removeContainer("test", c)
   246  }
   247  
   248  func (s *SwiftHTTPSuite) TestGETObjectContainerMissingNotFound(c *gc.C) {
   249  	s.ensureNotContainer("test", c)
   250  
   251  	s.sendRequest(c, "GET", "test/obj", nil, http.StatusNotFound)
   252  
   253  	s.ensureNotContainer("test", c)
   254  }
   255  
   256  func (s *SwiftHTTPSuite) TestGETObjectExistsOK(c *gc.C) {
   257  	data := []byte("test data")
   258  	s.ensureContainer("test", c)
   259  	s.ensureObject("test", "obj", data, c)
   260  
   261  	resp := s.sendRequest(c, "GET", "test/obj", nil, http.StatusOK)
   262  
   263  	s.ensureObjectData("test", "obj", data, c)
   264  
   265  	defer resp.Body.Close()
   266  	body, err := ioutil.ReadAll(resp.Body)
   267  	c.Assert(err, gc.IsNil)
   268  	c.Assert(body, gc.DeepEquals, data)
   269  
   270  	s.removeContainer("test", c)
   271  }
   272  
   273  func (s *SwiftHTTPSuite) TestDELETEObjectMissingNotFound(c *gc.C) {
   274  	s.ensureContainer("test", c)
   275  	s.ensureNotObject("test", "obj", c)
   276  
   277  	s.sendRequest(c, "DELETE", "test/obj", nil, http.StatusNotFound)
   278  
   279  	s.removeContainer("test", c)
   280  }
   281  
   282  func (s *SwiftHTTPSuite) TestDELETEObjectContainerMissingNotFound(c *gc.C) {
   283  	s.ensureNotContainer("test", c)
   284  
   285  	s.sendRequest(c, "DELETE", "test/obj", nil, http.StatusNotFound)
   286  
   287  	s.ensureNotContainer("test", c)
   288  }
   289  
   290  func (s *SwiftHTTPSuite) TestDELETEObjectExistsNoContent(c *gc.C) {
   291  	data := []byte("test data")
   292  	s.ensureContainer("test", c)
   293  	s.ensureObject("test", "obj", data, c)
   294  
   295  	s.sendRequest(c, "DELETE", "test/obj", nil, http.StatusNoContent)
   296  
   297  	s.removeContainer("test", c)
   298  }
   299  
   300  func (s *SwiftHTTPSuite) TestHEADContainerExistsOK(c *gc.C) {
   301  	s.ensureContainer("test", c)
   302  	data := []byte("test data")
   303  	s.ensureObject("test", "obj", data, c)
   304  
   305  	resp := s.sendRequest(c, "HEAD", "test", nil, http.StatusOK)
   306  	c.Assert(resp.Header.Get("Date"), gc.Not(gc.Equals), "")
   307  
   308  	defer resp.Body.Close()
   309  	body, err := ioutil.ReadAll(resp.Body)
   310  	c.Assert(err, gc.IsNil)
   311  	c.Assert(body, gc.DeepEquals, []byte{})
   312  	s.removeContainer("test", c)
   313  }
   314  
   315  func (s *SwiftHTTPSuite) TestHEADContainerMissingNotFound(c *gc.C) {
   316  	s.ensureNotContainer("test", c)
   317  
   318  	s.sendRequest(c, "HEAD", "test", nil, http.StatusNotFound)
   319  
   320  	s.ensureNotContainer("test", c)
   321  }
   322  
   323  func (s *SwiftHTTPSuite) TestHEADObjectExistsOK(c *gc.C) {
   324  	data := []byte("test data")
   325  	s.ensureContainer("test", c)
   326  	s.ensureObject("test", "obj", data, c)
   327  
   328  	resp := s.sendRequest(c, "HEAD", "test/obj", nil, http.StatusOK)
   329  
   330  	s.ensureObjectData("test", "obj", data, c)
   331  	c.Assert(resp.Header.Get("Date"), gc.Not(gc.Equals), "")
   332  
   333  	defer resp.Body.Close()
   334  	body, err := ioutil.ReadAll(resp.Body)
   335  	c.Assert(err, gc.IsNil)
   336  	c.Assert(body, gc.DeepEquals, []byte{})
   337  
   338  	s.removeContainer("test", c)
   339  }
   340  
   341  func (s *SwiftHTTPSuite) TestHEADObjectMissingNotFound(c *gc.C) {
   342  	s.ensureContainer("test", c)
   343  	s.ensureNotObject("test", "obj", c)
   344  
   345  	s.sendRequest(c, "HEAD", "test/obj", nil, http.StatusNotFound)
   346  
   347  	s.removeContainer("test", c)
   348  }
   349  
   350  func (s *SwiftHTTPSuite) TestUnauthorizedFails(c *gc.C) {
   351  	oldtoken := s.token
   352  	defer func() {
   353  		s.token = oldtoken
   354  	}()
   355  	// TODO(wallyworld) - 2013-02-11 bug=1121682
   356  	// until ACLs are supported, empty tokens are assumed to be used when we need to access a public container.
   357  	// token = ""
   358  	// s.sendRequest(c, "GET", "test", nil, http.StatusUnauthorized)
   359  
   360  	s.token = "invalid"
   361  	s.sendRequest(c, "PUT", "test", nil, http.StatusUnauthorized)
   362  
   363  	s.sendRequest(c, "DELETE", "test", nil, http.StatusUnauthorized)
   364  }
   365  
   366  func (s *SwiftHTTPSSuite) SetUpSuite(c *gc.C) {
   367  	s.HTTPSuite.SetUpSuite(c)
   368  	identityDouble := identityservice.NewUserPass()
   369  	userInfo := identityDouble.AddUser("fred", "secret", "tenant", "default")
   370  	s.token = userInfo.Token
   371  	c.Assert(s.Server.URL[:8], gc.Equals, "https://")
   372  	s.service = New(s.Server.URL, versionPath, userInfo.TenantId, region, identityDouble, nil)
   373  }
   374  
   375  func (s *SwiftHTTPSSuite) TearDownSuite(c *gc.C) {
   376  	s.HTTPSuite.TearDownSuite(c)
   377  }
   378  
   379  func (s *SwiftHTTPSSuite) SetUpTest(c *gc.C) {
   380  	s.HTTPSuite.SetUpTest(c)
   381  	s.service.SetupHTTP(s.Mux)
   382  }
   383  
   384  func (s *SwiftHTTPSSuite) TearDownTest(c *gc.C) {
   385  	s.HTTPSuite.TearDownTest(c)
   386  }
   387  
   388  func (s *SwiftHTTPSSuite) TestHasHTTPSServiceURL(c *gc.C) {
   389  	endpoints := s.service.Endpoints()
   390  	c.Assert(endpoints[0].PublicURL[:8], gc.Equals, "https://")
   391  }