github.com/aliyun/aliyun-oss-go-sdk@v3.0.2+incompatible/oss/download_test.go (about) 1 package oss 2 3 import ( 4 "bytes" 5 "fmt" 6 "net/http" 7 "os" 8 "strings" 9 "time" 10 11 . "gopkg.in/check.v1" 12 ) 13 14 type OssDownloadSuite struct { 15 cloudBoxControlClient *Client 16 client *Client 17 bucket *Bucket 18 } 19 20 var _ = Suite(&OssDownloadSuite{}) 21 22 // SetUpSuite runs once when the suite starts running 23 func (s *OssDownloadSuite) SetUpSuite(c *C) { 24 bucketName := bucketNamePrefix + RandLowStr(6) 25 if cloudboxControlEndpoint == "" { 26 client, err := New(endpoint, accessID, accessKey) 27 c.Assert(err, IsNil) 28 s.client = client 29 30 s.client.CreateBucket(bucketName) 31 32 bucket, err := s.client.Bucket(bucketName) 33 c.Assert(err, IsNil) 34 s.bucket = bucket 35 36 testLogger.Println("test crc started") 37 } else { 38 client, err := New(cloudboxEndpoint, accessID, accessKey) 39 c.Assert(err, IsNil) 40 s.client = client 41 42 controlClient, err := New(cloudboxControlEndpoint, accessID, accessKey) 43 c.Assert(err, IsNil) 44 s.cloudBoxControlClient = controlClient 45 controlClient.CreateBucket(bucketName) 46 47 bucket, err := s.client.Bucket(bucketName) 48 c.Assert(err, IsNil) 49 s.bucket = bucket 50 } 51 52 testLogger.Println("test download started") 53 } 54 55 // TearDownSuite runs before each test or benchmark starts running 56 func (s *OssDownloadSuite) TearDownSuite(c *C) { 57 // Delete part 58 keyMarker := KeyMarker("") 59 uploadIDMarker := UploadIDMarker("") 60 for { 61 lmur, err := s.bucket.ListMultipartUploads(keyMarker, uploadIDMarker) 62 c.Assert(err, IsNil) 63 for _, upload := range lmur.Uploads { 64 var imur = InitiateMultipartUploadResult{Bucket: s.bucket.BucketName, 65 Key: upload.Key, UploadID: upload.UploadID} 66 err = s.bucket.AbortMultipartUpload(imur) 67 c.Assert(err, IsNil) 68 } 69 keyMarker = KeyMarker(lmur.NextKeyMarker) 70 uploadIDMarker = UploadIDMarker(lmur.NextUploadIDMarker) 71 if !lmur.IsTruncated { 72 break 73 } 74 } 75 76 // Delete objects 77 marker := Marker("") 78 for { 79 lor, err := s.bucket.ListObjects(marker) 80 c.Assert(err, IsNil) 81 for _, object := range lor.Objects { 82 err = s.bucket.DeleteObject(object.Key) 83 c.Assert(err, IsNil) 84 } 85 marker = Marker(lor.NextMarker) 86 if !lor.IsTruncated { 87 break 88 } 89 } 90 91 // Delete bucket 92 if s.cloudBoxControlClient != nil { 93 err := s.cloudBoxControlClient.DeleteBucket(s.bucket.BucketName) 94 c.Assert(err, IsNil) 95 } else { 96 err := s.client.DeleteBucket(s.bucket.BucketName) 97 c.Assert(err, IsNil) 98 } 99 100 testLogger.Println("test download completed") 101 } 102 103 // SetUpTest runs after each test or benchmark runs 104 func (s *OssDownloadSuite) SetUpTest(c *C) { 105 err := removeTempFiles("../oss", ".jpg") 106 c.Assert(err, IsNil) 107 } 108 109 // TearDownTest runs once after all tests or benchmarks have finished running 110 func (s *OssDownloadSuite) TearDownTest(c *C) { 111 err := removeTempFiles("../oss", ".jpg") 112 c.Assert(err, IsNil) 113 114 err = removeTempFiles("../oss", ".temp") 115 c.Assert(err, IsNil) 116 } 117 118 // TestDownloadRoutineWithoutRecovery multipart downloads without checkpoint 119 func (s *OssDownloadSuite) TestDownloadRoutineWithoutRecovery(c *C) { 120 objectName := objectNamePrefix + RandStr(8) 121 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 122 newFile := RandStr(8) + ".jpg" 123 124 // Upload a file 125 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 126 c.Assert(err, IsNil) 127 128 // Download the file by default 129 err = s.bucket.DownloadFile(objectName, newFile, 100*1024) 130 c.Assert(err, IsNil) 131 132 // Check 133 eq, err := compareFiles(fileName, newFile) 134 c.Assert(err, IsNil) 135 c.Assert(eq, Equals, true) 136 137 // Use 2 coroutines to download the file and total parts count is 5 138 os.Remove(newFile) 139 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(2)) 140 c.Assert(err, IsNil) 141 142 // Check 143 eq, err = compareFiles(fileName, newFile) 144 c.Assert(err, IsNil) 145 c.Assert(eq, Equals, true) 146 147 // Use 5 coroutines to download the file and the total parts count is 5. 148 os.Remove(newFile) 149 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(5)) 150 c.Assert(err, IsNil) 151 152 // Check 153 eq, err = compareFiles(fileName, newFile) 154 c.Assert(err, IsNil) 155 c.Assert(eq, Equals, true) 156 157 // Use 10 coroutines to download the file and the total parts count is 5. 158 os.Remove(newFile) 159 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(10)) 160 c.Assert(err, IsNil) 161 162 // Check 163 eq, err = compareFiles(fileName, newFile) 164 c.Assert(err, IsNil) 165 c.Assert(eq, Equals, true) 166 167 err = s.bucket.DeleteObject(objectName) 168 c.Assert(err, IsNil) 169 } 170 171 // DownErrorHooker requests hook by downloadPart 172 func DownErrorHooker(part downloadPart) error { 173 if part.Index == 4 { 174 time.Sleep(time.Second) 175 return fmt.Errorf("ErrorHooker") 176 } 177 return nil 178 } 179 180 // TestDownloadRoutineWithRecovery multi-routine resumable download 181 func (s *OssDownloadSuite) TestDownloadRoutineWithRecovery(c *C) { 182 objectName := objectNamePrefix + RandStr(8) 183 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 184 newFile := RandStr(8) + ".jpg" 185 186 // Upload a file 187 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 188 c.Assert(err, IsNil) 189 190 // Download a file with default checkpoint 191 downloadPartHooker = DownErrorHooker 192 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, newFile+".cp")) 193 c.Assert(err, NotNil) 194 c.Assert(err.Error(), Equals, "ErrorHooker") 195 downloadPartHooker = defaultDownloadPartHook 196 197 // Check 198 dcp := downloadCheckpoint{} 199 err = dcp.load(newFile + ".cp") 200 c.Assert(err, IsNil) 201 c.Assert(dcp.Magic, Equals, downloadCpMagic) 202 c.Assert(len(dcp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ==")) 203 c.Assert(dcp.FilePath, Equals, newFile) 204 c.Assert(dcp.ObjStat.Size, Equals, int64(482048)) 205 c.Assert(len(dcp.ObjStat.LastModified) > 0, Equals, true) 206 c.Assert(dcp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"") 207 c.Assert(dcp.Object, Equals, objectName) 208 c.Assert(len(dcp.Parts), Equals, 5) 209 c.Assert(len(dcp.todoParts()), Equals, 1) 210 211 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, newFile+".cp")) 212 c.Assert(err, IsNil) 213 //download success, checkpoint file has been deleted 214 err = dcp.load(newFile + ".cp") 215 c.Assert(err, NotNil) 216 217 eq, err := compareFiles(fileName, newFile) 218 c.Assert(err, IsNil) 219 c.Assert(eq, Equals, true) 220 221 // Resumable download with empty checkpoint file path 222 downloadPartHooker = DownErrorHooker 223 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, "")) 224 c.Assert(err, NotNil) 225 c.Assert(err.Error(), Equals, "ErrorHooker") 226 downloadPartHooker = defaultDownloadPartHook 227 228 dcp = downloadCheckpoint{} 229 err = dcp.load(newFile + ".cp") 230 c.Assert(err, NotNil) 231 232 // Resumable download with checkpoint dir 233 os.Remove(newFile) 234 downloadPartHooker = DownErrorHooker 235 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, CheckpointDir(true, "./")) 236 c.Assert(err, NotNil) 237 c.Assert(err.Error(), Equals, "ErrorHooker") 238 downloadPartHooker = defaultDownloadPartHook 239 240 // Check 241 dcp = downloadCheckpoint{} 242 cpConf := cpConfig{IsEnable: true, DirPath: "./"} 243 cpFilePath := getDownloadCpFilePath(&cpConf, s.bucket.BucketName, objectName, "", newFile) 244 err = dcp.load(cpFilePath) 245 c.Assert(err, IsNil) 246 c.Assert(dcp.Magic, Equals, downloadCpMagic) 247 c.Assert(len(dcp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ==")) 248 c.Assert(dcp.FilePath, Equals, newFile) 249 c.Assert(dcp.ObjStat.Size, Equals, int64(482048)) 250 c.Assert(len(dcp.ObjStat.LastModified) > 0, Equals, true) 251 c.Assert(dcp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"") 252 c.Assert(dcp.Object, Equals, objectName) 253 c.Assert(len(dcp.Parts), Equals, 5) 254 c.Assert(len(dcp.todoParts()), Equals, 1) 255 256 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, CheckpointDir(true, "./")) 257 c.Assert(err, IsNil) 258 //download success, checkpoint file has been deleted 259 err = dcp.load(cpFilePath) 260 c.Assert(err, NotNil) 261 262 eq, err = compareFiles(fileName, newFile) 263 c.Assert(err, IsNil) 264 c.Assert(eq, Equals, true) 265 266 // Resumable download with checkpoint at a time. No error is expected in the download procedure. 267 os.Remove(newFile) 268 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, newFile+".cp")) 269 c.Assert(err, IsNil) 270 271 err = dcp.load(newFile + ".cp") 272 c.Assert(err, NotNil) 273 274 eq, err = compareFiles(fileName, newFile) 275 c.Assert(err, IsNil) 276 c.Assert(eq, Equals, true) 277 278 // Resumable download with checkpoint at a time. No error is expected in the download procedure. 279 os.Remove(newFile) 280 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(10), Checkpoint(true, newFile+".cp")) 281 c.Assert(err, IsNil) 282 283 err = dcp.load(newFile + ".cp") 284 c.Assert(err, NotNil) 285 286 eq, err = compareFiles(fileName, newFile) 287 c.Assert(err, IsNil) 288 c.Assert(eq, Equals, true) 289 290 err = s.bucket.DeleteObject(objectName) 291 c.Assert(err, IsNil) 292 } 293 294 // TestDownloadOption options 295 func (s *OssDownloadSuite) TestDownloadOption(c *C) { 296 objectName := objectNamePrefix + RandStr(8) 297 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 298 newFile := RandStr(8) + ".jpg" 299 300 // Upload the file 301 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 302 c.Assert(err, IsNil) 303 304 meta, err := s.bucket.GetObjectDetailedMeta(objectName) 305 c.Assert(err, IsNil) 306 307 // IfMatch 308 os.Remove(newFile) 309 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), IfMatch(meta.Get("Etag"))) 310 c.Assert(err, IsNil) 311 312 eq, err := compareFiles(fileName, newFile) 313 c.Assert(err, IsNil) 314 c.Assert(eq, Equals, true) 315 316 // IfNoneMatch 317 os.Remove(newFile) 318 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), IfNoneMatch(meta.Get("Etag"))) 319 c.Assert(err, NotNil) 320 321 // IfMatch 322 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), IfMatch(meta.Get("Etag"))) 323 c.Assert(err, IsNil) 324 325 eq, err = compareFiles(fileName, newFile) 326 c.Assert(err, IsNil) 327 c.Assert(eq, Equals, true) 328 329 // IfNoneMatch 330 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), IfNoneMatch(meta.Get("Etag"))) 331 c.Assert(err, NotNil) 332 } 333 334 // TestDownloadObjectChange tests the file is updated during the upload 335 func (s *OssDownloadSuite) TestDownloadObjectChange(c *C) { 336 objectName := objectNamePrefix + RandStr(8) 337 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 338 newFile := RandStr(8) + ".jpg" 339 340 // Upload a file 341 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 342 c.Assert(err, IsNil) 343 344 // Download with default checkpoint 345 downloadPartHooker = DownErrorHooker 346 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, newFile+".cp")) 347 c.Assert(err, NotNil) 348 c.Assert(err.Error(), Equals, "ErrorHooker") 349 downloadPartHooker = defaultDownloadPartHook 350 351 err = s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 352 c.Assert(err, IsNil) 353 354 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Checkpoint(true, newFile+".cp")) 355 c.Assert(err, IsNil) 356 357 eq, err := compareFiles(fileName, newFile) 358 c.Assert(err, IsNil) 359 c.Assert(eq, Equals, true) 360 } 361 362 // TestDownloadNegative tests downloading negative 363 func (s *OssDownloadSuite) TestDownloadNegative(c *C) { 364 objectName := objectNamePrefix + RandStr(8) 365 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 366 newFile := RandStr(8) + ".jpg" 367 368 // Upload a file 369 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 370 c.Assert(err, IsNil) 371 372 // Worker routine error 373 downloadPartHooker = DownErrorHooker 374 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(2)) 375 c.Assert(err, NotNil) 376 c.Assert(err.Error(), Equals, "ErrorHooker") 377 downloadPartHooker = defaultDownloadPartHook 378 379 // Local file does not exist 380 err = s.bucket.DownloadFile(objectName, "/tmp/", 100*1024, Routines(2)) 381 c.Assert(err, NotNil) 382 383 // Invalid part size 384 err = s.bucket.DownloadFile(objectName, newFile, 0, Routines(2)) 385 c.Assert(err, NotNil) 386 387 err = s.bucket.DownloadFile(objectName, newFile, 1024*1024*1024*100, Routines(2)) 388 c.Assert(err, IsNil) 389 390 err = s.bucket.DeleteObject(objectName) 391 c.Assert(err, IsNil) 392 393 // Local file does not exist 394 err = s.bucket.DownloadFile(objectName, "/tmp/", 100*1024) 395 c.Assert(err, NotNil) 396 397 err = s.bucket.DownloadFile(objectName, "/tmp/", 100*1024, Routines(2)) 398 c.Assert(err, NotNil) 399 400 // Invalid part size 401 err = s.bucket.DownloadFile(objectName, newFile, -1) 402 c.Assert(err, NotNil) 403 404 err = s.bucket.DownloadFile(objectName, newFile, 0, Routines(2)) 405 c.Assert(err, NotNil) 406 407 err = s.bucket.DownloadFile(objectName, newFile, 1024*1024*1024*100) 408 c.Assert(err, NotNil) 409 410 err = s.bucket.DownloadFile(objectName, newFile, 1024*1024*1024*100, Routines(2)) 411 c.Assert(err, NotNil) 412 } 413 414 // TestDownloadWithRange tests concurrent downloading with range specified and checkpoint enabled 415 func (s *OssDownloadSuite) TestDownloadWithRange(c *C) { 416 objectName := objectNamePrefix + RandStr(8) 417 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 418 newFile := RandStr(8) + ".jpg" 419 newFileGet := RandStr(8) + "-.jpg" 420 421 // Upload a file 422 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3)) 423 c.Assert(err, IsNil) 424 425 fileSize, err := getFileSize(fileName) 426 c.Assert(err, IsNil) 427 428 // Download with range, from 1024 to 4096 429 os.Remove(newFile) 430 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), Range(1024, 4095)) 431 c.Assert(err, IsNil) 432 433 // Check 434 eq, err := compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 435 c.Assert(err, IsNil) 436 c.Assert(eq, Equals, true) 437 438 os.Remove(newFileGet) 439 err = s.bucket.GetObjectToFile(objectName, newFileGet, Range(1024, 4095)) 440 c.Assert(err, IsNil) 441 442 // Compare get and download 443 eq, err = compareFiles(newFile, newFileGet) 444 c.Assert(err, IsNil) 445 c.Assert(eq, Equals, true) 446 447 // Download with range, from 1024 to 4096 448 os.Remove(newFile) 449 err = s.bucket.DownloadFile(objectName, newFile, 1024, Routines(3), NormalizedRange("1024-4095")) 450 c.Assert(err, IsNil) 451 452 // Check 453 eq, err = compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 454 c.Assert(err, IsNil) 455 c.Assert(eq, Equals, true) 456 457 os.Remove(newFileGet) 458 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("1024-4095")) 459 c.Assert(err, IsNil) 460 461 // Compare get and download 462 eq, err = compareFiles(newFile, newFileGet) 463 c.Assert(err, IsNil) 464 c.Assert(eq, Equals, true) 465 466 // Download with range, from 2048 to the end 467 os.Remove(newFile) 468 err = s.bucket.DownloadFile(objectName, newFile, 1024*1024, Routines(3), NormalizedRange("2048-")) 469 c.Assert(err, IsNil) 470 471 // Check 472 eq, err = compareFilesWithRange(fileName, 2048, newFile, 0, fileSize-2048) 473 c.Assert(err, IsNil) 474 c.Assert(eq, Equals, true) 475 476 os.Remove(newFileGet) 477 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("2048-")) 478 c.Assert(err, IsNil) 479 480 // Compare get and download 481 eq, err = compareFiles(newFile, newFileGet) 482 c.Assert(err, IsNil) 483 c.Assert(eq, Equals, true) 484 485 // Download with range, the last 4096 486 os.Remove(newFile) 487 err = s.bucket.DownloadFile(objectName, newFile, 1024, Routines(3), NormalizedRange("-4096")) 488 c.Assert(err, IsNil) 489 490 // Check 491 eq, err = compareFilesWithRange(fileName, fileSize-4096, newFile, 0, 4096) 492 c.Assert(err, IsNil) 493 c.Assert(eq, Equals, true) 494 495 os.Remove(newFileGet) 496 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("-4096")) 497 c.Assert(err, IsNil) 498 499 // Compare get and download 500 eq, err = compareFiles(newFile, newFileGet) 501 c.Assert(err, IsNil) 502 c.Assert(eq, Equals, true) 503 504 err = s.bucket.DeleteObject(objectName) 505 c.Assert(err, IsNil) 506 } 507 508 // TestDownloadWithCheckoutAndRange tests concurrent downloading with range specified and checkpoint enabled 509 func (s *OssDownloadSuite) TestDownloadWithCheckoutAndRange(c *C) { 510 objectName := objectNamePrefix + RandStr(8) 511 fileName := "../sample/BingWallpaper-2015-11-07.jpg" 512 newFile := RandStr(8) + ".jpg" 513 newFileGet := RandStr(8) + "-get.jpg" 514 515 // Upload a file 516 err := s.bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Checkpoint(true, fileName+".cp")) 517 c.Assert(err, IsNil) 518 519 fileSize, err := getFileSize(fileName) 520 c.Assert(err, IsNil) 521 522 // Download with range, from 1024 to 4096 523 os.Remove(newFile) 524 err = s.bucket.DownloadFile(objectName, newFile, 100*1024, Routines(3), Checkpoint(true, newFile+".cp"), Range(1024, 4095)) 525 c.Assert(err, IsNil) 526 527 // Check 528 eq, err := compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 529 c.Assert(err, IsNil) 530 c.Assert(eq, Equals, true) 531 532 os.Remove(newFileGet) 533 err = s.bucket.GetObjectToFile(objectName, newFileGet, Range(1024, 4095)) 534 c.Assert(err, IsNil) 535 536 // Compare get and download 537 eq, err = compareFiles(newFile, newFileGet) 538 c.Assert(err, IsNil) 539 c.Assert(eq, Equals, true) 540 541 // Download with range, from 1024 to 4096 542 os.Remove(newFile) 543 err = s.bucket.DownloadFile(objectName, newFile, 1024, Routines(3), Checkpoint(true, newFile+".cp"), NormalizedRange("1024-4095")) 544 c.Assert(err, IsNil) 545 546 // Check 547 eq, err = compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 548 c.Assert(err, IsNil) 549 c.Assert(eq, Equals, true) 550 551 os.Remove(newFileGet) 552 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("1024-4095")) 553 c.Assert(err, IsNil) 554 555 // Compare get and download 556 eq, err = compareFiles(newFile, newFileGet) 557 c.Assert(err, IsNil) 558 c.Assert(eq, Equals, true) 559 560 // Download with range, from 2048 to the end 561 os.Remove(newFile) 562 err = s.bucket.DownloadFile(objectName, newFile, 1024*1024, Routines(3), Checkpoint(true, newFile+".cp"), NormalizedRange("2048-")) 563 c.Assert(err, IsNil) 564 565 // Check 566 eq, err = compareFilesWithRange(fileName, 2048, newFile, 0, fileSize-2048) 567 c.Assert(err, IsNil) 568 c.Assert(eq, Equals, true) 569 570 os.Remove(newFileGet) 571 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("2048-")) 572 c.Assert(err, IsNil) 573 574 // Compare get and download 575 eq, err = compareFiles(newFile, newFileGet) 576 c.Assert(err, IsNil) 577 c.Assert(eq, Equals, true) 578 579 // Download with range, the last 4096 bytes 580 os.Remove(newFile) 581 err = s.bucket.DownloadFile(objectName, newFile, 1024, Routines(3), Checkpoint(true, newFile+".cp"), NormalizedRange("-4096")) 582 c.Assert(err, IsNil) 583 584 // Check 585 eq, err = compareFilesWithRange(fileName, fileSize-4096, newFile, 0, 4096) 586 c.Assert(err, IsNil) 587 c.Assert(eq, Equals, true) 588 589 os.Remove(newFileGet) 590 err = s.bucket.GetObjectToFile(objectName, newFileGet, NormalizedRange("-4096")) 591 c.Assert(err, IsNil) 592 593 // Compare get and download 594 eq, err = compareFiles(newFile, newFileGet) 595 c.Assert(err, IsNil) 596 c.Assert(eq, Equals, true) 597 598 err = s.bucket.DeleteObject(objectName) 599 c.Assert(err, IsNil) 600 } 601 602 // TestCombineCRCInDownloadParts tests combineCRCInParts 603 func (s *OssDownloadSuite) TestCombineCRCInDownloadParts(c *C) { 604 crc := combineCRCInParts(nil) 605 c.Assert(crc == 0, Equals, true) 606 607 crc = combineCRCInParts(make([]downloadPart, 0)) 608 c.Assert(crc == 0, Equals, true) 609 610 parts := make([]downloadPart, 1) 611 parts[0].CRC64 = 10278880121275185425 612 crc = combineCRCInParts(parts) 613 c.Assert(crc == 10278880121275185425, Equals, true) 614 615 parts = make([]downloadPart, 2) 616 parts[0].CRC64 = 6748440630437108969 617 parts[0].Start = 0 618 parts[0].End = 4 619 parts[1].CRC64 = 10278880121275185425 620 parts[1].Start = 5 621 parts[1].End = 8 622 crc = combineCRCInParts(parts) 623 c.Assert(crc == 11051210869376104954, Equals, true) 624 } 625 626 func getFileSize(fileName string) (int64, error) { 627 file, err := os.Open(fileName) 628 if err != nil { 629 return 0, err 630 } 631 defer file.Close() 632 633 stat, err := file.Stat() 634 if err != nil { 635 return 0, err 636 } 637 638 return stat.Size(), nil 639 } 640 641 // compareFilesWithRange compares the content between fileL and fileR with specified range 642 func compareFilesWithRange(fileL string, offsetL int64, fileR string, offsetR int64, size int64) (bool, error) { 643 finL, err := os.Open(fileL) 644 if err != nil { 645 return false, err 646 } 647 defer finL.Close() 648 finL.Seek(offsetL, os.SEEK_SET) 649 650 finR, err := os.Open(fileR) 651 if err != nil { 652 return false, err 653 } 654 defer finR.Close() 655 finR.Seek(offsetR, os.SEEK_SET) 656 657 statL, err := finL.Stat() 658 if err != nil { 659 return false, err 660 } 661 662 statR, err := finR.Stat() 663 if err != nil { 664 return false, err 665 } 666 667 if (offsetL+size > statL.Size()) || (offsetR+size > statR.Size()) { 668 return false, nil 669 } 670 671 part := statL.Size() - offsetL 672 if part > 16*1024 { 673 part = 16 * 1024 674 } 675 676 bufL := make([]byte, part) 677 bufR := make([]byte, part) 678 for readN := int64(0); readN < size; { 679 n, _ := finL.Read(bufL) 680 if 0 == n { 681 break 682 } 683 684 n, _ = finR.Read(bufR) 685 if 0 == n { 686 break 687 } 688 689 tailer := part 690 if tailer > size-readN { 691 tailer = size - readN 692 } 693 readN += tailer 694 695 if !bytes.Equal(bufL[0:tailer], bufR[0:tailer]) { 696 return false, nil 697 } 698 } 699 700 return true, nil 701 } 702 703 func (s *OssDownloadSuite) TestVersioningDownloadWithoutCheckPoint(c *C) { 704 // create a bucket with default proprety 705 client, err := New(endpoint, accessID, accessKey) 706 c.Assert(err, IsNil) 707 708 bucketName := bucketNamePrefix + RandLowStr(6) 709 err = client.CreateBucket(bucketName) 710 c.Assert(err, IsNil) 711 712 bucket, err := client.Bucket(bucketName) 713 714 // put bucket version:enabled 715 var versioningConfig VersioningConfig 716 versioningConfig.Status = string(VersionEnabled) 717 err = client.SetBucketVersioning(bucketName, versioningConfig) 718 c.Assert(err, IsNil) 719 time.Sleep(timeoutInOperation) 720 721 // begin test 722 objectName := objectNamePrefix + RandStr(8) 723 fileName := "test-file-" + RandStr(8) 724 fileData := RandStr(500 * 1024) 725 CreateFile(fileName, fileData, c) 726 727 newFile := RandStr(8) + ".jpg" 728 newFileGet := RandStr(8) + "-.jpg" 729 730 // Upload a file 731 var respHeader http.Header 732 options := []Option{Routines(3), GetResponseHeader(&respHeader)} 733 err = bucket.UploadFile(objectName, fileName, 100*1024, options...) 734 c.Assert(err, IsNil) 735 versionId := GetVersionId(respHeader) 736 c.Assert(len(versionId) > 0, Equals, true) 737 738 fileSize, err := getFileSize(fileName) 739 c.Assert(err, IsNil) 740 741 // overwrite emtpy object 742 err = bucket.PutObject(objectName, strings.NewReader("")) 743 c.Assert(err, IsNil) 744 745 // Download with range, from 1024 to 4096 746 os.Remove(newFile) 747 options = []Option{Routines(3), Range(1024, 4095), VersionId(versionId)} 748 err = bucket.DownloadFile(objectName, newFile, 100*1024, options...) 749 c.Assert(err, IsNil) 750 751 // Check 752 eq, err := compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 753 c.Assert(err, IsNil) 754 c.Assert(eq, Equals, true) 755 756 os.Remove(newFileGet) 757 options = []Option{Range(1024, 4095), VersionId(versionId)} 758 err = bucket.GetObjectToFile(objectName, newFileGet, options...) 759 c.Assert(err, IsNil) 760 761 // Compare get and download 762 eq, err = compareFiles(newFile, newFileGet) 763 c.Assert(err, IsNil) 764 c.Assert(eq, Equals, true) 765 766 // Download with range, from 1024 to 4096 767 os.Remove(newFile) 768 options = []Option{Routines(3), NormalizedRange("1024-4095"), VersionId(versionId)} 769 err = bucket.DownloadFile(objectName, newFile, 1024, options...) 770 c.Assert(err, IsNil) 771 772 // Check 773 eq, err = compareFilesWithRange(fileName, 1024, newFile, 0, 3072) 774 c.Assert(err, IsNil) 775 c.Assert(eq, Equals, true) 776 777 os.Remove(newFileGet) 778 options = []Option{NormalizedRange("1024-4095"), VersionId(versionId)} 779 err = bucket.GetObjectToFile(objectName, newFileGet, options...) 780 c.Assert(err, IsNil) 781 782 // Compare get and download 783 eq, err = compareFiles(newFile, newFileGet) 784 c.Assert(err, IsNil) 785 c.Assert(eq, Equals, true) 786 787 // Download with range, from 2048 to the end 788 os.Remove(newFile) 789 options = []Option{NormalizedRange("2048-"), VersionId(versionId)} 790 err = bucket.DownloadFile(objectName, newFile, 1024*1024, options...) 791 c.Assert(err, IsNil) 792 793 // Check 794 eq, err = compareFilesWithRange(fileName, 2048, newFile, 0, fileSize-2048) 795 c.Assert(err, IsNil) 796 c.Assert(eq, Equals, true) 797 798 os.Remove(newFileGet) 799 options = []Option{NormalizedRange("2048-"), VersionId(versionId)} 800 err = bucket.GetObjectToFile(objectName, newFileGet, options...) 801 c.Assert(err, IsNil) 802 803 // Compare get and download 804 eq, err = compareFiles(newFile, newFileGet) 805 c.Assert(err, IsNil) 806 c.Assert(eq, Equals, true) 807 808 // Download with range, the last 4096 809 os.Remove(newFile) 810 options = []Option{Routines(3), NormalizedRange("-4096"), VersionId(versionId)} 811 err = bucket.DownloadFile(objectName, newFile, 1024, options...) 812 c.Assert(err, IsNil) 813 814 // Check 815 eq, err = compareFilesWithRange(fileName, fileSize-4096, newFile, 0, 4096) 816 c.Assert(err, IsNil) 817 c.Assert(eq, Equals, true) 818 819 os.Remove(newFileGet) 820 options = []Option{NormalizedRange("-4096"), VersionId(versionId)} 821 err = bucket.GetObjectToFile(objectName, newFileGet, options...) 822 c.Assert(err, IsNil) 823 824 // Compare get and download 825 eq, err = compareFiles(newFile, newFileGet) 826 c.Assert(err, IsNil) 827 c.Assert(eq, Equals, true) 828 829 // download whole file 830 os.Remove(newFileGet) 831 options = []Option{Routines(3), VersionId(versionId)} 832 err = bucket.GetObjectToFile(objectName, newFileGet, options...) 833 c.Assert(err, IsNil) 834 835 // Compare get and download 836 eq, err = compareFiles(fileName, newFileGet) 837 c.Assert(err, IsNil) 838 c.Assert(eq, Equals, true) 839 840 os.Remove(fileName) 841 os.Remove(newFileGet) 842 err = bucket.DeleteObject(objectName) 843 c.Assert(err, IsNil) 844 ForceDeleteBucket(client, bucketName, c) 845 } 846 847 func (s *OssDownloadSuite) TestVersioningDownloadWithCheckPoint(c *C) { 848 // create a bucket with default proprety 849 client, err := New(endpoint, accessID, accessKey) 850 c.Assert(err, IsNil) 851 852 bucketName := bucketNamePrefix + RandLowStr(6) 853 err = client.CreateBucket(bucketName) 854 c.Assert(err, IsNil) 855 856 bucket, err := client.Bucket(bucketName) 857 858 // put bucket version:enabled 859 var versioningConfig VersioningConfig 860 versioningConfig.Status = string(VersionEnabled) 861 err = client.SetBucketVersioning(bucketName, versioningConfig) 862 c.Assert(err, IsNil) 863 time.Sleep(timeoutInOperation) 864 865 // begin test 866 objectName := objectNamePrefix + RandStr(8) 867 fileName := "test-file-" + RandStr(8) 868 fileData := RandStr(500 * 1024) 869 CreateFile(fileName, fileData, c) 870 newFile := RandStr(8) + ".jpg" 871 872 // Upload a file 873 var respHeader http.Header 874 options := []Option{Routines(3), GetResponseHeader(&respHeader)} 875 err = bucket.UploadFile(objectName, fileName, 100*1024, options...) 876 c.Assert(err, IsNil) 877 versionId := GetVersionId(respHeader) 878 c.Assert(len(versionId) > 0, Equals, true) 879 880 // Resumable download with checkpoint dir 881 os.Remove(newFile) 882 downloadPartHooker = DownErrorHooker 883 options = []Option{CheckpointDir(true, "./"), VersionId(versionId)} 884 885 strPayer := getPayer(options) 886 c.Assert(strPayer, Equals, "") 887 888 err = bucket.DownloadFile(objectName, newFile, 100*1024, options...) 889 c.Assert(err, NotNil) 890 c.Assert(err.Error(), Equals, "ErrorHooker") 891 892 // download again 893 downloadPartHooker = defaultDownloadPartHook 894 options = []Option{CheckpointDir(true, "./"), VersionId(versionId), GetResponseHeader(&respHeader)} 895 err = bucket.DownloadFile(objectName, newFile, 100*1024, options...) 896 c.Assert(err, IsNil) 897 c.Assert(GetVersionId(respHeader), Equals, versionId) 898 899 eq, err := compareFiles(fileName, newFile) 900 c.Assert(err, IsNil) 901 c.Assert(eq, Equals, true) 902 903 os.Remove(fileName) 904 os.Remove(newFile) 905 err = bucket.DeleteObject(objectName) 906 c.Assert(err, IsNil) 907 ForceDeleteBucket(client, bucketName, c) 908 } 909 910 func (s *OssDownloadSuite) TestdownloadFileChoiceOptions(c *C) { 911 // create a bucket with default proprety 912 client, err := New(endpoint, accessID, accessKey) 913 c.Assert(err, IsNil) 914 915 bucketName := bucketNamePrefix + RandLowStr(6) 916 err = client.CreateBucket(bucketName) 917 c.Assert(err, IsNil) 918 919 bucket, err := client.Bucket(bucketName) 920 921 // begin test 922 objectName := objectNamePrefix + RandStr(8) 923 fileName := "test-file-" + RandStr(8) 924 fileData := RandStr(500 * 1024) 925 CreateFile(fileName, fileData, c) 926 newFile := RandStr(8) + ".jpg" 927 928 // Upload a file 929 var respHeader http.Header 930 options := []Option{Routines(3), GetResponseHeader(&respHeader)} 931 err = bucket.UploadFile(objectName, fileName, 100*1024, options...) 932 c.Assert(err, IsNil) 933 934 // Resumable download with checkpoint dir 935 os.Remove(newFile) 936 937 // downloadFile with properties 938 options = []Option{ 939 ObjectACL(ACLPublicRead), 940 RequestPayer(Requester), 941 TrafficLimitHeader(1024 * 1024 * 8), 942 } 943 944 err = bucket.DownloadFile(objectName, newFile, 100*1024, options...) 945 c.Assert(err, IsNil) 946 947 eq, err := compareFiles(fileName, newFile) 948 c.Assert(err, IsNil) 949 c.Assert(eq, Equals, true) 950 951 os.Remove(fileName) 952 os.Remove(newFile) 953 err = bucket.DeleteObject(objectName) 954 c.Assert(err, IsNil) 955 ForceDeleteBucket(client, bucketName, c) 956 } 957 958 func (s *OssDownloadSuite) TestdownloadFileWithCpChoiceOptions(c *C) { 959 // create a bucket with default proprety 960 client, err := New(endpoint, accessID, accessKey) 961 c.Assert(err, IsNil) 962 963 bucketName := bucketNamePrefix + RandLowStr(6) 964 err = client.CreateBucket(bucketName) 965 c.Assert(err, IsNil) 966 967 bucket, err := client.Bucket(bucketName) 968 969 // begin test 970 objectName := objectNamePrefix + RandStr(8) 971 fileName := "test-file-" + RandStr(8) 972 fileData := RandStr(500 * 1024) 973 CreateFile(fileName, fileData, c) 974 newFile := RandStr(8) + ".jpg" 975 976 // Upload a file 977 var respHeader http.Header 978 options := []Option{Routines(3), GetResponseHeader(&respHeader)} 979 err = bucket.UploadFile(objectName, fileName, 100*1024, options...) 980 c.Assert(err, IsNil) 981 982 // Resumable download with checkpoint dir 983 os.Remove(newFile) 984 985 // DownloadFile with properties 986 options = []Option{ 987 ObjectACL(ACLPublicRead), 988 RequestPayer(Requester), 989 TrafficLimitHeader(1024 * 1024 * 8), 990 CheckpointDir(true, "./"), 991 } 992 993 err = bucket.DownloadFile(objectName, newFile, 100*1024, options...) 994 c.Assert(err, IsNil) 995 996 eq, err := compareFiles(fileName, newFile) 997 c.Assert(err, IsNil) 998 c.Assert(eq, Equals, true) 999 1000 os.Remove(fileName) 1001 os.Remove(newFile) 1002 err = bucket.DeleteObject(objectName) 1003 c.Assert(err, IsNil) 1004 ForceDeleteBucket(client, bucketName, c) 1005 }