github.com/qiniu/go-sdk/v7@v7.27.0/storage/bucket_test.go (about)

     1  //go:build integration
     2  // +build integration
     3  
     4  package storage
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"fmt"
    10  	"math/rand"
    11  	"net/http"
    12  	"net/url"
    13  	"os"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/qiniu/go-sdk/v7/auth"
    19  	"github.com/qiniu/go-sdk/v7/auth/qbox"
    20  	"github.com/qiniu/go-sdk/v7/client"
    21  )
    22  
    23  var (
    24  	testAK           = os.Getenv("accessKey")
    25  	testSK           = os.Getenv("secretKey")
    26  	testBucket       = os.Getenv("QINIU_TEST_BUCKET")
    27  	testBucketDomain = os.Getenv("QINIU_TEST_DOMAIN")
    28  	testPipeline     = os.Getenv("QINIU_TEST_PIPELINE")
    29  	testDebug        = os.Getenv("QINIU_SDK_DEBUG")
    30  	testUpHost       = os.Getenv("QINIU_TEST_UP_HOST")
    31  
    32  	testKey      = "qiniu.png"
    33  	testFetchUrl = "http://devtools.qiniu.com/qiniu.png"
    34  	testSiteUrl  = "http://devtools.qiniu.com"
    35  )
    36  
    37  // 现在qbox.Mac是auth.Credentials的别名, 这个地方使用原来的qbox.Mac
    38  // 测试兼容性是否正确
    39  var (
    40  	mac              *qbox.Mac
    41  	bucketManager    *BucketManager
    42  	operationManager *OperationManager
    43  	formUploader     *FormUploader
    44  	resumeUploader   *ResumeUploader
    45  	resumeUploaderV2 *ResumeUploaderV2
    46  	base64Uploader   *Base64Uploader
    47  	clt              client.Client
    48  )
    49  
    50  func init() {
    51  	if testDebug == "true" {
    52  		client.TurnOnDebug()
    53  	}
    54  	clt = client.Client{
    55  		Client: &http.Client{
    56  			Timeout:   time.Minute * 10,
    57  			Transport: client.DefaultTransport,
    58  		},
    59  	}
    60  	mac = auth.New(testAK, testSK)
    61  	cfg := Config{}
    62  	cfg.UseCdnDomains = false
    63  	cfg.UseHTTPS = true
    64  	bucketManager = NewBucketManagerEx(mac, &cfg, &clt)
    65  	operationManager = NewOperationManagerEx(mac, &cfg, &clt)
    66  	formUploader = NewFormUploaderEx(&cfg, &clt)
    67  	resumeUploader = NewResumeUploaderEx(&cfg, &clt)
    68  	resumeUploaderV2 = NewResumeUploaderV2Ex(&cfg, &clt)
    69  	base64Uploader = NewBase64UploaderEx(&cfg, &clt)
    70  	rand.Seed(time.Now().Unix())
    71  }
    72  
    73  // Test get zone
    74  func TestGetZone(t *testing.T) {
    75  	zone, err := GetZone(testAK, testBucket)
    76  	if err != nil {
    77  		t.Fatalf("GetZone() error, %s", err)
    78  	}
    79  	t.Log(zone.String())
    80  }
    81  
    82  // TestCreate 测试创建空间的功能
    83  func TestCreate(t *testing.T) {
    84  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
    85  	bucketName := fmt.Sprintf("gosdk-test-%d", r.Int())
    86  	bucketManager.DropBucket(bucketName)
    87  	err := bucketManager.CreateBucket(bucketName, RIDHuadong)
    88  	bucketManager.DropBucket(bucketName)
    89  	if err != nil {
    90  		t.Fatalf("CreateBucket() error: %v\n", err)
    91  	}
    92  }
    93  
    94  // TestUpdateObjectStatus 测试更新文件状态的功能
    95  func TestUpdateObjectStatus(t *testing.T) {
    96  	keysToStat := []string{"qiniu.png"}
    97  
    98  	for _, eachKey := range keysToStat {
    99  		err := bucketManager.UpdateObjectStatus(testBucket, eachKey, false)
   100  		if err != nil {
   101  			if !strings.Contains(err.Error(), "already disabled") {
   102  				t.Fatalf("UpdateObjectStatus error: %v\n", err)
   103  			}
   104  		}
   105  		err = bucketManager.UpdateObjectStatus(testBucket, eachKey, true)
   106  		if err != nil {
   107  			if !strings.Contains(err.Error(), "already enabled") {
   108  				t.Fatalf("UpdateObjectStatus error: %v\n", err)
   109  			}
   110  		}
   111  	}
   112  }
   113  
   114  // Test get bucket list
   115  func TestBuckets(t *testing.T) {
   116  	shared := true
   117  	buckets, err := bucketManager.Buckets(shared)
   118  	if err != nil {
   119  		t.Fatalf("Buckets() error, %s", err)
   120  	}
   121  
   122  	for _, bucket := range buckets {
   123  		t.Log(bucket)
   124  	}
   125  }
   126  
   127  // Test get bucket list v4
   128  func TestBucketsV4(t *testing.T) {
   129  	var input BucketV4Input
   130  	for i := 0; ; i++ {
   131  		output, err := bucketManager.BucketsV4(&input)
   132  		if err != nil {
   133  			t.Fatalf("Buckets() error, %s", err)
   134  		}
   135  
   136  		// 测试账号 bucket 较多,此处只测试第一页
   137  		// 如果测试账号 bucket 较少,未分页,则移除此处验证
   138  		if i == 0 {
   139  			if !output.IsTruncated {
   140  				t.Fatalf("Buckets() IsTruncated error, %s", err)
   141  			}
   142  			if len(output.NextMarker) == 0 {
   143  				t.Fatalf("Buckets() IsTruncated error, %s", err)
   144  			}
   145  		}
   146  
   147  		for _, bucket := range output.Buckets {
   148  			t.Log(bucket)
   149  
   150  			info, err := bucketManager.GetBucketInfo(bucket.Name)
   151  			if err != nil {
   152  				t.Fatalf("GetBucketInfo() error, %s", err)
   153  			}
   154  			t.Log(info)
   155  		}
   156  		if output.IsTruncated {
   157  			input.Marker = output.NextMarker
   158  		} else {
   159  			break
   160  		}
   161  	}
   162  }
   163  
   164  // Test set remark
   165  func TestSetRemark(t *testing.T) {
   166  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   167  	bucketName := fmt.Sprintf("gosdk-test-%d", r.Int())
   168  	bucketManager.DropBucket(bucketName)
   169  
   170  	err := bucketManager.CreateBucket(bucketName, RIDHuadong)
   171  	defer bucketManager.DropBucket(bucketName)
   172  	if err != nil {
   173  		t.Fatalf("CreateBucket() error: %v\n", err)
   174  	}
   175  
   176  	info, err := bucketManager.GetBucketInfo(bucketName)
   177  	if err != nil {
   178  		t.Fatalf("GetBucketInfo() error, %s", err)
   179  	}
   180  	if info.Remark != "" {
   181  		t.Logf("GetBucketInfo returns non-empty remark, %s", info.Remark)
   182  		t.Fail()
   183  	}
   184  
   185  	remark := fmt.Sprintf("test-remark-%d", r.Int())
   186  	err = bucketManager.SetRemark(bucketName, remark)
   187  	if err != nil {
   188  		t.Fatalf("SetRemark() error: %v\n", err)
   189  	}
   190  	info, err = bucketManager.GetBucketInfo(bucketName)
   191  	if err != nil {
   192  		t.Fatalf("GetBucketInfo() error, %s", err)
   193  	}
   194  	if info.Remark != remark {
   195  		t.Logf("GetBucketInfo returns unexpected remark, %s", info.Remark)
   196  		t.Fail()
   197  	}
   198  }
   199  
   200  // Test get file info
   201  func TestStat(t *testing.T) {
   202  	key := "qiniu.png"
   203  	copyKey := "staus_copy_" + key
   204  	if e := bucketManager.Copy(testBucket, key, testBucket, copyKey, true); e != nil {
   205  		t.Logf("1 Stat Copy error, %s", e)
   206  		t.Fail()
   207  	}
   208  	if e := bucketManager.ChangeType(testBucket, copyKey, 2); e != nil {
   209  		t.Logf("1 Stat Copy error, %s", e)
   210  		t.Fail()
   211  	}
   212  	if e := bucketManager.RestoreAr(testBucket, copyKey, 2); e != nil {
   213  		t.Logf("1 Stat Restore error, %s", e)
   214  		t.Fail()
   215  	}
   216  	if info, e := bucketManager.Stat(testBucket, copyKey); e != nil ||
   217  		info.Type != 2 || len(info.Hash) == 0 ||
   218  		info.RestoreStatus == 0 {
   219  		t.Logf("1 Stat() error, %+v", e)
   220  		t.Fail()
   221  	} else {
   222  		t.Logf("1 FileInfo:\n %s", info.String())
   223  	}
   224  
   225  	bucketManager.Delete(testBucket, copyKey)
   226  	copyKey = "rule_" + copyKey
   227  	ruleName := "golangStatusTest"
   228  	bucketManager.DelBucketLifeCycleRule(testBucket, ruleName)
   229  	if e := bucketManager.AddBucketLifeCycleRule(testBucket, &BucketLifeCycleRule{
   230  		Name:                   ruleName,
   231  		Prefix:                 "",
   232  		ToLineAfterDays:        10,
   233  		ToArchiveIRAfterDays:   20,
   234  		ToArchiveAfterDays:     30,
   235  		ToDeepArchiveAfterDays: 40,
   236  		DeleteAfterDays:        50,
   237  	}); e != nil {
   238  		t.Logf("Stat AddBucketLifeCycleRule() error, %s", e)
   239  		t.Fail()
   240  	}
   241  
   242  	if e := bucketManager.Copy(testBucket, key, testBucket, copyKey, true); e != nil {
   243  		t.Logf("2 Stat Copy error, %s", e)
   244  		t.Fail()
   245  	}
   246  	if e := bucketManager.DeleteAfterDays(testBucket, copyKey, 1); e != nil {
   247  		t.Logf("2 Stat Delete error, %s", e)
   248  		t.Fail()
   249  	}
   250  	client.DebugMode = true
   251  	if info, e := bucketManager.Stat(testBucket, copyKey); e != nil ||
   252  		len(info.Hash) == 0 || info.Expiration == 0 {
   253  		t.Logf("3 Stat() error, %v", e)
   254  		t.Fail()
   255  	} else {
   256  		t.Logf("3 FileInfo:\n %s", info.String())
   257  	}
   258  
   259  	bucketManager.Delete(testBucket, copyKey)
   260  	bucketManager.DelBucketLifeCycleRule(testBucket, ruleName)
   261  }
   262  
   263  func TestStatWithOption(t *testing.T) {
   264  	key := "stat_with_option_" + time.Now().String()
   265  
   266  	data := make([]byte, 1024*1024*5)
   267  	err := putDataByResumableV2(key, data)
   268  	if err != nil {
   269  		t.Logf("StatWithOption test upload data error, %s", err)
   270  		return
   271  	}
   272  
   273  	opt := &StatOpts{NeedParts: true}
   274  	info, err := bucketManager.StatWithOpts(testBucket, key, opt)
   275  	if err != nil || info.Parts == nil {
   276  		t.Logf("StatWithOption() error, %s", err)
   277  		t.Fail()
   278  	} else {
   279  		t.Logf("FileInfo:\n %s", info.String())
   280  	}
   281  }
   282  
   283  func TestStatWithMeta(t *testing.T) {
   284  	key := "meta_test_" + time.Now().String()
   285  
   286  	data := make([]byte, 1024*1024*5)
   287  	err := putDataByResumableV2(key, data)
   288  	if err != nil {
   289  		t.Logf("TestStatWithMeta test upload data error, %s", err)
   290  		return
   291  	}
   292  
   293  	info, err := bucketManager.Stat(testBucket, key)
   294  	if err != nil {
   295  		t.Logf("TestStatWithMeta() Stat error, %s", err)
   296  		t.Fail()
   297  	}
   298  	if len(info.MetaData) == 0 {
   299  		t.Log("TestStatWithMeta() MetaData is empty")
   300  		t.Fail()
   301  	}
   302  
   303  	// 同时修改 mime 和 meta
   304  	err = bucketManager.ChangeMimeAndMeta(testBucket, key, "application/abc", map[string]string{
   305  		"x-qn-meta-b": "x-qn-meta-bb-value",
   306  		"x-qn-meta-c": "x-qn-meta-c-value",
   307  	})
   308  	if err != nil {
   309  		t.Logf("TestStatWithMeta() ChangeMimeAndMeta error, %s", err)
   310  		t.Fail()
   311  	}
   312  
   313  	info, err = bucketManager.Stat(testBucket, key)
   314  	if err != nil {
   315  		t.Logf("TestStatWithMeta() Stat 2 error, %s", err)
   316  		t.Fail()
   317  	}
   318  
   319  	if info.MimeType != "application/abc" {
   320  		t.Log("TestStatWithMeta() MimeType c is error")
   321  		t.Fail()
   322  	}
   323  
   324  	if len(info.MetaData) == 0 {
   325  		t.Log("TestStatWithMeta() MetaData 2 is empty")
   326  		t.Fail()
   327  	}
   328  
   329  	if info.MetaData["b"] != "x-qn-meta-bb-value" {
   330  		t.Log("TestStatWithMeta() MetaData b is error")
   331  		t.Fail()
   332  	}
   333  
   334  	if info.MetaData["c"] != "x-qn-meta-c-value" {
   335  		t.Log("TestStatWithMeta() MetaData c is error")
   336  		t.Fail()
   337  	}
   338  
   339  	// 只修改 meta
   340  	err = bucketManager.ChangeMeta(testBucket, key, map[string]string{
   341  		"x-qn-meta-c": "x-qn-meta-cc-value",
   342  	})
   343  	if err != nil {
   344  		t.Logf("TestStatWithMeta() ChangeMimeAndMeta error, %s", err)
   345  		t.Fail()
   346  	}
   347  	info, err = bucketManager.Stat(testBucket, key)
   348  	if err != nil {
   349  		t.Logf("TestStatWithMeta() Stat 2 error, %s", err)
   350  		t.Fail()
   351  	}
   352  
   353  	if info.MimeType != "application/abc" {
   354  		t.Log("TestStatWithMeta() MimeType c is error")
   355  		t.Fail()
   356  	}
   357  
   358  	if len(info.MetaData) == 0 {
   359  		t.Log("TestStatWithMeta() MetaData 2 is empty")
   360  		t.Fail()
   361  	}
   362  
   363  	if info.MetaData["b"] != "x-qn-meta-bb-value" {
   364  		t.Log("TestStatWithMeta() MetaData b is error")
   365  		t.Fail()
   366  	}
   367  
   368  	if info.MetaData["c"] != "x-qn-meta-cc-value" {
   369  		t.Log("TestStatWithMeta() MetaData c is error")
   370  		t.Fail()
   371  	}
   372  
   373  	// 只修改 meta, 不带 x-qn-meta-
   374  	err = bucketManager.ChangeMeta(testBucket, key, map[string]string{
   375  		"d": "x-qn-meta-d-value",
   376  	})
   377  	if err != nil {
   378  		t.Logf("TestStatWithMeta() ChangeMeta error, %s", err)
   379  		t.Fail()
   380  	}
   381  	info, err = bucketManager.Stat(testBucket, key)
   382  	if err != nil {
   383  		t.Logf("TestStatWithMeta() Stat 2 error, %s", err)
   384  		t.Fail()
   385  	}
   386  
   387  	if info.MimeType != "application/abc" {
   388  		t.Log("TestStatWithMeta() MimeType c is error")
   389  		t.Fail()
   390  	}
   391  
   392  	if len(info.MetaData) == 0 {
   393  		t.Log("TestStatWithMeta() MetaData 2 is empty")
   394  		t.Fail()
   395  	}
   396  
   397  	if info.MetaData["d"] != "x-qn-meta-d-value" {
   398  		t.Log("TestStatWithMeta() MetaData d is error")
   399  		t.Fail()
   400  	}
   401  }
   402  
   403  func putDataByResumableV2(key string, data []byte) (err error) {
   404  	var putRet PutRet
   405  	putPolicy := PutPolicy{
   406  		Scope:           testBucket,
   407  		DeleteAfterDays: 1,
   408  	}
   409  	upToken := putPolicy.UploadToken(mac)
   410  	partSize := int64(1024 * 1024)
   411  	err = resumeUploaderV2.Put(context.Background(), &putRet, upToken, key, bytes.NewReader(data), int64(len(data)), &RputV2Extra{
   412  		PartSize: partSize,
   413  		Metadata: map[string]string{
   414  			"x-qn-meta-a": "x-qn-meta-a-value",
   415  			"x-qn-meta-b": "x-qn-meta-b-value",
   416  		},
   417  		CustomVars: map[string]string{
   418  			"x:var-a": "x:var-a-value",
   419  			"x:var-b": "x:var-b-value",
   420  		},
   421  	})
   422  	return
   423  }
   424  
   425  func TestCopyMoveDelete(t *testing.T) {
   426  	keysCopyTarget := []string{"qiniu_1.png", "qiniu_2.png", "qiniu_3.png"}
   427  	keysToDelete := make([]string, 0, len(keysCopyTarget))
   428  	for _, eachKey := range keysCopyTarget {
   429  		err := bucketManager.Copy(testBucket, testKey, testBucket, eachKey, true)
   430  		if err != nil {
   431  			t.Logf("Copy() error, %s", err)
   432  			t.Fail()
   433  		}
   434  	}
   435  
   436  	for _, eachKey := range keysCopyTarget {
   437  		keyToDelete := eachKey + "_move"
   438  		err := bucketManager.Move(testBucket, eachKey, testBucket, keyToDelete, true)
   439  		if err != nil {
   440  			t.Logf("Move() error, %s", err)
   441  			t.Fail()
   442  		} else {
   443  			keysToDelete = append(keysToDelete, keyToDelete)
   444  		}
   445  	}
   446  
   447  	for _, eachKey := range keysToDelete {
   448  		err := bucketManager.Delete(testBucket, eachKey)
   449  		if err != nil {
   450  			t.Logf("Delete() error, %s", err)
   451  			t.Fail()
   452  		}
   453  	}
   454  }
   455  
   456  func TestFetch(t *testing.T) {
   457  	ret, err := bucketManager.Fetch(testFetchUrl, testBucket, "qiniu-fetch.png")
   458  	if err != nil {
   459  		t.Logf("Fetch() error, %s", err)
   460  		t.Fail()
   461  	} else {
   462  		t.Logf("FetchRet:\n %s", ret.String())
   463  	}
   464  }
   465  
   466  func TestAsyncFetch(t *testing.T) {
   467  	param := AsyncFetchParam{Url: testFetchUrl, Bucket: testBucket}
   468  	ret, err := bucketManager.AsyncFetch(param)
   469  	if err != nil {
   470  		t.Logf("Fetch() error, %s", err)
   471  		t.Fail()
   472  	} else {
   473  		t.Logf("FetchRet:\n %#v", ret)
   474  	}
   475  }
   476  
   477  func TestFetchWithoutKey(t *testing.T) {
   478  	ret, err := bucketManager.FetchWithoutKey(testFetchUrl, testBucket)
   479  	if err != nil {
   480  		t.Logf("FetchWithoutKey() error, %s", err)
   481  		t.Fail()
   482  	} else {
   483  		t.Logf("FetchRet:\n %s", ret.String())
   484  	}
   485  }
   486  
   487  func TestDeleteAfterDays(t *testing.T) {
   488  	deleteKey := testKey + "_deleteAfterDays"
   489  	days := 7
   490  	bucketManager.Copy(testBucket, testKey, testBucket, deleteKey, true)
   491  	err := bucketManager.DeleteAfterDays(testBucket, deleteKey, days)
   492  	if err != nil {
   493  		t.Logf("DeleteAfterDays() error, %s", err)
   494  		t.Fail()
   495  	}
   496  }
   497  
   498  func TestChangeMime(t *testing.T) {
   499  	toChangeKey := testKey + "_changeMime"
   500  	bucketManager.Copy(testBucket, testKey, testBucket, toChangeKey, true)
   501  	newMime := "text/plain"
   502  	err := bucketManager.ChangeMime(testBucket, toChangeKey, newMime)
   503  	if err != nil {
   504  		t.Fatalf("ChangeMime() error, %s", err)
   505  	}
   506  
   507  	info, err := bucketManager.Stat(testBucket, toChangeKey)
   508  	if err != nil || info.MimeType != newMime {
   509  		t.Fatalf("ChangeMime() failed, %s", err)
   510  	}
   511  	bucketManager.Delete(testBucket, toChangeKey)
   512  }
   513  
   514  func TestChangeType(t *testing.T) {
   515  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   516  	toChangeKey := fmt.Sprintf("%s_changeType_%d", testKey, r.Int())
   517  	bucketManager.Copy(testBucket, testKey, testBucket, toChangeKey, true)
   518  	fileType := 1
   519  	err := bucketManager.ChangeType(testBucket, toChangeKey, fileType)
   520  	if err != nil {
   521  		t.Fatalf("ChangeType() error, %s", err)
   522  	}
   523  
   524  	info, err := bucketManager.Stat(testBucket, toChangeKey)
   525  	if err != nil || info.Type != fileType {
   526  		t.Fatalf("ChangeMime() failed, %s", err)
   527  	}
   528  	bucketManager.Delete(testBucket, toChangeKey)
   529  }
   530  
   531  func TestRestoreAr(t *testing.T) {
   532  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   533  	toRestoreArKey := fmt.Sprintf("%s_RestoreAr_%d", testKey, r.Int())
   534  	bucketManager.Copy(testBucket, testKey, testBucket, toRestoreArKey, true)
   535  	fileType := 2
   536  	err := bucketManager.ChangeType(testBucket, toRestoreArKey, fileType)
   537  	if err != nil {
   538  		t.Fatalf("ChangeType() error, %s", err)
   539  	}
   540  
   541  	err = bucketManager.RestoreAr(testBucket, toRestoreArKey, 5)
   542  	if err != nil {
   543  		t.Fatalf("RestoreAr() failed, %s", err)
   544  	}
   545  
   546  	info, err := bucketManager.Stat(testBucket, toRestoreArKey)
   547  	if err != nil || info.Type != fileType {
   548  		t.Fatalf("Stat() failed, %s", err)
   549  	}
   550  	defer bucketManager.Delete(testBucket, toRestoreArKey)
   551  }
   552  
   553  // SetImage成功以后, 后台生效需要一段时间;导致集成测试经常失败。
   554  // 如果要修改这一部分代码可以重新开启这个测试
   555  func aTestPrefetchAndImage(t *testing.T) {
   556  	err := bucketManager.SetImage(testSiteUrl, testBucket)
   557  	if err != nil {
   558  		t.Fatalf("SetImage() error, %s", err)
   559  	}
   560  
   561  	t.Log("set image success for bucket", testBucket)
   562  	// wait for image set to take effect
   563  	time.Sleep(time.Second * 10)
   564  
   565  	err = bucketManager.Prefetch(testBucket, testKey)
   566  	if err != nil {
   567  		t.Fatalf("Prefetch() error, %s", err)
   568  	}
   569  
   570  	err = bucketManager.UnsetImage(testBucket)
   571  	if err != nil {
   572  		t.Fatalf("UnsetImage() error, %s", err)
   573  	}
   574  
   575  	t.Log("unset image success for bucket", testBucket)
   576  }
   577  
   578  func TestListFiles(t *testing.T) {
   579  	limit := 100
   580  	prefix := "listfiles/"
   581  	for i := 0; i < limit; i++ {
   582  		newKey := fmt.Sprintf("%s%s/%d", prefix, testKey, i)
   583  		bucketManager.Copy(testBucket, testKey, testBucket, newKey, true)
   584  	}
   585  	entries, _, _, hasNext, err := bucketManager.ListFiles(testBucket, prefix, "", "", limit)
   586  	if err != nil {
   587  		t.Fatalf("ListFiles() error, %s", err)
   588  	}
   589  
   590  	if hasNext {
   591  		t.Fatalf("ListFiles() failed, unexpected hasNext")
   592  	}
   593  
   594  	if len(entries) != limit {
   595  		t.Fatalf("ListFiles() failed, unexpected items count, expected: %d, actual: %d", limit, len(entries))
   596  	}
   597  
   598  	for _, entry := range entries {
   599  		t.Logf("ListItem:\n%s", entry.String())
   600  	}
   601  }
   602  
   603  func TestBatch(t *testing.T) {
   604  	copyCnt := 100
   605  	copyOps := make([]string, 0, copyCnt)
   606  	testKeys := make([]string, 0, copyCnt)
   607  	for i := 0; i < copyCnt; i++ {
   608  		cpKey := fmt.Sprintf("%s_batchcopy_%d", testKey, i)
   609  		testKeys = append(testKeys, cpKey)
   610  		copyOps = append(copyOps, URICopy(testBucket, testKey, testBucket, cpKey, true))
   611  	}
   612  
   613  	batchCopyOpRets, bErr := bucketManager.Batch(copyOps)
   614  	if batchCopyOpRets == nil || bErr != nil {
   615  		t.Fatalf("BatchCopy error, %s", bErr)
   616  	}
   617  
   618  	statOps := make([]string, 0, copyCnt)
   619  	for _, k := range testKeys {
   620  		statOps = append(statOps, URIStat(testBucket, k))
   621  	}
   622  	batchOpRets, bErr := bucketManager.Batch(statOps)
   623  	if bErr != nil {
   624  		t.Fatalf("BatchStat error, %s", bErr)
   625  	}
   626  
   627  	t.Logf("BatchStat: %v", batchOpRets)
   628  }
   629  
   630  func TestBatchStat(t *testing.T) {
   631  	statOps := make([]string, 0, 2)
   632  	statOps = append(statOps, URIStat(testBucket, "form_test/120"))
   633  
   634  	rets, bErr := bucketManager.Batch(statOps)
   635  	if len(rets) == 0 || bErr != nil {
   636  		t.Fatalf("BatchStat error, %s", bErr)
   637  	}
   638  
   639  	ret := rets[0]
   640  	t.Log(ret)
   641  	if len(ret.Data.Hash) == 0 {
   642  		t.Fatalf("Hash error")
   643  	}
   644  	if len(ret.Data.MimeType) == 0 {
   645  		t.Fatalf("MimeType error")
   646  	}
   647  	if ret.Data.Type != 1 {
   648  		t.Fatalf("Type error")
   649  	}
   650  	if ret.Data.Status == nil {
   651  		t.Fatalf("Status error")
   652  	}
   653  }
   654  
   655  func TestBatchPartialFailure(t *testing.T) {
   656  	copyOps := make([]string, 0, 2)
   657  	cpKey := fmt.Sprintf("%s_batchcopy_%d", testKey, 0)
   658  	copyOps = append(copyOps, URICopy(testBucket, testKey, testBucket, cpKey, true))
   659  	cpKey = fmt.Sprintf("%s_batchcopy_%d", testKey, 0)
   660  	copyOps = append(copyOps, URICopy(testBucket, testKey+".notexisted", testBucket, cpKey, true))
   661  
   662  	rets, bErr := bucketManager.Batch(copyOps)
   663  	if bErr != nil {
   664  		t.Fatalf("BatchCopy error, %s", bErr)
   665  	}
   666  	if len(rets) != 2 {
   667  		t.Fatalf("BatchCopy returns wrong number of results")
   668  	}
   669  	if rets[0].Code != 200 {
   670  		t.Fatalf("BatchCopy[0] error, status = %d", rets[0].Code)
   671  	}
   672  	if rets[1].Code != 612 {
   673  		t.Fatalf("BatchCopy[1] error, status = %d", rets[1].Code)
   674  	}
   675  }
   676  
   677  func TestListBucket(t *testing.T) {
   678  	retChan, lErr := bucketManager.ListBucket(testBucket, "form_test", "", "")
   679  	if lErr != nil {
   680  		t.Fatalf("ListBucket: %v\n", lErr)
   681  	}
   682  	for ret := range retChan {
   683  		t.Log(ret.Item)
   684  		if len(ret.Item.Key) == 0 {
   685  			t.Fatalf("key error")
   686  		}
   687  		if len(ret.Item.Hash) == 0 {
   688  			t.Fatalf("Hash error")
   689  		}
   690  		if len(ret.Item.MimeType) == 0 {
   691  			t.Fatalf("MimeType error")
   692  		}
   693  		if ret.Item.Type < 0 {
   694  			t.Fatalf("Type error")
   695  		}
   696  		if ret.Item.Status < 0 {
   697  			t.Fatalf("Status error")
   698  		}
   699  	}
   700  
   701  	retChan, lErr = bucketManager.ListBucket(testBucket, "form_test/120", "", "")
   702  	if lErr != nil {
   703  		t.Fatalf("ListBucket: %v\n", lErr)
   704  	}
   705  	for ret := range retChan {
   706  		t.Log(ret.Item)
   707  		if len(ret.Item.Key) == 0 {
   708  			t.Fatalf("key error")
   709  		}
   710  		if len(ret.Item.Hash) == 0 {
   711  			t.Fatalf("Hash error")
   712  		}
   713  		if len(ret.Item.MimeType) == 0 {
   714  			t.Fatalf("MimeType error")
   715  		}
   716  		if ret.Item.Type != 1 {
   717  			t.Fatalf("Type error")
   718  		}
   719  		if ret.Item.Status != 1 {
   720  			t.Fatalf("Status error")
   721  		}
   722  	}
   723  }
   724  
   725  func TestListBucketWithCancel(t *testing.T) {
   726  	ctx, cancelFunc := context.WithCancel(context.Background())
   727  	cancelFunc()
   728  	_, lErr := bucketManager.ListBucketContext(ctx, testBucket, "", "", "")
   729  	if lErr == nil {
   730  		t.Fatal("ListBucket cancel error")
   731  	}
   732  	if !strings.Contains(lErr.Error(), "context canceled") {
   733  		t.Fatalf("ListBucket cancel error:%s", lErr.Error())
   734  	}
   735  }
   736  
   737  func TestGetBucketInfo(t *testing.T) {
   738  	bInfo, bErr := bucketManager.GetBucketInfo(testBucket)
   739  	if bErr != nil {
   740  		t.Fatalf("GetBucketInfo: %v\n", bErr)
   741  	}
   742  	t.Log(bInfo)
   743  }
   744  
   745  func TestBucketInfosInRegion(t *testing.T) {
   746  	bInfos, bErr := bucketManager.BucketInfosInRegion(RIDHuadong, true)
   747  	if bErr != nil {
   748  		t.Fatalf("BucketInfosInRegion: %v\n", bErr)
   749  	}
   750  	for _, bInfo := range bInfos {
   751  		t.Log(bInfo)
   752  	}
   753  }
   754  
   755  func TestRefererAntiLeechMode(t *testing.T) {
   756  	cfgs := []*ReferAntiLeechConfig{
   757  		{
   758  			Mode: 0, // 关闭referer防盗链
   759  		},
   760  		{
   761  			Mode:    1, // 开启referer白名单
   762  			Pattern: "*.qiniu.com",
   763  		},
   764  		{
   765  			Mode:    2, // 开启referer黑名单
   766  			Pattern: "*.qiniu.com",
   767  		},
   768  	}
   769  	for _, cfg := range cfgs {
   770  		err := bucketManager.SetReferAntiLeechMode(testBucket, cfg)
   771  		if err != nil {
   772  			t.Fatalf("SetReferAntiLeechMode: %v\n", err)
   773  		}
   774  	}
   775  
   776  	bInfo, bErr := bucketManager.GetBucketInfo(testBucket)
   777  	if bErr != nil {
   778  		t.Fatalf("GetBucketInfo: %v\n", bErr)
   779  	}
   780  	if bInfo.AntiLeechMode != 2 {
   781  		t.Fatalf("AntiLeechMode expected: %q, got: %q\n", 2, bInfo.AntiLeechMode)
   782  	}
   783  	if len(bInfo.ReferBl) != 1 || bInfo.ReferBl[0] != "*.qiniu.com" {
   784  		t.Fatalf("Referer blacklist expected: %q, got: %q\n", "*.qiniu.com", bInfo.ReferBl[0])
   785  	}
   786  }
   787  
   788  func TestBucketLifeCycleRule(t *testing.T) {
   789  	bucketManager.DelBucketLifeCycleRule(testBucket, "golangIntegrationTest")
   790  
   791  	err := bucketManager.AddBucketLifeCycleRule(testBucket, &BucketLifeCycleRule{
   792  		Name:                   "golangIntegrationTest",
   793  		Prefix:                 "testPutFileKey",
   794  		DeleteAfterDays:        13,
   795  		ToLineAfterDays:        1,
   796  		ToArchiveIRAfterDays:   2,
   797  		ToArchiveAfterDays:     6,
   798  		ToDeepArchiveAfterDays: 10,
   799  	})
   800  	if err != nil {
   801  		if !strings.Contains(err.Error(), "rule name exists") {
   802  			t.Fatalf("TestBucketLifeCycleRule: %v\n", err)
   803  		}
   804  	}
   805  	rules, err := bucketManager.GetBucketLifeCycleRule(testBucket)
   806  	if err != nil {
   807  		t.Fatalf("TestBucketLifeCycleRule: %v\n", err)
   808  	}
   809  	var foundRule *BucketLifeCycleRule
   810  	for i := range rules {
   811  		if rules[i].Name == "golangIntegrationTest" && rules[i].Prefix == "testPutFileKey" {
   812  			foundRule = &rules[i]
   813  			break
   814  		}
   815  	}
   816  	if foundRule == nil {
   817  		t.Fatalf("TestBucketLifeCycleRule: rule name not found")
   818  	} else if foundRule.DeleteAfterDays != 13 {
   819  		t.Fatalf("TestBucketLifeCycleRule: foundRule.DeleteAfterDays = %d", foundRule.DeleteAfterDays)
   820  	} else if foundRule.ToLineAfterDays != 1 {
   821  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToLineAfterDays = %d", foundRule.ToLineAfterDays)
   822  	} else if foundRule.ToArchiveAfterDays != 6 {
   823  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToArchiveAfterDays = %d", foundRule.ToArchiveAfterDays)
   824  	} else if foundRule.ToDeepArchiveAfterDays != 10 {
   825  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToDeepArchiveAfterDays = %d", foundRule.ToDeepArchiveAfterDays)
   826  	}
   827  
   828  	err = bucketManager.UpdateBucketLifeCycleRule(testBucket, &BucketLifeCycleRule{
   829  		Name:                   "golangIntegrationTest",
   830  		Prefix:                 "testPutFileKey",
   831  		DeleteAfterDays:        22,
   832  		ToLineAfterDays:        11,
   833  		ToArchiveIRAfterDays:   12,
   834  		ToArchiveAfterDays:     16,
   835  		ToDeepArchiveAfterDays: 20,
   836  	})
   837  	if err != nil {
   838  		t.Fatalf("TestBucketLifeCycleRule: %v\n", err)
   839  	}
   840  
   841  	rules, err = bucketManager.GetBucketLifeCycleRule(testBucket)
   842  	if err != nil {
   843  		t.Fatalf("TestBucketLifeCycleRule: %v\n", err)
   844  	}
   845  	foundRule = nil
   846  	for i := range rules {
   847  		if rules[i].Name == "golangIntegrationTest" && rules[i].Prefix == "testPutFileKey" {
   848  			foundRule = &rules[i]
   849  			break
   850  		}
   851  	}
   852  	if foundRule == nil {
   853  		t.Fatalf("TestBucketLifeCycleRule: rule name not found")
   854  	} else if foundRule.DeleteAfterDays != 22 {
   855  		t.Fatalf("TestBucketLifeCycleRule: foundRule.DeleteAfterDays = %d", foundRule.DeleteAfterDays)
   856  	} else if foundRule.ToLineAfterDays != 11 {
   857  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToLineAfterDays = %d", foundRule.ToLineAfterDays)
   858  	} else if foundRule.ToArchiveAfterDays != 16 {
   859  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToArchiveAfterDays = %d", foundRule.ToArchiveAfterDays)
   860  	} else if foundRule.ToDeepArchiveAfterDays != 20 {
   861  		t.Fatalf("TestBucketLifeCycleRule: foundRule.ToDeepArchiveAfterDays = %d", foundRule.ToDeepArchiveAfterDays)
   862  	}
   863  
   864  	err = bucketManager.DelBucketLifeCycleRule(testBucket, "golangIntegrationTest")
   865  	if err != nil {
   866  		t.Fatalf("TestBucketLifeCycleRule: %v\n", err)
   867  	}
   868  }
   869  
   870  func TestBucketEventRule(t *testing.T) {
   871  	err := bucketManager.AddBucketEvent(testBucket, &BucketEventRule{
   872  		Name:        "golangIntegrationTest",
   873  		Event:       []string{"put", "mkfile"},
   874  		Host:        "www.qiniu.com",
   875  		CallbackURL: []string{"http://www.qiniu.com"},
   876  	})
   877  	if err != nil {
   878  		if !strings.Contains(err.Error(), "event name exists") {
   879  			t.Fatalf("TestBucketEventRule: %v\n", err)
   880  		}
   881  	}
   882  	rules, err := bucketManager.GetBucketEvent(testBucket)
   883  	if err != nil {
   884  		t.Fatalf("TestBucketEventRule: %v\n", err)
   885  	}
   886  	exist := false
   887  	for _, rule := range rules {
   888  		if rule.Name == "golangIntegrationTest" && rule.Host == "www.qiniu.com" {
   889  			exist = true
   890  			break
   891  		}
   892  	}
   893  	if !exist {
   894  		t.Fatalf("TestBucketEventRule: %v\n", err)
   895  	}
   896  
   897  	err = bucketManager.UpdateBucketEnvent(testBucket, &BucketEventRule{
   898  		Name:        "golangIntegrationTest",
   899  		Event:       []string{"put", "mkfile"},
   900  		Host:        "www.qiniu.com",
   901  		CallbackURL: []string{"http://www.qiniu.com"},
   902  	})
   903  	if err != nil {
   904  		t.Fatalf("TestBucketEventRule: %v\n", err)
   905  	}
   906  	err = bucketManager.DelBucketEvent(testBucket, "golangIntegrationTest")
   907  	if err != nil {
   908  		t.Fatalf("TestBucketEventRule: %v\n", err)
   909  	}
   910  }
   911  
   912  func TestCorsRules(t *testing.T) {
   913  	err := bucketManager.AddCorsRules(testBucket, []CorsRule{
   914  		{
   915  			AllowedOrigin: []string{"http://www.test1.com"},
   916  			AllowedMethod: []string{"GET", "POST"},
   917  		},
   918  	})
   919  	if err != nil {
   920  		t.Fatalf("TestCorsRules: %v\n", err)
   921  	}
   922  	rules, err := bucketManager.GetCorsRules(testBucket)
   923  	if err != nil {
   924  		t.Fatalf("TestCorsRules: %v\n", err)
   925  	}
   926  	for _, r := range rules {
   927  		t.Log(r)
   928  	}
   929  }
   930  
   931  func TestListBucketDomains(t *testing.T) {
   932  	bInfos, err := bucketManager.ListBucketDomains(testBucket)
   933  	if err != nil {
   934  		/*
   935  			if !strings.Contains(err.Error(), "404 page not found") {
   936  				t.Fatalf("ListBucketDomains: %q\n", err)
   937  			}
   938  		*/
   939  		t.Fatalf("ListBucketDomains: %q\n", err)
   940  	}
   941  	for _, info := range bInfos {
   942  		t.Log(info)
   943  	}
   944  }
   945  
   946  func TestBucketQuota(t *testing.T) {
   947  	err := bucketManager.SetBucketQuota(testBucket, 0, 1000000000000000)
   948  	if err != nil {
   949  		t.Fatalf("TestBucketQuota: %q\n", err)
   950  	}
   951  	quota, err := bucketManager.GetBucketQuota(testBucket)
   952  	if err != nil {
   953  		t.Fatalf("TestBucketQuota: %q\n", err)
   954  	}
   955  	t.Log(quota)
   956  }
   957  
   958  func TestSetBucketAccessStyle(t *testing.T) {
   959  	err := bucketManager.TurnOnBucketProtected(testBucket)
   960  	if err != nil {
   961  		t.Fatalf("TestSetBucketAccessStyle: %q\n", err)
   962  	}
   963  	err = bucketManager.TurnOffBucketProtected(testBucket)
   964  	if err != nil {
   965  		t.Fatalf("TestSetBucketAccessStyle: %q\n", err)
   966  	}
   967  }
   968  
   969  func TestSetBucketMaxAge(t *testing.T) {
   970  	err := bucketManager.SetBucketMaxAge(testBucket, 20)
   971  	if err != nil {
   972  		t.Fatalf("TestSetBucketMaxAge: %q\n", err)
   973  	}
   974  	err = bucketManager.SetBucketMaxAge(testBucket, 0)
   975  	if err != nil {
   976  		t.Fatalf("TestSetBucketMaxAge: %q\n", err)
   977  	}
   978  }
   979  
   980  func TestSetBucketAccessMode(t *testing.T) {
   981  	r := rand.New(rand.NewSource(time.Now().UnixNano()))
   982  	bucketName := fmt.Sprintf("gosdk-test-%d", r.Int())
   983  	bucketManager.DropBucket(bucketName)
   984  	err := bucketManager.CreateBucket(bucketName, RIDHuadong)
   985  	if err != nil {
   986  		t.Fatalf("CreateBucket() error: %v\n", err)
   987  	}
   988  	defer bucketManager.DropBucket(bucketName)
   989  
   990  	err = bucketManager.MakeBucketPrivate(bucketName)
   991  	if err != nil {
   992  		t.Fatalf("TestSetBucketAccessMode: %q\n", err)
   993  	}
   994  	err = bucketManager.MakeBucketPublic(bucketName)
   995  	if err != nil {
   996  		t.Fatalf("TestSetBucketAccessMode: %q\n", err)
   997  	}
   998  }
   999  
  1000  func TestMakeURL(t *testing.T) {
  1001  	keys := map[string]string{ // rawKey => encodeKey,
  1002  		"":            "",
  1003  		"abc_def.mp4": "abc_def.mp4",
  1004  		"/ab/cd":      "/ab/cd",
  1005  		// "ab/中文/de":    "ab/%E4%B8%AD%E6%96%87/de",
  1006  		// "ab+-*de f":   "ab%2B-%2Ade%20f",
  1007  		"ab:cd": "ab%3Acd",
  1008  		// "ab@cd":            "ab%40cd",
  1009  		"ab?cd=ef":  "ab%3Fcd%3Def",
  1010  		"ab#e~f":    "ab%23e~f",
  1011  		"ab//cd":    "ab//cd",
  1012  		"abc%2F%2B": "abc%252F%252B",
  1013  		"ab cd":     "ab%20cd",
  1014  		// "ab/c:d?e#f//gh汉子": "ab/c%3Ad%3Fe%23f//gh%E6%B1%89%E5%AD%90",
  1015  	}
  1016  	s := MakePublicURL("https://abc.com:123/", "123/def?@#")
  1017  	if s != "https://abc.com:123/123/def?@" {
  1018  		t.Fatalf("TestMakeURL: %q\n", s)
  1019  	}
  1020  
  1021  	s = MakePublicURL("abc.com:123/", "123/def?@#")
  1022  	if s != "abc.com:123/123/def?@" {
  1023  		t.Fatalf("TestMakeURL: %q\n", s)
  1024  	}
  1025  
  1026  	q := make(url.Values)
  1027  	q.Add("?", "#")
  1028  	s = MakePublicURLv2WithQuery("https://abc.com:123/", "123/def?@#", q)
  1029  	if s != "https://abc.com:123/123/def%3F%40%23?%3F=%23" {
  1030  		t.Fatalf("TestMakeURL: %q\n", s)
  1031  	}
  1032  
  1033  	s = MakePublicURLv2WithQueryString("http://abc.com:123/", "123/def?@#|", "123/def?@#|")
  1034  	if s != "http://abc.com:123/123/def%3F@%23%7C?123/def%3F%40%23|" {
  1035  		t.Fatalf("TestMakeURL: %q\n", s)
  1036  	}
  1037  
  1038  	s = MakePublicURLv2("http://abc.com:123/", "123/def?@#")
  1039  	if s != "http://abc.com:123/123/def%3F%40%23" {
  1040  		t.Fatalf("TestMakeURL: %q\n", s)
  1041  	}
  1042  
  1043  	for rawKey, encodedKey := range keys {
  1044  		s = MakePublicURLv2("http://abc.com:123/", rawKey)
  1045  		e := "http://abc.com:123/" + encodedKey
  1046  		if s != e {
  1047  			t.Fatalf("TestMakeURL: %q %q\n", s, e)
  1048  		}
  1049  	}
  1050  }