upload_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. package oss
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "time"
  7. . "gopkg.in/check.v1"
  8. )
  9. type OssUploadSuite struct {
  10. client *Client
  11. bucket *Bucket
  12. }
  13. var _ = Suite(&OssUploadSuite{})
  14. // SetUpSuite runs once when the suite starts running
  15. func (s *OssUploadSuite) SetUpSuite(c *C) {
  16. client, err := New(endpoint, accessID, accessKey)
  17. c.Assert(err, IsNil)
  18. s.client = client
  19. s.client.CreateBucket(bucketName)
  20. // time.Sleep(timeoutInOperation)
  21. bucket, err := s.client.Bucket(bucketName)
  22. c.Assert(err, IsNil)
  23. s.bucket = bucket
  24. testLogger.Println("test upload started")
  25. }
  26. // TearDownSuite runs before each test or benchmark starts running
  27. func (s *OssUploadSuite) TearDownSuite(c *C) {
  28. // Delete part
  29. lmur, err := s.bucket.ListMultipartUploads()
  30. c.Assert(err, IsNil)
  31. for _, upload := range lmur.Uploads {
  32. var imur = InitiateMultipartUploadResult{Bucket: s.bucket.BucketName,
  33. Key: upload.Key, UploadID: upload.UploadID}
  34. err = s.bucket.AbortMultipartUpload(imur)
  35. c.Assert(err, IsNil)
  36. }
  37. // Delete objects
  38. lor, err := s.bucket.ListObjects()
  39. c.Assert(err, IsNil)
  40. for _, object := range lor.Objects {
  41. err = s.bucket.DeleteObject(object.Key)
  42. c.Assert(err, IsNil)
  43. }
  44. // Delete bucket
  45. err = s.client.DeleteBucket(s.bucket.BucketName)
  46. c.Assert(err, IsNil)
  47. testLogger.Println("test upload completed")
  48. }
  49. // SetUpTest runs after each test or benchmark runs
  50. func (s *OssUploadSuite) SetUpTest(c *C) {
  51. err := removeTempFiles("../oss", ".jpg")
  52. c.Assert(err, IsNil)
  53. }
  54. // TearDownTest runs once after all tests or benchmarks have finished running
  55. func (s *OssUploadSuite) TearDownTest(c *C) {
  56. err := removeTempFiles("../oss", ".jpg")
  57. c.Assert(err, IsNil)
  58. }
  59. // TestUploadRoutineWithoutRecovery tests multiroutineed upload without checkpoint
  60. func (s *OssUploadSuite) TestUploadRoutineWithoutRecovery(c *C) {
  61. objectName := objectNamePrefix + "turwr"
  62. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  63. newFile := "upload-new-file.jpg"
  64. // Routines is not specified, by default single routine
  65. err := s.bucket.UploadFile(objectName, fileName, 100*1024)
  66. c.Assert(err, IsNil)
  67. os.Remove(newFile)
  68. err = s.bucket.GetObjectToFile(objectName, newFile)
  69. c.Assert(err, IsNil)
  70. eq, err := compareFiles(fileName, newFile)
  71. c.Assert(err, IsNil)
  72. c.Assert(eq, Equals, true)
  73. err = s.bucket.DeleteObject(objectName)
  74. c.Assert(err, IsNil)
  75. // Specify routine count as 1
  76. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(1))
  77. c.Assert(err, IsNil)
  78. os.Remove(newFile)
  79. err = s.bucket.GetObjectToFile(objectName, newFile)
  80. c.Assert(err, IsNil)
  81. eq, err = compareFiles(fileName, newFile)
  82. c.Assert(err, IsNil)
  83. c.Assert(eq, Equals, true)
  84. err = s.bucket.DeleteObject(objectName)
  85. c.Assert(err, IsNil)
  86. // Specify routine count as 3, which is smaller than parts count 5
  87. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3))
  88. c.Assert(err, IsNil)
  89. os.Remove(newFile)
  90. err = s.bucket.GetObjectToFile(objectName, newFile)
  91. c.Assert(err, IsNil)
  92. eq, err = compareFiles(fileName, newFile)
  93. c.Assert(err, IsNil)
  94. c.Assert(eq, Equals, true)
  95. err = s.bucket.DeleteObject(objectName)
  96. c.Assert(err, IsNil)
  97. // Specify routine count as 5, which is same as the part count 5
  98. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(5))
  99. c.Assert(err, IsNil)
  100. os.Remove(newFile)
  101. err = s.bucket.GetObjectToFile(objectName, newFile)
  102. c.Assert(err, IsNil)
  103. eq, err = compareFiles(fileName, newFile)
  104. c.Assert(err, IsNil)
  105. c.Assert(eq, Equals, true)
  106. err = s.bucket.DeleteObject(objectName)
  107. c.Assert(err, IsNil)
  108. // Specify routine count as 10, which is bigger than the part count 5.
  109. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(10))
  110. c.Assert(err, IsNil)
  111. os.Remove(newFile)
  112. err = s.bucket.GetObjectToFile(objectName, newFile)
  113. c.Assert(err, IsNil)
  114. eq, err = compareFiles(fileName, newFile)
  115. c.Assert(err, IsNil)
  116. c.Assert(eq, Equals, true)
  117. err = s.bucket.DeleteObject(objectName)
  118. c.Assert(err, IsNil)
  119. // Invalid routine count, it will use 1 automatically.
  120. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(0))
  121. os.Remove(newFile)
  122. err = s.bucket.GetObjectToFile(objectName, newFile)
  123. c.Assert(err, IsNil)
  124. eq, err = compareFiles(fileName, newFile)
  125. c.Assert(err, IsNil)
  126. c.Assert(eq, Equals, true)
  127. err = s.bucket.DeleteObject(objectName)
  128. c.Assert(err, IsNil)
  129. // Invalid routine count, it will use 1 automatically
  130. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(-1))
  131. os.Remove(newFile)
  132. err = s.bucket.GetObjectToFile(objectName, newFile)
  133. c.Assert(err, IsNil)
  134. eq, err = compareFiles(fileName, newFile)
  135. c.Assert(err, IsNil)
  136. c.Assert(eq, Equals, true)
  137. err = s.bucket.DeleteObject(objectName)
  138. c.Assert(err, IsNil)
  139. // Option
  140. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Meta("myprop", "mypropval"))
  141. meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  142. c.Assert(err, IsNil)
  143. c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  144. os.Remove(newFile)
  145. err = s.bucket.GetObjectToFile(objectName, newFile)
  146. c.Assert(err, IsNil)
  147. eq, err = compareFiles(fileName, newFile)
  148. c.Assert(err, IsNil)
  149. c.Assert(eq, Equals, true)
  150. err = s.bucket.DeleteObject(objectName)
  151. c.Assert(err, IsNil)
  152. }
  153. // ErrorHooker is a UploadPart hook---it will fail the 5th part's upload.
  154. func ErrorHooker(id int, chunk FileChunk) error {
  155. if chunk.Number == 5 {
  156. time.Sleep(time.Second)
  157. return fmt.Errorf("ErrorHooker")
  158. }
  159. return nil
  160. }
  161. // TestUploadRoutineWithoutRecoveryNegative is multiroutineed upload without checkpoint
  162. func (s *OssUploadSuite) TestUploadRoutineWithoutRecoveryNegative(c *C) {
  163. objectName := objectNamePrefix + "turwrn"
  164. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  165. uploadPartHooker = ErrorHooker
  166. // Worker routine error
  167. err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(2))
  168. c.Assert(err, NotNil)
  169. c.Assert(err.Error(), Equals, "ErrorHooker")
  170. uploadPartHooker = defaultUploadPart
  171. // Local file does not exist
  172. err = s.bucket.UploadFile(objectName, "NotExist", 100*1024, Routines(2))
  173. c.Assert(err, NotNil)
  174. // The part size is invalid
  175. err = s.bucket.UploadFile(objectName, fileName, 1024, Routines(2))
  176. c.Assert(err, NotNil)
  177. err = s.bucket.UploadFile(objectName, fileName, 1024*1024*1024*100, Routines(2))
  178. c.Assert(err, NotNil)
  179. }
  180. // TestUploadRoutineWithRecovery is multi-routine upload with resumable recovery
  181. func (s *OssUploadSuite) TestUploadRoutineWithRecovery(c *C) {
  182. objectName := objectNamePrefix + "turtr"
  183. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  184. newFile := "upload-new-file-2.jpg"
  185. // Use default routines and default CP file path (fileName+.cp)
  186. // First upload for 4 parts
  187. uploadPartHooker = ErrorHooker
  188. err := s.bucket.UploadFile(objectName, fileName, 100*1024, Checkpoint(true, fileName+".cp"))
  189. c.Assert(err, NotNil)
  190. c.Assert(err.Error(), Equals, "ErrorHooker")
  191. uploadPartHooker = defaultUploadPart
  192. // Check CP
  193. ucp := uploadCheckpoint{}
  194. err = ucp.load(fileName + ".cp")
  195. c.Assert(err, IsNil)
  196. c.Assert(ucp.Magic, Equals, uploadCpMagic)
  197. c.Assert(len(ucp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
  198. c.Assert(ucp.FilePath, Equals, fileName)
  199. c.Assert(ucp.FileStat.Size, Equals, int64(482048))
  200. c.Assert(len(ucp.FileStat.LastModified.String()) > 0, Equals, true)
  201. c.Assert(ucp.FileStat.MD5, Equals, "")
  202. c.Assert(ucp.ObjectKey, Equals, objectName)
  203. c.Assert(len(ucp.UploadID), Equals, len("3F79722737D1469980DACEDCA325BB52"))
  204. c.Assert(len(ucp.Parts), Equals, 5)
  205. c.Assert(len(ucp.todoParts()), Equals, 1)
  206. c.Assert(len(ucp.allParts()), Equals, 5)
  207. // Second upload, finish the remaining part
  208. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Checkpoint(true, fileName+".cp"))
  209. c.Assert(err, IsNil)
  210. os.Remove(newFile)
  211. err = s.bucket.GetObjectToFile(objectName, newFile)
  212. c.Assert(err, IsNil)
  213. eq, err := compareFiles(fileName, newFile)
  214. c.Assert(err, IsNil)
  215. c.Assert(eq, Equals, true)
  216. err = s.bucket.DeleteObject(objectName)
  217. c.Assert(err, IsNil)
  218. err = ucp.load(fileName + ".cp")
  219. c.Assert(err, NotNil)
  220. // Resumable upload with empty checkpoint path
  221. uploadPartHooker = ErrorHooker
  222. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), CheckpointDir(true, ""))
  223. c.Assert(err, NotNil)
  224. c.Assert(err.Error(), Equals, "ErrorHooker")
  225. uploadPartHooker = defaultUploadPart
  226. ucp = uploadCheckpoint{}
  227. err = ucp.load(fileName + ".cp")
  228. c.Assert(err, NotNil)
  229. // Resumable upload with checkpoint dir
  230. uploadPartHooker = ErrorHooker
  231. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), CheckpointDir(true, "./"))
  232. c.Assert(err, NotNil)
  233. c.Assert(err.Error(), Equals, "ErrorHooker")
  234. uploadPartHooker = defaultUploadPart
  235. // Check CP
  236. ucp = uploadCheckpoint{}
  237. cpConf := cpConfig{IsEnable: true, DirPath: "./"}
  238. cpFilePath := getUploadCpFilePath(&cpConf, fileName, s.bucket.BucketName, objectName)
  239. err = ucp.load(cpFilePath)
  240. c.Assert(err, IsNil)
  241. c.Assert(ucp.Magic, Equals, uploadCpMagic)
  242. c.Assert(len(ucp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
  243. c.Assert(ucp.FilePath, Equals, fileName)
  244. c.Assert(ucp.FileStat.Size, Equals, int64(482048))
  245. c.Assert(len(ucp.FileStat.LastModified.String()) > 0, Equals, true)
  246. c.Assert(ucp.FileStat.MD5, Equals, "")
  247. c.Assert(ucp.ObjectKey, Equals, objectName)
  248. c.Assert(len(ucp.UploadID), Equals, len("3F79722737D1469980DACEDCA325BB52"))
  249. c.Assert(len(ucp.Parts), Equals, 5)
  250. c.Assert(len(ucp.todoParts()), Equals, 1)
  251. c.Assert(len(ucp.allParts()), Equals, 5)
  252. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), CheckpointDir(true, "./"))
  253. c.Assert(err, IsNil)
  254. os.Remove(newFile)
  255. err = s.bucket.GetObjectToFile(objectName, newFile)
  256. c.Assert(err, IsNil)
  257. eq, err = compareFiles(fileName, newFile)
  258. c.Assert(err, IsNil)
  259. c.Assert(eq, Equals, true)
  260. err = s.bucket.DeleteObject(objectName)
  261. c.Assert(err, IsNil)
  262. err = ucp.load(cpFilePath)
  263. c.Assert(err, NotNil)
  264. // Upload all 5 parts without error
  265. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Checkpoint(true, objectName+".cp"))
  266. c.Assert(err, IsNil)
  267. os.Remove(newFile)
  268. err = s.bucket.GetObjectToFile(objectName, newFile)
  269. c.Assert(err, IsNil)
  270. eq, err = compareFiles(fileName, newFile)
  271. c.Assert(err, IsNil)
  272. c.Assert(eq, Equals, true)
  273. err = s.bucket.DeleteObject(objectName)
  274. c.Assert(err, IsNil)
  275. // Upload all 5 parts with 10 routines without error
  276. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(10), Checkpoint(true, objectName+".cp"))
  277. c.Assert(err, IsNil)
  278. os.Remove(newFile)
  279. err = s.bucket.GetObjectToFile(objectName, newFile)
  280. c.Assert(err, IsNil)
  281. eq, err = compareFiles(fileName, newFile)
  282. c.Assert(err, IsNil)
  283. c.Assert(eq, Equals, true)
  284. err = s.bucket.DeleteObject(objectName)
  285. c.Assert(err, IsNil)
  286. // Option
  287. err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Checkpoint(true, objectName+".cp"), Meta("myprop", "mypropval"))
  288. meta, err := s.bucket.GetObjectDetailedMeta(objectName)
  289. c.Assert(err, IsNil)
  290. c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
  291. os.Remove(newFile)
  292. err = s.bucket.GetObjectToFile(objectName, newFile)
  293. c.Assert(err, IsNil)
  294. eq, err = compareFiles(fileName, newFile)
  295. c.Assert(err, IsNil)
  296. c.Assert(eq, Equals, true)
  297. err = s.bucket.DeleteObject(objectName)
  298. c.Assert(err, IsNil)
  299. }
  300. // TestUploadRoutineWithRecoveryNegative is multiroutineed upload without checkpoint
  301. func (s *OssUploadSuite) TestUploadRoutineWithRecoveryNegative(c *C) {
  302. objectName := objectNamePrefix + "turrn"
  303. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  304. // The local file does not exist
  305. err := s.bucket.UploadFile(objectName, "NotExist", 100*1024, Checkpoint(true, "NotExist.cp"))
  306. c.Assert(err, NotNil)
  307. err = s.bucket.UploadFile(objectName, "NotExist", 100*1024, Routines(2), Checkpoint(true, "NotExist.cp"))
  308. c.Assert(err, NotNil)
  309. // Specified part size is invalid
  310. err = s.bucket.UploadFile(objectName, fileName, 1024, Checkpoint(true, fileName+".cp"))
  311. c.Assert(err, NotNil)
  312. err = s.bucket.UploadFile(objectName, fileName, 1024, Routines(2), Checkpoint(true, fileName+".cp"))
  313. c.Assert(err, NotNil)
  314. err = s.bucket.UploadFile(objectName, fileName, 1024*1024*1024*100, Checkpoint(true, fileName+".cp"))
  315. c.Assert(err, NotNil)
  316. err = s.bucket.UploadFile(objectName, fileName, 1024*1024*1024*100, Routines(2), Checkpoint(true, fileName+".cp"))
  317. c.Assert(err, NotNil)
  318. }
  319. // TestUploadLocalFileChange tests the file is updated while being uploaded
  320. func (s *OssUploadSuite) TestUploadLocalFileChange(c *C) {
  321. objectName := objectNamePrefix + "tulfc"
  322. fileName := "../sample/BingWallpaper-2015-11-07.jpg"
  323. localFile := "BingWallpaper-2015-11-07.jpg"
  324. newFile := "upload-new-file-3.jpg"
  325. os.Remove(localFile)
  326. err := copyFile(fileName, localFile)
  327. c.Assert(err, IsNil)
  328. // First upload for 4 parts
  329. uploadPartHooker = ErrorHooker
  330. err = s.bucket.UploadFile(objectName, localFile, 100*1024, Checkpoint(true, localFile+".cp"))
  331. c.Assert(err, NotNil)
  332. c.Assert(err.Error(), Equals, "ErrorHooker")
  333. uploadPartHooker = defaultUploadPart
  334. os.Remove(localFile)
  335. err = copyFile(fileName, localFile)
  336. c.Assert(err, IsNil)
  337. // Updating the file. The second upload will re-upload all 5 parts.
  338. err = s.bucket.UploadFile(objectName, localFile, 100*1024, Checkpoint(true, localFile+".cp"))
  339. c.Assert(err, IsNil)
  340. os.Remove(newFile)
  341. err = s.bucket.GetObjectToFile(objectName, newFile)
  342. c.Assert(err, IsNil)
  343. eq, err := compareFiles(fileName, newFile)
  344. c.Assert(err, IsNil)
  345. c.Assert(eq, Equals, true)
  346. err = s.bucket.DeleteObject(objectName)
  347. c.Assert(err, IsNil)
  348. }
  349. func copyFile(src, dst string) error {
  350. srcFile, err := os.Open(src)
  351. if err != nil {
  352. return err
  353. }
  354. defer srcFile.Close()
  355. dstFile, err := os.Create(dst)
  356. if err != nil {
  357. return err
  358. }
  359. defer dstFile.Close()
  360. _, err = io.Copy(dstFile, srcFile)
  361. return err
  362. }