Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 

428 righe
12 KiB

  1. package s3_test
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "net/http"
  6. "testing"
  7. "time"
  8. "github.com/goamz/goamz/aws"
  9. "github.com/goamz/goamz/s3"
  10. "github.com/goamz/goamz/testutil"
  11. . "gopkg.in/check.v1"
  12. )
  13. func Test(t *testing.T) {
  14. TestingT(t)
  15. }
  16. type S struct {
  17. s3 *s3.S3
  18. }
  19. var _ = Suite(&S{})
  20. var testServer = testutil.NewHTTPServer()
  21. func (s *S) SetUpSuite(c *C) {
  22. testServer.Start()
  23. auth := aws.Auth{AccessKey: "abc", SecretKey: "123"}
  24. s.s3 = s3.New(auth, aws.Region{Name: "faux-region-1", S3Endpoint: testServer.URL})
  25. }
  26. func (s *S) TearDownSuite(c *C) {
  27. s.s3.AttemptStrategy = s3.DefaultAttemptStrategy
  28. }
  29. func (s *S) SetUpTest(c *C) {
  30. s.s3.AttemptStrategy = aws.AttemptStrategy{
  31. Total: 300 * time.Millisecond,
  32. Delay: 100 * time.Millisecond,
  33. }
  34. }
  35. func (s *S) TearDownTest(c *C) {
  36. testServer.Flush()
  37. }
  38. func (s *S) DisableRetries() {
  39. s.s3.AttemptStrategy = aws.AttemptStrategy{}
  40. }
  41. // PutBucket docs: http://goo.gl/kBTCu
  42. func (s *S) TestPutBucket(c *C) {
  43. testServer.Response(200, nil, "")
  44. b := s.s3.Bucket("bucket")
  45. err := b.PutBucket(s3.Private)
  46. c.Assert(err, IsNil)
  47. req := testServer.WaitRequest()
  48. c.Assert(req.Method, Equals, "PUT")
  49. c.Assert(req.URL.Path, Equals, "/bucket/")
  50. c.Assert(req.Header["Date"], Not(Equals), "")
  51. }
  52. // Head docs: http://bit.ly/17K1ylI
  53. func (s *S) TestHead(c *C) {
  54. testServer.Response(200, nil, "content")
  55. b := s.s3.Bucket("bucket")
  56. resp, err := b.Head("name", nil)
  57. req := testServer.WaitRequest()
  58. c.Assert(req.Method, Equals, "HEAD")
  59. c.Assert(req.URL.Path, Equals, "/bucket/name")
  60. c.Assert(req.Header["Date"], Not(Equals), "")
  61. c.Assert(err, IsNil)
  62. c.Assert(resp.ContentLength, FitsTypeOf, int64(0))
  63. c.Assert(resp, FitsTypeOf, &http.Response{})
  64. }
  65. // DeleteBucket docs: http://goo.gl/GoBrY
  66. func (s *S) TestDelBucket(c *C) {
  67. testServer.Response(204, nil, "")
  68. b := s.s3.Bucket("bucket")
  69. err := b.DelBucket()
  70. c.Assert(err, IsNil)
  71. req := testServer.WaitRequest()
  72. c.Assert(req.Method, Equals, "DELETE")
  73. c.Assert(req.URL.Path, Equals, "/bucket/")
  74. c.Assert(req.Header["Date"], Not(Equals), "")
  75. }
  76. // GetObject docs: http://goo.gl/isCO7
  77. func (s *S) TestGet(c *C) {
  78. testServer.Response(200, nil, "content")
  79. b := s.s3.Bucket("bucket")
  80. data, err := b.Get("name")
  81. req := testServer.WaitRequest()
  82. c.Assert(req.Method, Equals, "GET")
  83. c.Assert(req.URL.Path, Equals, "/bucket/name")
  84. c.Assert(req.Header["Date"], Not(Equals), "")
  85. c.Assert(err, IsNil)
  86. c.Assert(string(data), Equals, "content")
  87. }
  88. func (s *S) TestURL(c *C) {
  89. testServer.Response(200, nil, "content")
  90. b := s.s3.Bucket("bucket")
  91. url := b.URL("name")
  92. r, err := http.Get(url)
  93. c.Assert(err, IsNil)
  94. data, err := ioutil.ReadAll(r.Body)
  95. r.Body.Close()
  96. c.Assert(err, IsNil)
  97. c.Assert(string(data), Equals, "content")
  98. req := testServer.WaitRequest()
  99. c.Assert(req.Method, Equals, "GET")
  100. c.Assert(req.URL.Path, Equals, "/bucket/name")
  101. }
  102. func (s *S) TestGetReader(c *C) {
  103. testServer.Response(200, nil, "content")
  104. b := s.s3.Bucket("bucket")
  105. rc, err := b.GetReader("name")
  106. c.Assert(err, IsNil)
  107. data, err := ioutil.ReadAll(rc)
  108. rc.Close()
  109. c.Assert(err, IsNil)
  110. c.Assert(string(data), Equals, "content")
  111. req := testServer.WaitRequest()
  112. c.Assert(req.Method, Equals, "GET")
  113. c.Assert(req.URL.Path, Equals, "/bucket/name")
  114. c.Assert(req.Header["Date"], Not(Equals), "")
  115. }
  116. func (s *S) TestGetNotFound(c *C) {
  117. for i := 0; i < 10; i++ {
  118. testServer.Response(404, nil, GetObjectErrorDump)
  119. }
  120. b := s.s3.Bucket("non-existent-bucket")
  121. data, err := b.Get("non-existent")
  122. req := testServer.WaitRequest()
  123. c.Assert(req.Method, Equals, "GET")
  124. c.Assert(req.URL.Path, Equals, "/non-existent-bucket/non-existent")
  125. c.Assert(req.Header["Date"], Not(Equals), "")
  126. s3err, _ := err.(*s3.Error)
  127. c.Assert(s3err, NotNil)
  128. c.Assert(s3err.StatusCode, Equals, 404)
  129. c.Assert(s3err.BucketName, Equals, "non-existent-bucket")
  130. c.Assert(s3err.RequestId, Equals, "3F1B667FAD71C3D8")
  131. c.Assert(s3err.HostId, Equals, "L4ee/zrm1irFXY5F45fKXIRdOf9ktsKY/8TDVawuMK2jWRb1RF84i1uBzkdNqS5D")
  132. c.Assert(s3err.Code, Equals, "NoSuchBucket")
  133. c.Assert(s3err.Message, Equals, "The specified bucket does not exist")
  134. c.Assert(s3err.Error(), Equals, "The specified bucket does not exist")
  135. c.Assert(data, IsNil)
  136. }
  137. // PutObject docs: http://goo.gl/FEBPD
  138. func (s *S) TestPutObject(c *C) {
  139. testServer.Response(200, nil, "")
  140. b := s.s3.Bucket("bucket")
  141. err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{})
  142. c.Assert(err, IsNil)
  143. req := testServer.WaitRequest()
  144. c.Assert(req.Method, Equals, "PUT")
  145. c.Assert(req.URL.Path, Equals, "/bucket/name")
  146. c.Assert(req.Header["Date"], Not(DeepEquals), []string{""})
  147. c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"})
  148. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"})
  149. //c.Assert(req.Header["Content-MD5"], DeepEquals, "...")
  150. c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"})
  151. }
  152. func (s *S) TestPutObjectReadTimeout(c *C) {
  153. s.s3.ReadTimeout = 50 * time.Millisecond
  154. defer func() {
  155. s.s3.ReadTimeout = 0
  156. }()
  157. b := s.s3.Bucket("bucket")
  158. err := b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{})
  159. // Make sure that we get a timeout error.
  160. c.Assert(err, NotNil)
  161. // Set the response after the request times out so that the next request will work.
  162. testServer.Response(200, nil, "")
  163. // This time set the response within our timeout period so that we expect the call
  164. // to return successfully.
  165. go func() {
  166. time.Sleep(25 * time.Millisecond)
  167. testServer.Response(200, nil, "")
  168. }()
  169. err = b.Put("name", []byte("content"), "content-type", s3.Private, s3.Options{})
  170. c.Assert(err, IsNil)
  171. }
  172. func (s *S) TestPutObjectHeader(c *C) {
  173. testServer.Response(200, nil, "")
  174. b := s.s3.Bucket("bucket")
  175. err := b.PutHeader(
  176. "name",
  177. []byte("content"),
  178. map[string][]string{"Content-Type": {"content-type"}},
  179. s3.Private,
  180. )
  181. c.Assert(err, IsNil)
  182. req := testServer.WaitRequest()
  183. c.Assert(req.Method, Equals, "PUT")
  184. c.Assert(req.URL.Path, Equals, "/bucket/name")
  185. c.Assert(req.Header["Date"], Not(DeepEquals), []string{""})
  186. c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"})
  187. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"})
  188. //c.Assert(req.Header["Content-MD5"], DeepEquals, "...")
  189. c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"})
  190. }
  191. func (s *S) TestPutReader(c *C) {
  192. testServer.Response(200, nil, "")
  193. b := s.s3.Bucket("bucket")
  194. buf := bytes.NewBufferString("content")
  195. err := b.PutReader("name", buf, int64(buf.Len()), "content-type", s3.Private, s3.Options{})
  196. c.Assert(err, IsNil)
  197. req := testServer.WaitRequest()
  198. c.Assert(req.Method, Equals, "PUT")
  199. c.Assert(req.URL.Path, Equals, "/bucket/name")
  200. c.Assert(req.Header["Date"], Not(DeepEquals), []string{""})
  201. c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"})
  202. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"})
  203. //c.Assert(req.Header["Content-MD5"], Equals, "...")
  204. c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"})
  205. }
  206. func (s *S) TestPutReaderHeader(c *C) {
  207. testServer.Response(200, nil, "")
  208. b := s.s3.Bucket("bucket")
  209. buf := bytes.NewBufferString("content")
  210. err := b.PutReaderHeader(
  211. "name",
  212. buf,
  213. int64(buf.Len()),
  214. map[string][]string{"Content-Type": {"content-type"}},
  215. s3.Private,
  216. )
  217. c.Assert(err, IsNil)
  218. req := testServer.WaitRequest()
  219. c.Assert(req.Method, Equals, "PUT")
  220. c.Assert(req.URL.Path, Equals, "/bucket/name")
  221. c.Assert(req.Header["Date"], Not(DeepEquals), []string{""})
  222. c.Assert(req.Header["Content-Type"], DeepEquals, []string{"content-type"})
  223. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"7"})
  224. //c.Assert(req.Header["Content-MD5"], Equals, "...")
  225. c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"})
  226. }
  227. // DelObject docs: http://goo.gl/APeTt
  228. func (s *S) TestDelObject(c *C) {
  229. testServer.Response(200, nil, "")
  230. b := s.s3.Bucket("bucket")
  231. err := b.Del("name")
  232. c.Assert(err, IsNil)
  233. req := testServer.WaitRequest()
  234. c.Assert(req.Method, Equals, "DELETE")
  235. c.Assert(req.URL.Path, Equals, "/bucket/name")
  236. c.Assert(req.Header["Date"], Not(Equals), "")
  237. }
  238. func (s *S) TestDelMultiObjects(c *C) {
  239. testServer.Response(200, nil, "")
  240. b := s.s3.Bucket("bucket")
  241. objects := []s3.Object{s3.Object{Key: "test"}}
  242. err := b.DelMulti(s3.Delete{
  243. Quiet: false,
  244. Objects: objects,
  245. })
  246. c.Assert(err, IsNil)
  247. req := testServer.WaitRequest()
  248. c.Assert(req.Method, Equals, "POST")
  249. c.Assert(req.URL.RawQuery, Equals, "delete=")
  250. c.Assert(req.Header["Date"], Not(Equals), "")
  251. c.Assert(req.Header["Content-MD5"], Not(Equals), "")
  252. c.Assert(req.Header["Content-Type"], Not(Equals), "")
  253. c.Assert(req.ContentLength, Not(Equals), "")
  254. }
  255. // Bucket List Objects docs: http://goo.gl/YjQTc
  256. func (s *S) TestList(c *C) {
  257. testServer.Response(200, nil, GetListResultDump1)
  258. b := s.s3.Bucket("quotes")
  259. data, err := b.List("N", "", "", 0)
  260. c.Assert(err, IsNil)
  261. req := testServer.WaitRequest()
  262. c.Assert(req.Method, Equals, "GET")
  263. c.Assert(req.URL.Path, Equals, "/quotes/")
  264. c.Assert(req.Header["Date"], Not(Equals), "")
  265. c.Assert(req.Form["prefix"], DeepEquals, []string{"N"})
  266. c.Assert(req.Form["delimiter"], DeepEquals, []string{""})
  267. c.Assert(req.Form["marker"], DeepEquals, []string{""})
  268. c.Assert(req.Form["max-keys"], DeepEquals, []string(nil))
  269. c.Assert(data.Name, Equals, "quotes")
  270. c.Assert(data.Prefix, Equals, "N")
  271. c.Assert(data.IsTruncated, Equals, false)
  272. c.Assert(len(data.Contents), Equals, 2)
  273. c.Assert(data.Contents[0].Key, Equals, "Nelson")
  274. c.Assert(data.Contents[0].LastModified, Equals, "2006-01-01T12:00:00.000Z")
  275. c.Assert(data.Contents[0].ETag, Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`)
  276. c.Assert(data.Contents[0].Size, Equals, int64(5))
  277. c.Assert(data.Contents[0].StorageClass, Equals, "STANDARD")
  278. c.Assert(data.Contents[0].Owner.ID, Equals, "bcaf161ca5fb16fd081034f")
  279. c.Assert(data.Contents[0].Owner.DisplayName, Equals, "webfile")
  280. c.Assert(data.Contents[1].Key, Equals, "Neo")
  281. c.Assert(data.Contents[1].LastModified, Equals, "2006-01-01T12:00:00.000Z")
  282. c.Assert(data.Contents[1].ETag, Equals, `"828ef3fdfa96f00ad9f27c383fc9ac7f"`)
  283. c.Assert(data.Contents[1].Size, Equals, int64(4))
  284. c.Assert(data.Contents[1].StorageClass, Equals, "STANDARD")
  285. c.Assert(data.Contents[1].Owner.ID, Equals, "bcaf1ffd86a5fb16fd081034f")
  286. c.Assert(data.Contents[1].Owner.DisplayName, Equals, "webfile")
  287. }
  288. func (s *S) TestListWithDelimiter(c *C) {
  289. testServer.Response(200, nil, GetListResultDump2)
  290. b := s.s3.Bucket("quotes")
  291. data, err := b.List("photos/2006/", "/", "some-marker", 1000)
  292. c.Assert(err, IsNil)
  293. req := testServer.WaitRequest()
  294. c.Assert(req.Method, Equals, "GET")
  295. c.Assert(req.URL.Path, Equals, "/quotes/")
  296. c.Assert(req.Header["Date"], Not(Equals), "")
  297. c.Assert(req.Form["prefix"], DeepEquals, []string{"photos/2006/"})
  298. c.Assert(req.Form["delimiter"], DeepEquals, []string{"/"})
  299. c.Assert(req.Form["marker"], DeepEquals, []string{"some-marker"})
  300. c.Assert(req.Form["max-keys"], DeepEquals, []string{"1000"})
  301. c.Assert(data.Name, Equals, "example-bucket")
  302. c.Assert(data.Prefix, Equals, "photos/2006/")
  303. c.Assert(data.Delimiter, Equals, "/")
  304. c.Assert(data.Marker, Equals, "some-marker")
  305. c.Assert(data.IsTruncated, Equals, false)
  306. c.Assert(len(data.Contents), Equals, 0)
  307. c.Assert(data.CommonPrefixes, DeepEquals, []string{"photos/2006/feb/", "photos/2006/jan/"})
  308. }
  309. func (s *S) TestExists(c *C) {
  310. testServer.Response(200, nil, "")
  311. b := s.s3.Bucket("bucket")
  312. result, err := b.Exists("name")
  313. req := testServer.WaitRequest()
  314. c.Assert(req.Method, Equals, "HEAD")
  315. c.Assert(err, IsNil)
  316. c.Assert(result, Equals, true)
  317. }
  318. func (s *S) TestExistsNotFound404(c *C) {
  319. testServer.Response(404, nil, "")
  320. b := s.s3.Bucket("bucket")
  321. result, err := b.Exists("name")
  322. req := testServer.WaitRequest()
  323. c.Assert(req.Method, Equals, "HEAD")
  324. c.Assert(err, IsNil)
  325. c.Assert(result, Equals, false)
  326. }
  327. func (s *S) TestExistsNotFound403(c *C) {
  328. testServer.Response(403, nil, "")
  329. b := s.s3.Bucket("bucket")
  330. result, err := b.Exists("name")
  331. req := testServer.WaitRequest()
  332. c.Assert(req.Method, Equals, "HEAD")
  333. c.Assert(err, IsNil)
  334. c.Assert(result, Equals, false)
  335. }