You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
8.2 KiB

  1. package cos
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/xml"
  6. "fmt"
  7. "hash/crc64"
  8. "io/ioutil"
  9. "net/http"
  10. "reflect"
  11. "strconv"
  12. "testing"
  13. )
  14. func TestObjectService_AbortMultipartUpload(t *testing.T) {
  15. setup()
  16. defer teardown()
  17. name := "test/hello.txt"
  18. uploadID := "xxxxaabcc"
  19. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  20. testMethod(t, r, http.MethodDelete)
  21. vs := values{
  22. "uploadId": uploadID,
  23. }
  24. testFormValues(t, r, vs)
  25. w.WriteHeader(http.StatusNoContent)
  26. })
  27. _, err := client.Object.AbortMultipartUpload(context.Background(),
  28. name, uploadID)
  29. if err != nil {
  30. t.Fatalf("Object.AbortMultipartUpload returned error: %v", err)
  31. }
  32. }
  33. func TestObjectService_InitiateMultipartUpload(t *testing.T) {
  34. setup()
  35. defer teardown()
  36. opt := &InitiateMultipartUploadOptions{
  37. ObjectPutHeaderOptions: &ObjectPutHeaderOptions{
  38. ContentType: "text/html",
  39. },
  40. ACLHeaderOptions: &ACLHeaderOptions{
  41. XCosACL: "private",
  42. },
  43. }
  44. name := "test/hello.txt"
  45. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  46. v := new(BucketPutTaggingOptions)
  47. xml.NewDecoder(r.Body).Decode(v)
  48. testMethod(t, r, http.MethodPost)
  49. testHeader(t, r, "x-cos-acl", "private")
  50. testHeader(t, r, "Content-Type", "text/html")
  51. vs := values{
  52. "uploads": "",
  53. }
  54. testFormValues(t, r, vs)
  55. fmt.Fprint(w, `<InitiateMultipartUploadResult>
  56. <Bucket>test-1253846586</Bucket>
  57. <Key>test/hello.txt</Key>
  58. <UploadId>149795166761115ef06e259b2fceb8ff34bf7dd840883d26a0f90243562dd398efa41718db</UploadId>
  59. </InitiateMultipartUploadResult>`)
  60. })
  61. ref, _, err := client.Object.InitiateMultipartUpload(context.Background(),
  62. name, opt)
  63. if err != nil {
  64. t.Fatalf("Object.InitiateMultipartUpload returned error: %v", err)
  65. }
  66. want := &InitiateMultipartUploadResult{
  67. XMLName: xml.Name{Local: "InitiateMultipartUploadResult"},
  68. Bucket: "test-1253846586",
  69. Key: "test/hello.txt",
  70. UploadID: "149795166761115ef06e259b2fceb8ff34bf7dd840883d26a0f90243562dd398efa41718db",
  71. }
  72. if !reflect.DeepEqual(ref, want) {
  73. t.Errorf("Object.InitiateMultipartUpload returned %+v, want %+v", ref, want)
  74. }
  75. }
  76. func TestObjectService_UploadPart(t *testing.T) {
  77. setup()
  78. defer teardown()
  79. opt := &ObjectUploadPartOptions{}
  80. name := "test/hello.txt"
  81. uploadID := "xxxxx"
  82. partNumber := 1
  83. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  84. testMethod(t, r, http.MethodPut)
  85. vs := values{
  86. "uploadId": uploadID,
  87. "partNumber": "1",
  88. }
  89. testFormValues(t, r, vs)
  90. b, _ := ioutil.ReadAll(r.Body)
  91. tb := crc64.MakeTable(crc64.ECMA)
  92. crc := crc64.Update(0, tb, b)
  93. v := string(b)
  94. want := "hello"
  95. if !reflect.DeepEqual(v, want) {
  96. t.Errorf("Object.UploadPart request body: %#v, want %#v", v, want)
  97. }
  98. w.Header().Add("x-cos-hash-crc64ecma", strconv.FormatUint(crc, 10))
  99. })
  100. r := bytes.NewReader([]byte("hello"))
  101. _, err := client.Object.UploadPart(context.Background(),
  102. name, uploadID, partNumber, r, opt)
  103. if err != nil {
  104. t.Fatalf("Object.UploadPart returned error: %v", err)
  105. }
  106. }
  107. func TestObjectService_ListParts(t *testing.T) {
  108. setup()
  109. defer teardown()
  110. name := "test/hello.txt"
  111. uploadID := "149795194893578fd83aceef3a88f708f81f00e879fda5ea8a80bf15aba52746d42d512387"
  112. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  113. v := new(BucketPutTaggingOptions)
  114. xml.NewDecoder(r.Body).Decode(v)
  115. testMethod(t, r, http.MethodGet)
  116. vs := values{
  117. "uploadId": uploadID,
  118. }
  119. testFormValues(t, r, vs)
  120. fmt.Fprint(w, `<ListPartsResult>
  121. <Bucket>test-1253846586</Bucket>
  122. <Encoding-type/>
  123. <Key>test/hello.txt</Key>
  124. <UploadId>149795194893578fd83aceef3a88f708f81f00e879fda5ea8a80bf15aba52746d42d512387</UploadId>
  125. <Owner>
  126. <ID>1253846586</ID>
  127. <DisplayName>1253846586</DisplayName>
  128. </Owner>
  129. <PartNumberMarker>0</PartNumberMarker>
  130. <Initiator>
  131. <ID>qcs::cam::uin/100000760461:uin/100000760461</ID>
  132. <DisplayName>100000760461</DisplayName>
  133. </Initiator>
  134. <Part>
  135. <PartNumber>1</PartNumber>
  136. <LastModified>2017-06-20T09:45:49.000Z</LastModified>
  137. <ETag>&quot;fae3dba15f4d9b2d76cbaed5de3a08e3&quot;</ETag>
  138. <Size>6291456</Size>
  139. </Part>
  140. <Part>
  141. <PartNumber>2</PartNumber>
  142. <LastModified>2017-06-20T09:45:50.000Z</LastModified>
  143. <ETag>&quot;c81982550f2f965118d486176d9541d4&quot;</ETag>
  144. <Size>6391456</Size>
  145. </Part>
  146. <StorageClass>Standard</StorageClass>
  147. <MaxParts>1000</MaxParts>
  148. <IsTruncated>false</IsTruncated>
  149. </ListPartsResult>`)
  150. })
  151. ref, _, err := client.Object.ListParts(context.Background(),
  152. name, uploadID, nil)
  153. if err != nil {
  154. t.Fatalf("Object.ListParts returned error: %v", err)
  155. }
  156. want := &ObjectListPartsResult{
  157. XMLName: xml.Name{Local: "ListPartsResult"},
  158. Bucket: "test-1253846586",
  159. UploadID: uploadID,
  160. Key: name,
  161. Owner: &Owner{
  162. ID: "1253846586",
  163. DisplayName: "1253846586",
  164. },
  165. PartNumberMarker: "0",
  166. Initiator: &Initiator{
  167. ID: "qcs::cam::uin/100000760461:uin/100000760461",
  168. DisplayName: "100000760461",
  169. },
  170. Parts: []Object{
  171. {
  172. PartNumber: 1,
  173. LastModified: "2017-06-20T09:45:49.000Z",
  174. ETag: "\"fae3dba15f4d9b2d76cbaed5de3a08e3\"",
  175. Size: 6291456,
  176. },
  177. {
  178. PartNumber: 2,
  179. LastModified: "2017-06-20T09:45:50.000Z",
  180. ETag: "\"c81982550f2f965118d486176d9541d4\"",
  181. Size: 6391456,
  182. },
  183. },
  184. StorageClass: "Standard",
  185. MaxParts: "1000",
  186. IsTruncated: false,
  187. }
  188. if !reflect.DeepEqual(ref, want) {
  189. t.Errorf("Object.ListParts returned \n%#v, want \n%#v", ref, want)
  190. }
  191. }
  192. func TestObjectService_CompleteMultipartUpload(t *testing.T) {
  193. setup()
  194. defer teardown()
  195. name := "test/hello.txt"
  196. uploadID := "149795194893578fd83aceef3a88f708f81f00e879fda5ea8a80bf15aba52746d42d512387"
  197. opt := &CompleteMultipartUploadOptions{
  198. Parts: []Object{
  199. {
  200. PartNumber: 1,
  201. ETag: "\"fae3dba15f4d9b2d76cbaed5de3a08e3\"",
  202. },
  203. {
  204. PartNumber: 2,
  205. ETag: "\"c81982550f2f965118d486176d9541d4\"",
  206. },
  207. },
  208. }
  209. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  210. v := new(CompleteMultipartUploadOptions)
  211. xml.NewDecoder(r.Body).Decode(v)
  212. testMethod(t, r, http.MethodPost)
  213. vs := values{
  214. "uploadId": uploadID,
  215. }
  216. testFormValues(t, r, vs)
  217. want := opt
  218. want.XMLName = xml.Name{Local: "CompleteMultipartUpload"}
  219. if !reflect.DeepEqual(v, want) {
  220. t.Errorf("Object.CompleteMultipartUpload request body: %+v, want %+v", v, want)
  221. }
  222. fmt.Fprint(w, `<CompleteMultipartUploadResult>
  223. <Location>test-1253846586.cos.ap-guangzhou.myqcloud.com/test/hello.txt</Location>
  224. <Bucket>test</Bucket>
  225. <Key>test/hello.txt</Key>
  226. <ETag>&quot;594f98b11c6901c0f0683de1085a6d0e-4&quot;</ETag>
  227. </CompleteMultipartUploadResult>`)
  228. })
  229. ref, _, err := client.Object.CompleteMultipartUpload(context.Background(),
  230. name, uploadID, opt)
  231. if err != nil {
  232. t.Fatalf("Object.ListParts returned error: %v", err)
  233. }
  234. want := &CompleteMultipartUploadResult{
  235. XMLName: xml.Name{Local: "CompleteMultipartUploadResult"},
  236. Bucket: "test",
  237. Key: name,
  238. ETag: "\"594f98b11c6901c0f0683de1085a6d0e-4\"",
  239. Location: "test-1253846586.cos.ap-guangzhou.myqcloud.com/test/hello.txt",
  240. }
  241. if !reflect.DeepEqual(ref, want) {
  242. t.Errorf("Object.CompleteMultipartUpload returned \n%#v, want \n%#v", ref, want)
  243. }
  244. }
  245. func TestObjectService_CopyPart(t *testing.T) {
  246. setup()
  247. defer teardown()
  248. sourceUrl := "test-1253846586.cos.ap-guangzhou.myqcloud.com/test.source"
  249. opt := &ObjectCopyPartOptions{}
  250. name := "test/hello.txt"
  251. uploadID := "xxxxx"
  252. partNumber := 1
  253. mux.HandleFunc("/test/hello.txt", func(w http.ResponseWriter, r *http.Request) {
  254. testMethod(t, r, http.MethodPut)
  255. vs := values{
  256. "uploadId": uploadID,
  257. "partNumber": "1",
  258. }
  259. testFormValues(t, r, vs)
  260. fmt.Fprint(w, `<CopyPartResult>
  261. <ETag>&quot;ba82b57cfdfda8bd17ad4e5879ebb4fe&quot;</ETag>
  262. <LastModified>2017-09-04T04:45:45</LastModified>
  263. </CopyPartResult>`)
  264. })
  265. r, _, err := client.Object.CopyPart(context.Background(),
  266. name, uploadID, partNumber, sourceUrl, opt)
  267. if err != nil {
  268. t.Fatalf("Object.CopyPart returned error: %v", err)
  269. }
  270. want := &CopyPartResult{
  271. XMLName: xml.Name{Local: "CopyPartResult"},
  272. ETag: `"ba82b57cfdfda8bd17ad4e5879ebb4fe"`,
  273. LastModified: "2017-09-04T04:45:45",
  274. }
  275. if !reflect.DeepEqual(r, want) {
  276. t.Errorf("Object.Copy returned %+v, want %+v", r, want)
  277. }
  278. }