github.com/aliyun/aliyun-oss-go-sdk@v3.0.2+incompatible/oss/multicopy_test.go (about)

     1  package oss
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	. "gopkg.in/check.v1"
    11  )
    12  
    13  type OssCopySuite struct {
    14  	cloudBoxControlClient *Client
    15  	client                *Client
    16  	bucket                *Bucket
    17  }
    18  
    19  var _ = Suite(&OssCopySuite{})
    20  
    21  // SetUpSuite runs once when the suite starts running
    22  func (s *OssCopySuite) SetUpSuite(c *C) {
    23  	bucketName := bucketNamePrefix + RandLowStr(6)
    24  	if cloudboxControlEndpoint == "" {
    25  		client, err := New(endpoint, accessID, accessKey)
    26  		c.Assert(err, IsNil)
    27  		s.client = client
    28  
    29  		s.client.CreateBucket(bucketName)
    30  
    31  		bucket, err := s.client.Bucket(bucketName)
    32  		c.Assert(err, IsNil)
    33  		s.bucket = bucket
    34  	} else {
    35  		client, err := New(cloudboxEndpoint, accessID, accessKey)
    36  		c.Assert(err, IsNil)
    37  		s.client = client
    38  
    39  		controlClient, err := New(cloudboxControlEndpoint, accessID, accessKey)
    40  		c.Assert(err, IsNil)
    41  		s.cloudBoxControlClient = controlClient
    42  		controlClient.CreateBucket(bucketName)
    43  
    44  		bucket, err := s.client.Bucket(bucketName)
    45  		c.Assert(err, IsNil)
    46  		s.bucket = bucket
    47  	}
    48  
    49  	testLogger.Println("test copy started")
    50  }
    51  
    52  // TearDownSuite runs before each test or benchmark starts running
    53  func (s *OssCopySuite) TearDownSuite(c *C) {
    54  	// Delete Part
    55  	keyMarker := KeyMarker("")
    56  	uploadIDMarker := UploadIDMarker("")
    57  	for {
    58  		lmur, err := s.bucket.ListMultipartUploads(keyMarker, uploadIDMarker)
    59  		c.Assert(err, IsNil)
    60  		for _, upload := range lmur.Uploads {
    61  			var imur = InitiateMultipartUploadResult{Bucket: bucketName,
    62  				Key: upload.Key, UploadID: upload.UploadID}
    63  			err = s.bucket.AbortMultipartUpload(imur)
    64  			c.Assert(err, IsNil)
    65  		}
    66  		keyMarker = KeyMarker(lmur.NextKeyMarker)
    67  		uploadIDMarker = UploadIDMarker(lmur.NextUploadIDMarker)
    68  		if !lmur.IsTruncated {
    69  			break
    70  		}
    71  	}
    72  
    73  	// Delete objects
    74  	marker := Marker("")
    75  	for {
    76  		lor, err := s.bucket.ListObjects(marker)
    77  		c.Assert(err, IsNil)
    78  		for _, object := range lor.Objects {
    79  			err = s.bucket.DeleteObject(object.Key)
    80  			c.Assert(err, IsNil)
    81  		}
    82  		marker = Marker(lor.NextMarker)
    83  		if !lor.IsTruncated {
    84  			break
    85  		}
    86  	}
    87  
    88  	// Delete bucket
    89  	if s.cloudBoxControlClient != nil {
    90  		err := s.cloudBoxControlClient.DeleteBucket(s.bucket.BucketName)
    91  		c.Assert(err, IsNil)
    92  	} else {
    93  		err := s.client.DeleteBucket(s.bucket.BucketName)
    94  		c.Assert(err, IsNil)
    95  	}
    96  
    97  	testLogger.Println("test copy completed")
    98  }
    99  
   100  // SetUpTest runs after each test or benchmark runs
   101  func (s *OssCopySuite) SetUpTest(c *C) {
   102  	err := removeTempFiles("../oss", ".jpg")
   103  	c.Assert(err, IsNil)
   104  }
   105  
   106  // TearDownTest runs once after all tests or benchmarks have finished running
   107  func (s *OssCopySuite) TearDownTest(c *C) {
   108  	err := removeTempFiles("../oss", ".jpg")
   109  	c.Assert(err, IsNil)
   110  }
   111  
   112  // TestCopyRoutineWithoutRecovery is multi-routine copy without resumable recovery
   113  func (s *OssCopySuite) TestCopyRoutineWithoutRecovery(c *C) {
   114  	srcObjectName := objectNamePrefix + RandStr(8)
   115  	destObjectName := srcObjectName + "-dest"
   116  	fileName := "../sample/BingWallpaper-2015-11-07.jpg"
   117  	newFile := "copy-new-file.jpg"
   118  
   119  	// Upload source file
   120  	err := s.bucket.UploadFile(srcObjectName, fileName, 100*1024, Routines(3))
   121  	c.Assert(err, IsNil)
   122  	os.Remove(newFile)
   123  
   124  	// Does not specify parameter 'routines', by default it's single routine
   125  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024)
   126  	c.Assert(err, IsNil)
   127  
   128  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   129  	c.Assert(err, IsNil)
   130  
   131  	eq, err := compareFiles(fileName, newFile)
   132  	c.Assert(err, IsNil)
   133  	c.Assert(eq, Equals, true)
   134  
   135  	err = s.bucket.DeleteObject(destObjectName)
   136  	c.Assert(err, IsNil)
   137  	os.Remove(newFile)
   138  
   139  	// Specify one routine.
   140  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(1))
   141  	c.Assert(err, IsNil)
   142  
   143  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   144  	c.Assert(err, IsNil)
   145  
   146  	eq, err = compareFiles(fileName, newFile)
   147  	c.Assert(err, IsNil)
   148  	c.Assert(eq, Equals, true)
   149  
   150  	err = s.bucket.DeleteObject(destObjectName)
   151  	c.Assert(err, IsNil)
   152  	os.Remove(newFile)
   153  
   154  	// Specify three routines, which is less than parts count 5
   155  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(3))
   156  	c.Assert(err, IsNil)
   157  
   158  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   159  	c.Assert(err, IsNil)
   160  
   161  	eq, err = compareFiles(fileName, newFile)
   162  	c.Assert(err, IsNil)
   163  	c.Assert(eq, Equals, true)
   164  
   165  	err = s.bucket.DeleteObject(destObjectName)
   166  	c.Assert(err, IsNil)
   167  	os.Remove(newFile)
   168  
   169  	// Specify 5 routines which is the same as parts count
   170  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(5))
   171  	c.Assert(err, IsNil)
   172  
   173  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   174  	c.Assert(err, IsNil)
   175  
   176  	eq, err = compareFiles(fileName, newFile)
   177  	c.Assert(err, IsNil)
   178  	c.Assert(eq, Equals, true)
   179  
   180  	err = s.bucket.DeleteObject(destObjectName)
   181  	c.Assert(err, IsNil)
   182  	os.Remove(newFile)
   183  
   184  	// Specify routine count 10, which is more than parts count
   185  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(10))
   186  	c.Assert(err, IsNil)
   187  
   188  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   189  	c.Assert(err, IsNil)
   190  
   191  	eq, err = compareFiles(fileName, newFile)
   192  	c.Assert(err, IsNil)
   193  	c.Assert(eq, Equals, true)
   194  
   195  	err = s.bucket.DeleteObject(destObjectName)
   196  	c.Assert(err, IsNil)
   197  	os.Remove(newFile)
   198  
   199  	// Invalid routine count, will use single routine
   200  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(-1))
   201  	c.Assert(err, IsNil)
   202  
   203  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   204  	c.Assert(err, IsNil)
   205  
   206  	eq, err = compareFiles(fileName, newFile)
   207  	c.Assert(err, IsNil)
   208  	c.Assert(eq, Equals, true)
   209  
   210  	err = s.bucket.DeleteObject(destObjectName)
   211  	c.Assert(err, IsNil)
   212  	os.Remove(newFile)
   213  
   214  	// Option
   215  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(3), Meta("myprop", "mypropval"))
   216  
   217  	meta, err := s.bucket.GetObjectDetailedMeta(destObjectName)
   218  	c.Assert(err, IsNil)
   219  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   220  
   221  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   222  	c.Assert(err, IsNil)
   223  
   224  	eq, err = compareFiles(fileName, newFile)
   225  	c.Assert(err, IsNil)
   226  	c.Assert(eq, Equals, true)
   227  
   228  	err = s.bucket.DeleteObject(destObjectName)
   229  	c.Assert(err, IsNil)
   230  	os.Remove(newFile)
   231  
   232  	err = s.bucket.DeleteObject(srcObjectName)
   233  	c.Assert(err, IsNil)
   234  }
   235  
   236  // CopyErrorHooker is a copypart request hook
   237  func CopyErrorHooker(part copyPart) error {
   238  	if part.Number == 5 {
   239  		time.Sleep(time.Second)
   240  		return fmt.Errorf("ErrorHooker")
   241  	}
   242  	return nil
   243  }
   244  
   245  // TestCopyRoutineWithoutRecoveryNegative is a multiple routines copy without checkpoint
   246  func (s *OssCopySuite) TestCopyRoutineWithoutRecoveryNegative(c *C) {
   247  	srcObjectName := objectNamePrefix + RandStr(8)
   248  	destObjectName := srcObjectName + "-dest"
   249  	fileName := "../sample/BingWallpaper-2015-11-07.jpg"
   250  
   251  	// Upload source file
   252  	err := s.bucket.UploadFile(srcObjectName, fileName, 100*1024, Routines(3))
   253  	c.Assert(err, IsNil)
   254  
   255  	copyPartHooker = CopyErrorHooker
   256  	// Worker routine errors
   257  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 100*1024, Routines(2))
   258  
   259  	c.Assert(err, NotNil)
   260  	c.Assert(err.Error(), Equals, "ErrorHooker")
   261  	copyPartHooker = defaultCopyPartHook
   262  
   263  	// Source bucket does not exist
   264  	err = s.bucket.CopyFile("notexist", srcObjectName, destObjectName, 100*1024, Routines(2))
   265  	c.Assert(err, NotNil)
   266  
   267  	// Target object does not exist
   268  	err = s.bucket.CopyFile(s.bucket.BucketName, "notexist", destObjectName, 100*1024, Routines(2))
   269  
   270  	// The part size is invalid
   271  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024, Routines(2))
   272  	c.Assert(err, NotNil)
   273  
   274  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*1024*1024*100, Routines(2))
   275  	c.Assert(err, NotNil)
   276  
   277  	// Delete the source file
   278  	err = s.bucket.DeleteObject(srcObjectName)
   279  	c.Assert(err, IsNil)
   280  }
   281  
   282  // TestCopyRoutineWithRecovery is a multiple routines copy with resumable recovery
   283  func (s *OssCopySuite) TestCopyRoutineWithRecovery(c *C) {
   284  	srcObjectName := objectNamePrefix + RandStr(8)
   285  	destObjectName := srcObjectName + "-dest"
   286  	fileName := "../sample/BingWallpaper-2015-11-07.jpg"
   287  	newFile := RandStr(8) + ".jpg"
   288  
   289  	// Upload source file
   290  	err := s.bucket.UploadFile(srcObjectName, fileName, 100*1024, Routines(3))
   291  	c.Assert(err, IsNil)
   292  	os.Remove(newFile)
   293  
   294  	// Routines default value, CP's default path is destObjectName+.cp
   295  	// Copy object with checkpoint enabled, single runtine.
   296  	// Copy 4 parts---the CopyErrorHooker makes sure the copy of part 5 will fail.
   297  	copyPartHooker = CopyErrorHooker
   298  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Checkpoint(true, destObjectName+".cp"))
   299  	c.Assert(err, NotNil)
   300  	c.Assert(err.Error(), Equals, "ErrorHooker")
   301  	copyPartHooker = defaultCopyPartHook
   302  
   303  	// Check CP
   304  	ccp := copyCheckpoint{}
   305  	err = ccp.load(destObjectName + ".cp")
   306  	c.Assert(err, IsNil)
   307  	c.Assert(ccp.Magic, Equals, copyCpMagic)
   308  	c.Assert(len(ccp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
   309  	c.Assert(ccp.SrcBucketName, Equals, s.bucket.BucketName)
   310  	c.Assert(ccp.SrcObjectKey, Equals, srcObjectName)
   311  	c.Assert(ccp.DestBucketName, Equals, s.bucket.BucketName)
   312  	c.Assert(ccp.DestObjectKey, Equals, destObjectName)
   313  	c.Assert(len(ccp.CopyID), Equals, len("3F79722737D1469980DACEDCA325BB52"))
   314  	c.Assert(ccp.ObjStat.Size, Equals, int64(482048))
   315  	c.Assert(len(ccp.ObjStat.LastModified), Equals, len("2015-12-17 18:43:03 +0800 CST"))
   316  	c.Assert(ccp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"")
   317  	c.Assert(len(ccp.Parts), Equals, 5)
   318  	c.Assert(len(ccp.todoParts()), Equals, 1)
   319  	c.Assert(ccp.PartStat[4], Equals, false)
   320  
   321  	// Second copy, finish the last part
   322  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Checkpoint(true, destObjectName+".cp"))
   323  	c.Assert(err, IsNil)
   324  
   325  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   326  	c.Assert(err, IsNil)
   327  
   328  	eq, err := compareFiles(fileName, newFile)
   329  	c.Assert(err, IsNil)
   330  	c.Assert(eq, Equals, true)
   331  
   332  	err = s.bucket.DeleteObject(destObjectName)
   333  	c.Assert(err, IsNil)
   334  	os.Remove(newFile)
   335  
   336  	err = ccp.load(fileName + ".cp")
   337  	c.Assert(err, NotNil)
   338  
   339  	//multicopy with empty checkpoint path
   340  	copyPartHooker = CopyErrorHooker
   341  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Checkpoint(true, ""))
   342  	c.Assert(err, NotNil)
   343  	c.Assert(err.Error(), Equals, "ErrorHooker")
   344  	copyPartHooker = defaultCopyPartHook
   345  	ccp = copyCheckpoint{}
   346  	err = ccp.load(destObjectName + ".cp")
   347  	c.Assert(err, NotNil)
   348  
   349  	//multi copy with checkpoint dir
   350  	copyPartHooker = CopyErrorHooker
   351  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(2), CheckpointDir(true, "./"))
   352  	c.Assert(err, NotNil)
   353  	c.Assert(err.Error(), Equals, "ErrorHooker")
   354  	copyPartHooker = defaultCopyPartHook
   355  
   356  	// Check CP
   357  	ccp = copyCheckpoint{}
   358  	cpConf := cpConfig{IsEnable: true, DirPath: "./"}
   359  	cpFilePath := getCopyCpFilePath(&cpConf, s.bucket.BucketName, srcObjectName, s.bucket.BucketName, destObjectName, "")
   360  	err = ccp.load(cpFilePath)
   361  	c.Assert(err, IsNil)
   362  	c.Assert(ccp.Magic, Equals, copyCpMagic)
   363  	c.Assert(len(ccp.MD5), Equals, len("LC34jZU5xK4hlxi3Qn3XGQ=="))
   364  	c.Assert(ccp.SrcBucketName, Equals, s.bucket.BucketName)
   365  	c.Assert(ccp.SrcObjectKey, Equals, srcObjectName)
   366  	c.Assert(ccp.DestBucketName, Equals, s.bucket.BucketName)
   367  	c.Assert(ccp.DestObjectKey, Equals, destObjectName)
   368  	c.Assert(len(ccp.CopyID), Equals, len("3F79722737D1469980DACEDCA325BB52"))
   369  	c.Assert(ccp.ObjStat.Size, Equals, int64(482048))
   370  	c.Assert(len(ccp.ObjStat.LastModified), Equals, len("2015-12-17 18:43:03 +0800 CST"))
   371  	c.Assert(ccp.ObjStat.Etag, Equals, "\"2351E662233817A7AE974D8C5B0876DD-5\"")
   372  	c.Assert(len(ccp.Parts), Equals, 5)
   373  	c.Assert(len(ccp.todoParts()), Equals, 1)
   374  	c.Assert(ccp.PartStat[4], Equals, false)
   375  
   376  	// Second copy, finish the last part.
   377  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(2), CheckpointDir(true, "./"))
   378  	c.Assert(err, IsNil)
   379  
   380  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   381  	c.Assert(err, IsNil)
   382  
   383  	eq, err = compareFiles(fileName, newFile)
   384  	c.Assert(err, IsNil)
   385  	c.Assert(eq, Equals, true)
   386  
   387  	err = s.bucket.DeleteObject(destObjectName)
   388  	c.Assert(err, IsNil)
   389  	os.Remove(newFile)
   390  
   391  	err = ccp.load(srcObjectName + ".cp")
   392  	c.Assert(err, NotNil)
   393  
   394  	// First copy without error.
   395  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(3), Checkpoint(true, destObjectName+".cp"))
   396  	c.Assert(err, IsNil)
   397  
   398  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   399  	c.Assert(err, IsNil)
   400  
   401  	eq, err = compareFiles(fileName, newFile)
   402  	c.Assert(err, IsNil)
   403  	c.Assert(eq, Equals, true)
   404  
   405  	err = s.bucket.DeleteObject(destObjectName)
   406  	c.Assert(err, IsNil)
   407  	os.Remove(newFile)
   408  
   409  	// Copy with multiple coroutines, no errors.
   410  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(10), Checkpoint(true, destObjectName+".cp"))
   411  	c.Assert(err, IsNil)
   412  
   413  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   414  	c.Assert(err, IsNil)
   415  
   416  	eq, err = compareFiles(fileName, newFile)
   417  	c.Assert(err, IsNil)
   418  	c.Assert(eq, Equals, true)
   419  
   420  	err = s.bucket.DeleteObject(destObjectName)
   421  	c.Assert(err, IsNil)
   422  	os.Remove(newFile)
   423  
   424  	// Option
   425  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(5), Checkpoint(true, destObjectName+".cp"), Meta("myprop", "mypropval"))
   426  	c.Assert(err, IsNil)
   427  
   428  	meta, err := s.bucket.GetObjectDetailedMeta(destObjectName)
   429  	c.Assert(err, IsNil)
   430  	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
   431  
   432  	err = s.bucket.GetObjectToFile(destObjectName, newFile)
   433  	c.Assert(err, IsNil)
   434  
   435  	eq, err = compareFiles(fileName, newFile)
   436  	c.Assert(err, IsNil)
   437  	c.Assert(eq, Equals, true)
   438  
   439  	err = s.bucket.DeleteObject(destObjectName)
   440  	c.Assert(err, IsNil)
   441  	os.Remove(newFile)
   442  
   443  	// Delete the source file
   444  	err = s.bucket.DeleteObject(srcObjectName)
   445  	c.Assert(err, IsNil)
   446  }
   447  
   448  // TestCopyRoutineWithRecoveryNegative is a multiple routineed copy without checkpoint
   449  func (s *OssCopySuite) TestCopyRoutineWithRecoveryNegative(c *C) {
   450  	srcObjectName := objectNamePrefix + RandStr(8)
   451  	destObjectName := srcObjectName + "-dest"
   452  
   453  	// Source bucket does not exist
   454  	err := s.bucket.CopyFile("notexist", srcObjectName, destObjectName, 100*1024, Checkpoint(true, destObjectName+".cp"))
   455  	c.Assert(err, NotNil)
   456  	c.Assert(err, NotNil)
   457  
   458  	// Source object does not exist
   459  	err = s.bucket.CopyFile(s.bucket.BucketName, "notexist", destObjectName, 100*1024, Routines(2), Checkpoint(true, destObjectName+".cp"))
   460  	c.Assert(err, NotNil)
   461  
   462  	// Specify part size is invalid.
   463  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024, Checkpoint(true, destObjectName+".cp"))
   464  	c.Assert(err, NotNil)
   465  
   466  	err = s.bucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*1024*1024*100, Routines(2), Checkpoint(true, destObjectName+".cp"))
   467  	c.Assert(err, NotNil)
   468  }
   469  
   470  // TestCopyFileCrossBucket is a cross bucket's direct copy.
   471  func (s *OssCopySuite) TestCopyFileCrossBucket(c *C) {
   472  	destBucketName := s.bucket.BucketName + "-cross-b"
   473  	srcObjectName := objectNamePrefix + RandStr(8)
   474  	destObjectName := srcObjectName + "-dest"
   475  	fileName := "../sample/BingWallpaper-2015-11-07.jpg"
   476  	newFile := RandStr(8) + ".jpg"
   477  
   478  	destBucket, err := s.client.Bucket(destBucketName)
   479  	c.Assert(err, IsNil)
   480  
   481  	// Create a target bucket
   482  	err = s.client.CreateBucket(destBucketName)
   483  
   484  	// Upload source file
   485  	err = s.bucket.UploadFile(srcObjectName, fileName, 100*1024, Routines(3))
   486  	c.Assert(err, IsNil)
   487  	os.Remove(newFile)
   488  
   489  	// Copy files
   490  	err = destBucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(5), Checkpoint(true, destObjectName+".cp"))
   491  	c.Assert(err, IsNil)
   492  
   493  	err = destBucket.GetObjectToFile(destObjectName, newFile)
   494  	c.Assert(err, IsNil)
   495  
   496  	eq, err := compareFiles(fileName, newFile)
   497  	c.Assert(err, IsNil)
   498  	c.Assert(eq, Equals, true)
   499  
   500  	err = destBucket.DeleteObject(destObjectName)
   501  	c.Assert(err, IsNil)
   502  	os.Remove(newFile)
   503  
   504  	// Copy file with options
   505  	err = destBucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, Routines(10), Checkpoint(true, "copy.cp"), Meta("myprop", "mypropval"))
   506  	c.Assert(err, IsNil)
   507  
   508  	err = destBucket.GetObjectToFile(destObjectName, newFile)
   509  	c.Assert(err, IsNil)
   510  
   511  	eq, err = compareFiles(fileName, newFile)
   512  	c.Assert(err, IsNil)
   513  	c.Assert(eq, Equals, true)
   514  
   515  	err = destBucket.DeleteObject(destObjectName)
   516  	c.Assert(err, IsNil)
   517  	os.Remove(newFile)
   518  
   519  	// Delete target bucket
   520  	ForceDeleteBucket(s.client, destBucketName, c)
   521  }
   522  
   523  func (s *OssCopySuite) TestVersioningCopyFileCrossBucket(c *C) {
   524  	// create a bucket with default proprety
   525  	client, err := New(endpoint, accessID, accessKey)
   526  	c.Assert(err, IsNil)
   527  
   528  	bucketName := bucketNamePrefix + RandLowStr(6)
   529  	err = client.CreateBucket(bucketName)
   530  	c.Assert(err, IsNil)
   531  
   532  	bucket, err := client.Bucket(bucketName)
   533  
   534  	// put bucket version:enabled
   535  	var versioningConfig VersioningConfig
   536  	versioningConfig.Status = string(VersionEnabled)
   537  	err = client.SetBucketVersioning(bucketName, versioningConfig)
   538  	c.Assert(err, IsNil)
   539  
   540  	// begin test
   541  	objectName := objectNamePrefix + RandStr(8)
   542  	fileName := "test-file-" + RandStr(8)
   543  	fileData := RandStr(500 * 1024)
   544  	CreateFile(fileName, fileData, c)
   545  	newFile := "test-file-" + RandStr(8)
   546  	destBucketName := bucketName + "-desc"
   547  	srcObjectName := objectNamePrefix + RandStr(8)
   548  	destObjectName := srcObjectName + "-dest"
   549  
   550  	// Create dest bucket
   551  	err = client.CreateBucket(destBucketName)
   552  	c.Assert(err, IsNil)
   553  	destBucket, err := client.Bucket(destBucketName)
   554  	c.Assert(err, IsNil)
   555  
   556  	err = client.SetBucketVersioning(destBucketName, versioningConfig)
   557  	c.Assert(err, IsNil)
   558  
   559  	// Upload source file
   560  	var respHeader http.Header
   561  	options := []Option{Routines(3), GetResponseHeader(&respHeader)}
   562  	err = bucket.UploadFile(srcObjectName, fileName, 100*1024, options...)
   563  	versionId := GetVersionId(respHeader)
   564  	c.Assert(len(versionId) > 0, Equals, true)
   565  
   566  	c.Assert(err, IsNil)
   567  	os.Remove(newFile)
   568  
   569  	// overwrite emtpy object
   570  	err = bucket.PutObject(srcObjectName, strings.NewReader(""))
   571  	c.Assert(err, IsNil)
   572  
   573  	// Copy files
   574  	var respCopyHeader http.Header
   575  	options = []Option{Routines(5), Checkpoint(true, destObjectName+".cp"), GetResponseHeader(&respCopyHeader), VersionId(versionId)}
   576  	err = destBucket.CopyFile(bucketName, srcObjectName, destObjectName, 1024*100, options...)
   577  	c.Assert(err, IsNil)
   578  	versionIdCopy := GetVersionId(respCopyHeader)
   579  	c.Assert(len(versionIdCopy) > 0, Equals, true)
   580  
   581  	err = destBucket.GetObjectToFile(destObjectName, newFile, VersionId(versionIdCopy))
   582  	c.Assert(err, IsNil)
   583  
   584  	eq, err := compareFiles(fileName, newFile)
   585  	c.Assert(err, IsNil)
   586  	c.Assert(eq, Equals, true)
   587  
   588  	err = destBucket.DeleteObject(destObjectName)
   589  	c.Assert(err, IsNil)
   590  	os.Remove(newFile)
   591  
   592  	// Copy file with options meta
   593  	options = []Option{Routines(10), Checkpoint(true, "copy.cp"), Meta("myprop", "mypropval"), GetResponseHeader(&respCopyHeader), VersionId(versionId)}
   594  	err = destBucket.CopyFile(bucketName, srcObjectName, destObjectName, 1024*100, options...)
   595  	c.Assert(err, IsNil)
   596  	versionIdCopy = GetVersionId(respCopyHeader)
   597  
   598  	err = destBucket.GetObjectToFile(destObjectName, newFile, VersionId(versionIdCopy))
   599  	c.Assert(err, IsNil)
   600  
   601  	eq, err = compareFiles(fileName, newFile)
   602  	c.Assert(err, IsNil)
   603  	c.Assert(eq, Equals, true)
   604  
   605  	os.Remove(fileName)
   606  	os.Remove(newFile)
   607  	destBucket.DeleteObject(destObjectName)
   608  	bucket.DeleteObject(objectName)
   609  	ForceDeleteBucket(client, bucketName, c)
   610  	ForceDeleteBucket(client, destBucketName, c)
   611  }
   612  
   613  // TestCopyFileChoiceOptions
   614  func (s *OssCopySuite) TestCopyFileChoiceOptions(c *C) {
   615  	destBucketName := s.bucket.BucketName + "-desc"
   616  	srcObjectName := objectNamePrefix + RandStr(8)
   617  	destObjectName := srcObjectName + "-dest"
   618  	fileName := "../sample/BingWallpaper-2015-11-07.jpg"
   619  	newFile := RandStr(8) + ".jpg"
   620  
   621  	destBucket, err := s.client.Bucket(destBucketName)
   622  	c.Assert(err, IsNil)
   623  
   624  	// Create a target bucket
   625  	err = s.client.CreateBucket(destBucketName)
   626  
   627  	// Upload source file
   628  	err = s.bucket.UploadFile(srcObjectName, fileName, 100*1024, Routines(3))
   629  	c.Assert(err, IsNil)
   630  	os.Remove(newFile)
   631  
   632  	// copyfile with properties
   633  	options := []Option{
   634  		ObjectACL(ACLPublicRead),
   635  		RequestPayer(Requester),
   636  		TrafficLimitHeader(1024 * 1024 * 8),
   637  		ObjectStorageClass(StorageArchive),
   638  		ServerSideEncryption("AES256"),
   639  		Routines(5), // without checkpoint
   640  	}
   641  
   642  	// Copy files
   643  	err = destBucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, options...)
   644  	c.Assert(err, IsNil)
   645  
   646  	// check object
   647  	meta, err := destBucket.GetObjectDetailedMeta(destObjectName)
   648  	c.Assert(err, IsNil)
   649  	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
   650  	c.Assert(meta.Get("X-Oss-Server-Side-Encryption"), Equals, "AES256")
   651  
   652  	aclResult, err := destBucket.GetObjectACL(destObjectName)
   653  	c.Assert(aclResult.ACL, Equals, "public-read")
   654  	c.Assert(err, IsNil)
   655  
   656  	err = destBucket.DeleteObject(destObjectName)
   657  	c.Assert(err, IsNil)
   658  	os.Remove(newFile)
   659  
   660  	// Copy file with options
   661  	options = []Option{
   662  		ObjectACL(ACLPublicRead),
   663  		RequestPayer(Requester),
   664  		TrafficLimitHeader(1024 * 1024 * 8),
   665  		ObjectStorageClass(StorageArchive),
   666  		ServerSideEncryption("AES256"),
   667  		Routines(10),
   668  		Checkpoint(true, "copy.cp"), // with checkpoint
   669  	}
   670  
   671  	err = destBucket.CopyFile(s.bucket.BucketName, srcObjectName, destObjectName, 1024*100, options...)
   672  	c.Assert(err, IsNil)
   673  
   674  	// check object
   675  	meta, err = destBucket.GetObjectDetailedMeta(destObjectName)
   676  	c.Assert(err, IsNil)
   677  	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
   678  	c.Assert(meta.Get("X-Oss-Server-Side-Encryption"), Equals, "AES256")
   679  
   680  	aclResult, err = destBucket.GetObjectACL(destObjectName)
   681  	c.Assert(aclResult.ACL, Equals, "public-read")
   682  	c.Assert(err, IsNil)
   683  
   684  	err = destBucket.DeleteObject(destObjectName)
   685  	c.Assert(err, IsNil)
   686  	os.Remove(newFile)
   687  
   688  	// Delete target bucket
   689  	err = s.client.DeleteBucket(destBucketName)
   690  	c.Assert(err, IsNil)
   691  }