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 }