crc_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. package oss
  2. import (
  3. "crypto/md5"
  4. "encoding/base64"
  5. "hash/crc64"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "strings"
  10. "time"
  11. . "gopkg.in/check.v1"
  12. )
  13. type OssCrcSuite struct {
  14. client *Client
  15. bucket *Bucket
  16. }
  17. var _ = Suite(&OssCrcSuite{})
  18. // Run once when the suite starts running
  19. func (s *OssCrcSuite) SetUpSuite(c *C) {
  20. client, err := New(endpoint, accessID, accessKey)
  21. c.Assert(err, IsNil)
  22. s.client = client
  23. s.client.CreateBucket(bucketName)
  24. time.Sleep(5 * time.Second)
  25. bucket, err := s.client.Bucket(bucketName)
  26. c.Assert(err, IsNil)
  27. s.bucket = bucket
  28. testLogger.Println("test crc started")
  29. }
  30. // Run before each test or benchmark starts running
  31. func (s *OssCrcSuite) TearDownSuite(c *C) {
  32. // Delete Part
  33. lmur, err := s.bucket.ListMultipartUploads()
  34. c.Assert(err, IsNil)
  35. for _, upload := range lmur.Uploads {
  36. var imur = InitiateMultipartUploadResult{Bucket: s.bucket.BucketName,
  37. Key: upload.Key, UploadID: upload.UploadID}
  38. err = s.bucket.AbortMultipartUpload(imur)
  39. c.Assert(err, IsNil)
  40. }
  41. // Delete Objects
  42. lor, err := s.bucket.ListObjects()
  43. c.Assert(err, IsNil)
  44. for _, object := range lor.Objects {
  45. err = s.bucket.DeleteObject(object.Key)
  46. c.Assert(err, IsNil)
  47. }
  48. testLogger.Println("test crc completed")
  49. }
  50. // Run after each test or benchmark runs
  51. func (s *OssCrcSuite) SetUpTest(c *C) {
  52. err := removeTempFiles("../oss", ".jpg")
  53. c.Assert(err, IsNil)
  54. }
  55. // Run once after all tests or benchmarks have finished running
  56. func (s *OssCrcSuite) TearDownTest(c *C) {
  57. err := removeTempFiles("../oss", ".jpg")
  58. c.Assert(err, IsNil)
  59. }
  60. // TestCRCGolden 测试OSS实现的CRC64
  61. func (s *OssCrcSuite) TestCRCGolden(c *C) {
  62. type crcTest struct {
  63. out uint64
  64. in string
  65. }
  66. var crcGolden = []crcTest{
  67. {0x0, ""},
  68. {0x3420000000000000, "a"},
  69. {0x36c4200000000000, "ab"},
  70. {0x3776c42000000000, "abc"},
  71. {0x336776c420000000, "abcd"},
  72. {0x32d36776c4200000, "abcde"},
  73. {0x3002d36776c42000, "abcdef"},
  74. {0x31b002d36776c420, "abcdefg"},
  75. {0xe21b002d36776c4, "abcdefgh"},
  76. {0x8b6e21b002d36776, "abcdefghi"},
  77. {0x7f5b6e21b002d367, "abcdefghij"},
  78. {0x8ec0e7c835bf9cdf, "Discard medicine more than two years old."},
  79. {0xc7db1759e2be5ab4, "He who has a shady past knows that nice guys finish last."},
  80. {0xfbf9d9603a6fa020, "I wouldn't marry him with a ten foot pole."},
  81. {0xeafc4211a6daa0ef, "Free! Free!/A trip/to Mars/for 900/empty jars/Burma Shave"},
  82. {0x3e05b21c7a4dc4da, "The days of the digital watch are numbered. -Tom Stoppard"},
  83. {0x5255866ad6ef28a6, "Nepal premier won't resign."},
  84. {0x8a79895be1e9c361, "For every action there is an equal and opposite government program."},
  85. {0x8878963a649d4916, "His money is twice tainted: 'taint yours and 'taint mine."},
  86. {0xa7b9d53ea87eb82f, "There is no reason for any individual to have a computer in their home. -Ken Olsen, 1977"},
  87. {0xdb6805c0966a2f9c, "It's a tiny change to the code and not completely disgusting. - Bob Manchek"},
  88. {0xf3553c65dacdadd2, "size: a.out: bad magic"},
  89. {0x9d5e034087a676b9, "The major problem is with sendmail. -Mark Horton"},
  90. {0xa6db2d7f8da96417, "Give me a rock, paper and scissors and I will move the world. CCFestoon"},
  91. {0x325e00cd2fe819f9, "If the enemy is within range, then so are you."},
  92. {0x88c6600ce58ae4c6, "It's well we cannot hear the screams/That we create in others' dreams."},
  93. {0x28c4a3f3b769e078, "You remind me of a TV show, but that's all right: I watch it anyway."},
  94. {0xa698a34c9d9f1dca, "C is as portable as Stonehedge!!"},
  95. {0xf6c1e2a8c26c5cfc, "Even if I could be Shakespeare, I think I should still choose to be Faraday. - A. Huxley"},
  96. {0xd402559dfe9b70c, "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"},
  97. {0xdb6efff26aa94946, "How can you write a big system without C++? -Paul Glick"},
  98. }
  99. var tab = crc64.MakeTable(crc64.ISO)
  100. for i := 0; i < len(crcGolden); i++ {
  101. golden := crcGolden[i]
  102. crc := NewCRC(tab, 0)
  103. io.WriteString(crc, golden.in)
  104. sum := crc.Sum64()
  105. c.Assert(sum, Equals, golden.out)
  106. }
  107. }
  108. // testCRC64Combine test crc64 on vector[0..pos] which should have CRC-64 crc.
  109. // Also test CRC64Combine on vector[] split in two.
  110. func testCRC64Combine(c *C, str string, pos int, crc uint64) {
  111. tabECMA := crc64.MakeTable(crc64.ECMA)
  112. // test crc64
  113. hash := crc64.New(tabECMA)
  114. io.WriteString(hash, str)
  115. crc1 := hash.Sum64()
  116. c.Assert(crc1, Equals, crc)
  117. // test crc64 combine
  118. hash = crc64.New(tabECMA)
  119. io.WriteString(hash, str[0:pos])
  120. crc1 = hash.Sum64()
  121. hash = crc64.New(tabECMA)
  122. io.WriteString(hash, str[pos:len(str)])
  123. crc2 := hash.Sum64()
  124. crc1 = CRC64Combine(crc1, crc2, uint64(len(str)-pos))
  125. c.Assert(crc1, Equals, crc)
  126. }
  127. // TestCRCGolden 测试CRC64Combine
  128. func (s *OssCrcSuite) TestCRCCombine(c *C) {
  129. str := "123456789"
  130. testCRC64Combine(c, str, (len(str)+1)>>1, 0x995DC9BBDF1939FA)
  131. str = "This is a test of the emergency broadcast system."
  132. testCRC64Combine(c, str, (len(str)+1)>>1, 0x27DB187FC15BBC72)
  133. }
  134. // TestEnableCRCAndMD5 开启MD5和CRC校验
  135. func (s *OssCrcSuite) TestEnableCRCAndMD5(c *C) {
  136. objectName := objectNamePrefix + "tecam"
  137. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  138. newFileName := "BingWallpaper-2015-11-07-2.jpg"
  139. objectValue := "空山新雨后,天气晚来秋。明月松间照,清泉石上流。竹喧归浣女,莲动下渔舟。随意春芳歇,王孙自可留。"
  140. client, err := New(endpoint, accessID, accessKey, EnableCRC(true), EnableMD5(true), MD5ThresholdCalcInMemory(200*1024))
  141. c.Assert(err, IsNil)
  142. bucket, err := client.Bucket(bucketName)
  143. c.Assert(err, IsNil)
  144. // PutObject
  145. err = bucket.PutObject(objectName, strings.NewReader(objectValue))
  146. c.Assert(err, IsNil)
  147. // GetObject
  148. body, err := bucket.GetObject(objectName)
  149. c.Assert(err, IsNil)
  150. _, err = ioutil.ReadAll(body)
  151. c.Assert(err, IsNil)
  152. body.Close()
  153. // GetObjectWithCRC
  154. getResult, err := bucket.DoGetObject(&GetObjectRequest{objectName}, nil)
  155. c.Assert(err, IsNil)
  156. str, err := readBody(getResult.Response.Body)
  157. c.Assert(err, IsNil)
  158. c.Assert(str, Equals, objectValue)
  159. c.Assert(getResult.ClientCRC.Sum64(), Equals, getResult.ServerCRC)
  160. // PutObjectFromFile
  161. err = bucket.PutObjectFromFile(objectName, fileName)
  162. c.Assert(err, IsNil)
  163. // GetObjectToFile
  164. err = bucket.GetObjectToFile(objectName, newFileName)
  165. c.Assert(err, IsNil)
  166. eq, err := compareFiles(fileName, newFileName)
  167. c.Assert(err, IsNil)
  168. c.Assert(eq, Equals, true)
  169. // DeleteObject
  170. err = bucket.DeleteObject(objectName)
  171. c.Assert(err, IsNil)
  172. // AppendObject
  173. var nextPos int64
  174. nextPos, err = bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  175. c.Assert(err, IsNil)
  176. nextPos, err = bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  177. c.Assert(err, IsNil)
  178. err = bucket.DeleteObject(objectName)
  179. c.Assert(err, IsNil)
  180. request := &AppendObjectRequest{
  181. ObjectKey: objectName,
  182. Reader: strings.NewReader(objectValue),
  183. Position: 0,
  184. }
  185. appendResult, err := bucket.DoAppendObject(request, []Option{InitCRC(0)})
  186. c.Assert(err, IsNil)
  187. request.Position = appendResult.NextPosition
  188. appendResult, err = bucket.DoAppendObject(request, []Option{InitCRC(appendResult.CRC)})
  189. c.Assert(err, IsNil)
  190. err = s.bucket.DeleteObject(objectName)
  191. c.Assert(err, IsNil)
  192. // MultipartUpload
  193. chunks, err := SplitFileByPartSize(fileName, 100*1024)
  194. imurUpload, err := bucket.InitiateMultipartUpload(objectName)
  195. c.Assert(err, IsNil)
  196. var partsUpload []UploadPart
  197. for _, chunk := range chunks {
  198. part, err := bucket.UploadPartFromFile(imurUpload, fileName, chunk.Offset, chunk.Size, (int)(chunk.Number))
  199. c.Assert(err, IsNil)
  200. partsUpload = append(partsUpload, part)
  201. }
  202. _, err = bucket.CompleteMultipartUpload(imurUpload, partsUpload)
  203. c.Assert(err, IsNil)
  204. // Check MultipartUpload
  205. err = bucket.GetObjectToFile(objectName, newFileName)
  206. c.Assert(err, IsNil)
  207. eq, err = compareFiles(fileName, newFileName)
  208. c.Assert(err, IsNil)
  209. c.Assert(eq, Equals, true)
  210. // DeleteObjects
  211. _, err = bucket.DeleteObjects([]string{objectName})
  212. c.Assert(err, IsNil)
  213. }
  214. // TestDisableCRCAndMD5 关闭MD5和CRC校验
  215. func (s *OssCrcSuite) TestDisableCRCAndMD5(c *C) {
  216. objectName := objectNamePrefix + "tdcam"
  217. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  218. newFileName := "BingWallpaper-2015-11-07-3.jpg"
  219. objectValue := "中岁颇好道,晚家南山陲。兴来每独往,胜事空自知。行到水穷处,坐看云起时。偶然值林叟,谈笑无还期。"
  220. client, err := New(endpoint, accessID, accessKey, EnableCRC(false), EnableMD5(false))
  221. c.Assert(err, IsNil)
  222. bucket, err := client.Bucket(bucketName)
  223. c.Assert(err, IsNil)
  224. // PutObject
  225. err = bucket.PutObject(objectName, strings.NewReader(objectValue))
  226. c.Assert(err, IsNil)
  227. // GetObject
  228. body, err := bucket.GetObject(objectName)
  229. c.Assert(err, IsNil)
  230. _, err = ioutil.ReadAll(body)
  231. c.Assert(err, IsNil)
  232. body.Close()
  233. // GetObjectWithCRC
  234. getResult, err := bucket.DoGetObject(&GetObjectRequest{objectName}, nil)
  235. c.Assert(err, IsNil)
  236. str, err := readBody(getResult.Response.Body)
  237. c.Assert(err, IsNil)
  238. c.Assert(str, Equals, objectValue)
  239. // PutObjectFromFile
  240. err = bucket.PutObjectFromFile(objectName, fileName)
  241. c.Assert(err, IsNil)
  242. // GetObjectToFile
  243. err = bucket.GetObjectToFile(objectName, newFileName)
  244. c.Assert(err, IsNil)
  245. eq, err := compareFiles(fileName, newFileName)
  246. c.Assert(err, IsNil)
  247. c.Assert(eq, Equals, true)
  248. // DeleteObject
  249. err = bucket.DeleteObject(objectName)
  250. c.Assert(err, IsNil)
  251. // AppendObject
  252. var nextPos int64
  253. nextPos, err = bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  254. c.Assert(err, IsNil)
  255. nextPos, err = bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  256. c.Assert(err, IsNil)
  257. err = bucket.DeleteObject(objectName)
  258. c.Assert(err, IsNil)
  259. request := &AppendObjectRequest{
  260. ObjectKey: objectName,
  261. Reader: strings.NewReader(objectValue),
  262. Position: 0,
  263. }
  264. appendResult, err := bucket.DoAppendObject(request, []Option{InitCRC(0)})
  265. c.Assert(err, IsNil)
  266. request.Position = appendResult.NextPosition
  267. appendResult, err = bucket.DoAppendObject(request, []Option{InitCRC(appendResult.CRC)})
  268. c.Assert(err, IsNil)
  269. err = s.bucket.DeleteObject(objectName)
  270. c.Assert(err, IsNil)
  271. // MultipartUpload
  272. chunks, err := SplitFileByPartSize(fileName, 100*1024)
  273. imurUpload, err := bucket.InitiateMultipartUpload(objectName)
  274. c.Assert(err, IsNil)
  275. var partsUpload []UploadPart
  276. for _, chunk := range chunks {
  277. part, err := bucket.UploadPartFromFile(imurUpload, fileName, chunk.Offset, chunk.Size, (int)(chunk.Number))
  278. c.Assert(err, IsNil)
  279. partsUpload = append(partsUpload, part)
  280. }
  281. _, err = bucket.CompleteMultipartUpload(imurUpload, partsUpload)
  282. c.Assert(err, IsNil)
  283. // Check MultipartUpload
  284. err = bucket.GetObjectToFile(objectName, newFileName)
  285. c.Assert(err, IsNil)
  286. eq, err = compareFiles(fileName, newFileName)
  287. c.Assert(err, IsNil)
  288. c.Assert(eq, Equals, true)
  289. // DeleteObjects
  290. _, err = bucket.DeleteObjects([]string{objectName})
  291. c.Assert(err, IsNil)
  292. }
  293. // TestSpecifyContentMD5 指定MD5
  294. func (s *OssCrcSuite) TestSpecifyContentMD5(c *C) {
  295. objectName := objectNamePrefix + "tdcam"
  296. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  297. objectValue := "积雨空林烟火迟,蒸藜炊黍饷东菑。漠漠水田飞白鹭,阴阴夏木啭黄鹂。山中习静观朝槿,松下清斋折露葵。野老与人争席罢,海鸥何事更相疑。"
  298. mh := md5.Sum([]byte(objectValue))
  299. md5B64 := base64.StdEncoding.EncodeToString(mh[:])
  300. // PutObject
  301. err := s.bucket.PutObject(objectName, strings.NewReader(objectValue), ContentMD5(md5B64))
  302. c.Assert(err, IsNil)
  303. // PutObjectFromFile
  304. file, err := os.Open(fileName)
  305. md5 := md5.New()
  306. io.Copy(md5, file)
  307. mdHex := base64.StdEncoding.EncodeToString(md5.Sum(nil)[:])
  308. err = s.bucket.PutObjectFromFile(objectName, fileName, ContentMD5(mdHex))
  309. c.Assert(err, IsNil)
  310. err = s.bucket.DeleteObject(objectName)
  311. c.Assert(err, IsNil)
  312. // AppendObject
  313. var nextPos int64
  314. nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  315. c.Assert(err, IsNil)
  316. nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos)
  317. c.Assert(err, IsNil)
  318. err = s.bucket.DeleteObject(objectName)
  319. c.Assert(err, IsNil)
  320. request := &AppendObjectRequest{
  321. ObjectKey: objectName,
  322. Reader: strings.NewReader(objectValue),
  323. Position: 0,
  324. }
  325. appendResult, err := s.bucket.DoAppendObject(request, []Option{InitCRC(0)})
  326. c.Assert(err, IsNil)
  327. request.Position = appendResult.NextPosition
  328. appendResult, err = s.bucket.DoAppendObject(request, []Option{InitCRC(appendResult.CRC)})
  329. c.Assert(err, IsNil)
  330. err = s.bucket.DeleteObject(objectName)
  331. c.Assert(err, IsNil)
  332. // MultipartUpload
  333. imurUpload, err := s.bucket.InitiateMultipartUpload(objectName)
  334. c.Assert(err, IsNil)
  335. var partsUpload []UploadPart
  336. part, err := s.bucket.UploadPart(imurUpload, strings.NewReader(objectValue), (int64)(len([]byte(objectValue))), 1)
  337. c.Assert(err, IsNil)
  338. partsUpload = append(partsUpload, part)
  339. _, err = s.bucket.CompleteMultipartUpload(imurUpload, partsUpload)
  340. c.Assert(err, IsNil)
  341. // DeleteObject
  342. err = s.bucket.DeleteObject(objectName)
  343. c.Assert(err, IsNil)
  344. }
  345. // TestCopyObjectToOrFromNegative
  346. func (s *OssCrcSuite) TestAppendObjectNegative(c *C) {
  347. objectName := objectNamePrefix + "taoncrc"
  348. objectValue := "空山不见人,但闻人语响。返影入深林,复照青苔上。"
  349. nextPos, err := s.bucket.AppendObject(objectName, strings.NewReader(objectValue), 0, InitCRC(0))
  350. c.Assert(err, IsNil)
  351. nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader(objectValue), nextPos, InitCRC(0))
  352. c.Assert(err, NotNil)
  353. c.Assert(strings.HasPrefix(err.Error(), "oss: the crc"), Equals, true)
  354. }