25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

374 satır
12 KiB

  1. package s3_test
  2. import (
  3. "encoding/xml"
  4. "io"
  5. "io/ioutil"
  6. "strings"
  7. "github.com/goamz/goamz/s3"
  8. . "gopkg.in/check.v1"
  9. )
  10. func (s *S) TestInitMulti(c *C) {
  11. testServer.Response(200, nil, InitMultiResultDump)
  12. b := s.s3.Bucket("sample")
  13. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  14. c.Assert(err, IsNil)
  15. req := testServer.WaitRequest()
  16. c.Assert(req.Method, Equals, "POST")
  17. c.Assert(req.URL.Path, Equals, "/sample/multi")
  18. c.Assert(req.Header["Content-Type"], DeepEquals, []string{"text/plain"})
  19. c.Assert(req.Header["X-Amz-Acl"], DeepEquals, []string{"private"})
  20. c.Assert(req.Form["uploads"], DeepEquals, []string{""})
  21. c.Assert(multi.UploadId, Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  22. }
  23. func (s *S) TestMultiNoPreviousUpload(c *C) {
  24. // Don't retry the NoSuchUpload error.
  25. s.DisableRetries()
  26. testServer.Response(404, nil, NoSuchUploadErrorDump)
  27. testServer.Response(200, nil, InitMultiResultDump)
  28. b := s.s3.Bucket("sample")
  29. multi, err := b.Multi("multi", "text/plain", s3.Private)
  30. c.Assert(err, IsNil)
  31. req := testServer.WaitRequest()
  32. c.Assert(req.Method, Equals, "GET")
  33. c.Assert(req.URL.Path, Equals, "/sample/")
  34. c.Assert(req.Form["uploads"], DeepEquals, []string{""})
  35. c.Assert(req.Form["prefix"], DeepEquals, []string{"multi"})
  36. req = testServer.WaitRequest()
  37. c.Assert(req.Method, Equals, "POST")
  38. c.Assert(req.URL.Path, Equals, "/sample/multi")
  39. c.Assert(req.Form["uploads"], DeepEquals, []string{""})
  40. c.Assert(multi.UploadId, Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  41. }
  42. func (s *S) TestMultiReturnOld(c *C) {
  43. testServer.Response(200, nil, ListMultiResultDump)
  44. b := s.s3.Bucket("sample")
  45. multi, err := b.Multi("multi1", "text/plain", s3.Private)
  46. c.Assert(err, IsNil)
  47. c.Assert(multi.Key, Equals, "multi1")
  48. c.Assert(multi.UploadId, Equals, "iUVug89pPvSswrikD")
  49. req := testServer.WaitRequest()
  50. c.Assert(req.Method, Equals, "GET")
  51. c.Assert(req.URL.Path, Equals, "/sample/")
  52. c.Assert(req.Form["uploads"], DeepEquals, []string{""})
  53. c.Assert(req.Form["prefix"], DeepEquals, []string{"multi1"})
  54. }
  55. func (s *S) TestListParts(c *C) {
  56. testServer.Response(200, nil, InitMultiResultDump)
  57. testServer.Response(200, nil, ListPartsResultDump1)
  58. testServer.Response(404, nil, NoSuchUploadErrorDump) // :-(
  59. testServer.Response(200, nil, ListPartsResultDump2)
  60. b := s.s3.Bucket("sample")
  61. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  62. c.Assert(err, IsNil)
  63. parts, err := multi.ListParts()
  64. c.Assert(err, IsNil)
  65. c.Assert(parts, HasLen, 3)
  66. c.Assert(parts[0].N, Equals, 1)
  67. c.Assert(parts[0].Size, Equals, int64(5))
  68. c.Assert(parts[0].ETag, Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`)
  69. c.Assert(parts[1].N, Equals, 2)
  70. c.Assert(parts[1].Size, Equals, int64(5))
  71. c.Assert(parts[1].ETag, Equals, `"d067a0fa9dc61a6e7195ca99696b5a89"`)
  72. c.Assert(parts[2].N, Equals, 3)
  73. c.Assert(parts[2].Size, Equals, int64(5))
  74. c.Assert(parts[2].ETag, Equals, `"49dcd91231f801159e893fb5c6674985"`)
  75. testServer.WaitRequest()
  76. req := testServer.WaitRequest()
  77. c.Assert(req.Method, Equals, "GET")
  78. c.Assert(req.URL.Path, Equals, "/sample/multi")
  79. c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  80. c.Assert(req.Form["max-parts"], DeepEquals, []string{"1000"})
  81. testServer.WaitRequest() // The internal error.
  82. req = testServer.WaitRequest()
  83. c.Assert(req.Method, Equals, "GET")
  84. c.Assert(req.URL.Path, Equals, "/sample/multi")
  85. c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  86. c.Assert(req.Form["max-parts"], DeepEquals, []string{"1000"})
  87. c.Assert(req.Form["part-number-marker"], DeepEquals, []string{"2"})
  88. }
  89. func (s *S) TestPutPart(c *C) {
  90. headers := map[string]string{
  91. "ETag": `"26f90efd10d614f100252ff56d88dad8"`,
  92. }
  93. testServer.Response(200, nil, InitMultiResultDump)
  94. testServer.Response(200, headers, "")
  95. b := s.s3.Bucket("sample")
  96. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  97. c.Assert(err, IsNil)
  98. part, err := multi.PutPart(1, strings.NewReader("<part 1>"))
  99. c.Assert(err, IsNil)
  100. c.Assert(part.N, Equals, 1)
  101. c.Assert(part.Size, Equals, int64(8))
  102. c.Assert(part.ETag, Equals, headers["ETag"])
  103. testServer.WaitRequest()
  104. req := testServer.WaitRequest()
  105. c.Assert(req.Method, Equals, "PUT")
  106. c.Assert(req.URL.Path, Equals, "/sample/multi")
  107. c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  108. c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"})
  109. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"8"})
  110. c.Assert(req.Header["Content-Md5"], DeepEquals, []string{"JvkO/RDWFPEAJS/1bYja2A=="})
  111. }
  112. func readAll(r io.Reader) string {
  113. data, err := ioutil.ReadAll(r)
  114. if err != nil {
  115. panic(err)
  116. }
  117. return string(data)
  118. }
  119. func (s *S) TestPutAllNoPreviousUpload(c *C) {
  120. // Don't retry the NoSuchUpload error.
  121. s.DisableRetries()
  122. etag1 := map[string]string{"ETag": `"etag1"`}
  123. etag2 := map[string]string{"ETag": `"etag2"`}
  124. etag3 := map[string]string{"ETag": `"etag3"`}
  125. testServer.Response(200, nil, InitMultiResultDump)
  126. testServer.Response(404, nil, NoSuchUploadErrorDump)
  127. testServer.Response(200, etag1, "")
  128. testServer.Response(200, etag2, "")
  129. testServer.Response(200, etag3, "")
  130. b := s.s3.Bucket("sample")
  131. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  132. c.Assert(err, IsNil)
  133. parts, err := multi.PutAll(strings.NewReader("part1part2last"), 5)
  134. c.Assert(parts, HasLen, 3)
  135. c.Assert(parts[0].ETag, Equals, `"etag1"`)
  136. c.Assert(parts[1].ETag, Equals, `"etag2"`)
  137. c.Assert(parts[2].ETag, Equals, `"etag3"`)
  138. c.Assert(err, IsNil)
  139. // Init
  140. testServer.WaitRequest()
  141. // List old parts. Won't find anything.
  142. req := testServer.WaitRequest()
  143. c.Assert(req.Method, Equals, "GET")
  144. c.Assert(req.URL.Path, Equals, "/sample/multi")
  145. // Send part 1.
  146. req = testServer.WaitRequest()
  147. c.Assert(req.Method, Equals, "PUT")
  148. c.Assert(req.URL.Path, Equals, "/sample/multi")
  149. c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"})
  150. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"})
  151. c.Assert(readAll(req.Body), Equals, "part1")
  152. // Send part 2.
  153. req = testServer.WaitRequest()
  154. c.Assert(req.Method, Equals, "PUT")
  155. c.Assert(req.URL.Path, Equals, "/sample/multi")
  156. c.Assert(req.Form["partNumber"], DeepEquals, []string{"2"})
  157. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"})
  158. c.Assert(readAll(req.Body), Equals, "part2")
  159. // Send part 3 with shorter body.
  160. req = testServer.WaitRequest()
  161. c.Assert(req.Method, Equals, "PUT")
  162. c.Assert(req.URL.Path, Equals, "/sample/multi")
  163. c.Assert(req.Form["partNumber"], DeepEquals, []string{"3"})
  164. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"4"})
  165. c.Assert(readAll(req.Body), Equals, "last")
  166. }
  167. func (s *S) TestPutAllZeroSizeFile(c *C) {
  168. // Don't retry the NoSuchUpload error.
  169. s.DisableRetries()
  170. etag1 := map[string]string{"ETag": `"etag1"`}
  171. testServer.Response(200, nil, InitMultiResultDump)
  172. testServer.Response(404, nil, NoSuchUploadErrorDump)
  173. testServer.Response(200, etag1, "")
  174. b := s.s3.Bucket("sample")
  175. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  176. c.Assert(err, IsNil)
  177. // Must send at least one part, so that completing it will work.
  178. parts, err := multi.PutAll(strings.NewReader(""), 5)
  179. c.Assert(parts, HasLen, 1)
  180. c.Assert(parts[0].ETag, Equals, `"etag1"`)
  181. c.Assert(err, IsNil)
  182. // Init
  183. testServer.WaitRequest()
  184. // List old parts. Won't find anything.
  185. req := testServer.WaitRequest()
  186. c.Assert(req.Method, Equals, "GET")
  187. c.Assert(req.URL.Path, Equals, "/sample/multi")
  188. // Send empty part.
  189. req = testServer.WaitRequest()
  190. c.Assert(req.Method, Equals, "PUT")
  191. c.Assert(req.URL.Path, Equals, "/sample/multi")
  192. c.Assert(req.Form["partNumber"], DeepEquals, []string{"1"})
  193. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"0"})
  194. c.Assert(readAll(req.Body), Equals, "")
  195. }
  196. func (s *S) TestPutAllResume(c *C) {
  197. etag2 := map[string]string{"ETag": `"etag2"`}
  198. testServer.Response(200, nil, InitMultiResultDump)
  199. testServer.Response(200, nil, ListPartsResultDump1)
  200. testServer.Response(200, nil, ListPartsResultDump2)
  201. testServer.Response(200, etag2, "")
  202. b := s.s3.Bucket("sample")
  203. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  204. c.Assert(err, IsNil)
  205. // "part1" and "part3" match the checksums in ResultDump1.
  206. // The middle one is a mismatch (it refers to "part2").
  207. parts, err := multi.PutAll(strings.NewReader("part1partXpart3"), 5)
  208. c.Assert(parts, HasLen, 3)
  209. c.Assert(parts[0].N, Equals, 1)
  210. c.Assert(parts[0].Size, Equals, int64(5))
  211. c.Assert(parts[0].ETag, Equals, `"ffc88b4ca90a355f8ddba6b2c3b2af5c"`)
  212. c.Assert(parts[1].N, Equals, 2)
  213. c.Assert(parts[1].Size, Equals, int64(5))
  214. c.Assert(parts[1].ETag, Equals, `"etag2"`)
  215. c.Assert(parts[2].N, Equals, 3)
  216. c.Assert(parts[2].Size, Equals, int64(5))
  217. c.Assert(parts[2].ETag, Equals, `"49dcd91231f801159e893fb5c6674985"`)
  218. c.Assert(err, IsNil)
  219. // Init
  220. testServer.WaitRequest()
  221. // List old parts, broken in two requests.
  222. for i := 0; i < 2; i++ {
  223. req := testServer.WaitRequest()
  224. c.Assert(req.Method, Equals, "GET")
  225. c.Assert(req.URL.Path, Equals, "/sample/multi")
  226. }
  227. // Send part 2, as it didn't match the checksum.
  228. req := testServer.WaitRequest()
  229. c.Assert(req.Method, Equals, "PUT")
  230. c.Assert(req.URL.Path, Equals, "/sample/multi")
  231. c.Assert(req.Form["partNumber"], DeepEquals, []string{"2"})
  232. c.Assert(req.Header["Content-Length"], DeepEquals, []string{"5"})
  233. c.Assert(readAll(req.Body), Equals, "partX")
  234. }
  235. func (s *S) TestMultiComplete(c *C) {
  236. testServer.Response(200, nil, InitMultiResultDump)
  237. // Note the 200 response. Completing will hold the connection on some
  238. // kind of long poll, and may return a late error even after a 200.
  239. testServer.Response(200, nil, InternalErrorDump)
  240. testServer.Response(200, nil, "")
  241. b := s.s3.Bucket("sample")
  242. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  243. c.Assert(err, IsNil)
  244. err = multi.Complete([]s3.Part{{2, `"ETag2"`, 32}, {1, `"ETag1"`, 64}})
  245. // returns InternalErrorDump in the payload, which should manifest as
  246. // an error.
  247. c.Assert(err, NotNil)
  248. testServer.WaitRequest()
  249. req := testServer.WaitRequest()
  250. c.Assert(req.Method, Equals, "POST")
  251. c.Assert(req.URL.Path, Equals, "/sample/multi")
  252. c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  253. var payload struct {
  254. XMLName xml.Name
  255. Part []struct {
  256. PartNumber int
  257. ETag string
  258. }
  259. }
  260. dec := xml.NewDecoder(req.Body)
  261. err = dec.Decode(&payload)
  262. c.Assert(err, IsNil)
  263. c.Assert(payload.XMLName.Local, Equals, "CompleteMultipartUpload")
  264. c.Assert(len(payload.Part), Equals, 2)
  265. c.Assert(payload.Part[0].PartNumber, Equals, 1)
  266. c.Assert(payload.Part[0].ETag, Equals, `"ETag1"`)
  267. c.Assert(payload.Part[1].PartNumber, Equals, 2)
  268. c.Assert(payload.Part[1].ETag, Equals, `"ETag2"`)
  269. }
  270. func (s *S) TestMultiAbort(c *C) {
  271. testServer.Response(200, nil, InitMultiResultDump)
  272. testServer.Response(200, nil, "")
  273. b := s.s3.Bucket("sample")
  274. multi, err := b.InitMulti("multi", "text/plain", s3.Private)
  275. c.Assert(err, IsNil)
  276. err = multi.Abort()
  277. c.Assert(err, IsNil)
  278. testServer.WaitRequest()
  279. req := testServer.WaitRequest()
  280. c.Assert(req.Method, Equals, "DELETE")
  281. c.Assert(req.URL.Path, Equals, "/sample/multi")
  282. c.Assert(req.Form.Get("uploadId"), Matches, "JNbR_[A-Za-z0-9.]+QQ--")
  283. }
  284. func (s *S) TestListMulti(c *C) {
  285. testServer.Response(200, nil, ListMultiResultDump)
  286. b := s.s3.Bucket("sample")
  287. multis, prefixes, err := b.ListMulti("", "/")
  288. c.Assert(err, IsNil)
  289. c.Assert(prefixes, DeepEquals, []string{"a/", "b/"})
  290. c.Assert(multis, HasLen, 2)
  291. c.Assert(multis[0].Key, Equals, "multi1")
  292. c.Assert(multis[0].UploadId, Equals, "iUVug89pPvSswrikD")
  293. c.Assert(multis[1].Key, Equals, "multi2")
  294. c.Assert(multis[1].UploadId, Equals, "DkirwsSvPp98guVUi")
  295. req := testServer.WaitRequest()
  296. c.Assert(req.Method, Equals, "GET")
  297. c.Assert(req.URL.Path, Equals, "/sample/")
  298. c.Assert(req.Form["uploads"], DeepEquals, []string{""})
  299. c.Assert(req.Form["prefix"], DeepEquals, []string{""})
  300. c.Assert(req.Form["delimiter"], DeepEquals, []string{"/"})
  301. c.Assert(req.Form["max-uploads"], DeepEquals, []string{"1000"})
  302. }