You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

454 lines
14 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. package cos
  2. // Basic imports
  3. import (
  4. "context"
  5. "fmt"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/suite"
  8. "github.com/toranger/cos-go-sdk-v5"
  9. "io/ioutil"
  10. "math/rand"
  11. "net/http"
  12. "net/url"
  13. "os"
  14. "strings"
  15. "testing"
  16. "time"
  17. )
  18. // Define the suite, and absorb the built-in basic suite
  19. // functionality from testify - including a T() method which
  20. // returns the current testing context
  21. type CosTestSuite struct {
  22. suite.Suite
  23. VariableThatShouldStartAtFive int
  24. // CI client
  25. Client *cos.Client
  26. // Copy source client
  27. CClient *cos.Client
  28. Region string
  29. Bucket string
  30. Appid string
  31. // test_object
  32. TestObject string
  33. // special_file_name
  34. SepFileName string
  35. }
  36. func (s *CosTestSuite) SetupSuite() {
  37. fmt.Println("Set up test")
  38. // init
  39. s.TestObject = "test.txt"
  40. s.SepFileName = "中文" + "→↓←→↖↗↙↘! \"#$%&'()*+,-./0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
  41. // CI client for test interface
  42. // URL like this http://test-1253846586.cos.ap-guangzhou.myqcloud.com
  43. u := os.Getenv("COS_BUCKET_URL")
  44. // Get the region
  45. iu, _ := url.Parse(u)
  46. p := strings.Split(iu.Host, ".")
  47. assert.Equal(s.T(), 5, len(p), "Bucket host is not right")
  48. s.Region = p[2]
  49. // Bucket name
  50. pp := strings.Split(p[0], "-")
  51. s.Bucket = pp[0]
  52. s.Appid = pp[1]
  53. ib := &cos.BaseURL{BucketURL: iu}
  54. s.Client = cos.NewClient(ib, &http.Client{
  55. Transport: &cos.AuthorizationTransport{
  56. SecretID: os.Getenv("COS_SECRETID"),
  57. SecretKey: os.Getenv("COS_SECRETKEY"),
  58. },
  59. })
  60. opt := &cos.BucketPutOptions{
  61. XCosACL: "public-read",
  62. }
  63. r, err := s.Client.Bucket.Put(context.Background(), opt)
  64. if err != nil && r.StatusCode == 409 {
  65. fmt.Println("BucketAlreadyOwnedByYou")
  66. } else if err != nil {
  67. assert.Nil(s.T(), err, "PutBucket Failed")
  68. }
  69. }
  70. // Begin of api test
  71. // Service API
  72. func (s *CosTestSuite) TestGetService() {
  73. _, _, err := s.Client.Service.Get(context.Background())
  74. assert.Nil(s.T(), err, "GetService Failed")
  75. }
  76. // Bucket API
  77. func (s *CosTestSuite) TestPutHeadDeleteBucket() {
  78. // Notic sometimes the bucket host can not analyis, may has i/o timeout problem
  79. u := "http://gosdkbuckettest-" + time.Now().Format(time.RFC3339) + "-" + s.Appid + ".cos.ap-beijing-1.myqcloud.com"
  80. iu, _ := url.Parse(u)
  81. ib := &cos.BaseURL{BucketURL: iu}
  82. client := cos.NewClient(ib, &http.Client{
  83. Transport: &cos.AuthorizationTransport{
  84. SecretID: os.Getenv("COS_SECRETID"),
  85. SecretKey: os.Getenv("COS_SECRETKEY"),
  86. },
  87. })
  88. r, err := client.Bucket.Put(context.Background(), nil)
  89. if err != nil && r.StatusCode == 409 {
  90. fmt.Println("BucketAlreadyOwnedByYou")
  91. } else if err != nil {
  92. assert.Nil(s.T(), err, "PutBucket Failed")
  93. }
  94. time.Sleep(3 * time.Second)
  95. _, err = client.Bucket.Head(context.Background())
  96. assert.Nil(s.T(), err, "HeadBucket Failed")
  97. _, err = client.Bucket.Delete(context.Background())
  98. assert.Nil(s.T(), err, "DeleteBucket Failed")
  99. }
  100. func (s *CosTestSuite) TestPutBucketACLIllegal() {
  101. opt := &cos.BucketPutACLOptions{
  102. Header: &cos.ACLHeaderOptions{
  103. XCosACL: "public-read-writ",
  104. },
  105. }
  106. _, err := s.Client.Bucket.PutACL(context.Background(), opt)
  107. assert.NotNil(s.T(), err, "PutBucketACL illegal Failed")
  108. }
  109. func (s *CosTestSuite) TestPutGetBucketACLNormal() {
  110. // with header
  111. opt := &cos.BucketPutACLOptions{
  112. Header: &cos.ACLHeaderOptions{
  113. XCosACL: "private",
  114. },
  115. }
  116. _, err := s.Client.Bucket.PutACL(context.Background(), opt)
  117. assert.Nil(s.T(), err, "PutBucketACL normal Failed")
  118. v, _, err := s.Client.Bucket.GetACL(context.Background())
  119. assert.Nil(s.T(), err, "GetBucketACL normal Failed")
  120. assert.Equal(s.T(), 1, len(v.AccessControlList), "GetBucketACL normal Failed, must be private")
  121. }
  122. func (s *CosTestSuite) TestGetBucket() {
  123. opt := &cos.BucketGetOptions{
  124. Prefix: "中文",
  125. MaxKeys: 3,
  126. }
  127. _, _, err := s.Client.Bucket.Get(context.Background(), opt)
  128. assert.Nil(s.T(), err, "GetBucket Failed")
  129. }
  130. func (s *CosTestSuite) TestGetBucketLocation() {
  131. v, _, err := s.Client.Bucket.GetLocation(context.Background())
  132. assert.Nil(s.T(), err, "GetLocation Failed")
  133. assert.Equal(s.T(), s.Region, v.Location, "GetLocation wrong region")
  134. }
  135. func (s *CosTestSuite) TestPutGetDeleteCORS() {
  136. opt := &cos.BucketPutCORSOptions{
  137. Rules: []cos.BucketCORSRule{
  138. {
  139. AllowedOrigins: []string{"http://www.qq.com"},
  140. AllowedMethods: []string{"PUT", "GET"},
  141. AllowedHeaders: []string{"x-cos-meta-test", "x-cos-xx"},
  142. MaxAgeSeconds: 500,
  143. ExposeHeaders: []string{"x-cos-meta-test1"},
  144. },
  145. },
  146. }
  147. _, err := s.Client.Bucket.PutCORS(context.Background(), opt)
  148. assert.Nil(s.T(), err, "PutBucketCORS Failed")
  149. v, _, err := s.Client.Bucket.GetCORS(context.Background())
  150. assert.Nil(s.T(), err, "GetBucketCORS Failed")
  151. assert.Equal(s.T(), 1, len(v.Rules), "GetBucketCORS wrong number rules")
  152. }
  153. func (s *CosTestSuite) TestPutGetDeleteLifeCycle() {
  154. lc := &cos.BucketPutLifecycleOptions{
  155. Rules: []cos.BucketLifecycleRule{
  156. {
  157. ID: "1234",
  158. Filter: &cos.BucketLifecycleFilter{Prefix: "test"},
  159. Status: "Enabled",
  160. Transition: &cos.BucketLifecycleTransition{
  161. Days: 10,
  162. StorageClass: "Standard",
  163. },
  164. },
  165. },
  166. }
  167. _, err := s.Client.Bucket.PutLifecycle(context.Background(), lc)
  168. assert.Nil(s.T(), err, "PutBucketLifecycle Failed")
  169. _, r, err := s.Client.Bucket.GetLifecycle(context.Background())
  170. // Might cleaned by other case concrrent
  171. if err != nil && 404 != r.StatusCode {
  172. assert.Nil(s.T(), err, "GetBucketLifecycle Failed")
  173. }
  174. _, err = s.Client.Bucket.DeleteLifecycle(context.Background())
  175. assert.Nil(s.T(), err, "DeleteBucketLifecycle Failed")
  176. }
  177. func (s *CosTestSuite) TestListMultipartUploads() {
  178. // Create new upload
  179. name := "test_multipart" + time.Now().Format(time.RFC3339)
  180. flag := false
  181. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  182. assert.Nil(s.T(), err, "InitiateMultipartUpload Failed")
  183. id := v.UploadID
  184. // List
  185. r, _, err := s.Client.Bucket.ListMultipartUploads(context.Background(), nil)
  186. assert.Nil(s.T(), err, "ListMultipartUploads Failed")
  187. for _, p := range r.Uploads {
  188. if p.Key == name {
  189. assert.Equal(s.T(), id, p.UploadID, "ListMultipartUploads wrong uploadid")
  190. flag = true
  191. }
  192. }
  193. assert.Equal(s.T(), true, flag, "ListMultipartUploads wrong key")
  194. // Abort
  195. _, err = s.Client.Object.AbortMultipartUpload(context.Background(), name, id)
  196. assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  197. }
  198. // Object API
  199. func (s *CosTestSuite) TestPutHeadGetDeleteObject_10MB() {
  200. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  201. b := make([]byte, 1024*1024*10)
  202. _, err := rand.Read(b)
  203. content := fmt.Sprintf("%X", b)
  204. f := strings.NewReader(content)
  205. _, err = s.Client.Object.Put(context.Background(), name, f, nil)
  206. assert.Nil(s.T(), err, "PutObject Failed")
  207. _, err = s.Client.Object.Head(context.Background(), name, nil)
  208. assert.Nil(s.T(), err, "HeadObject Failed")
  209. _, err = s.Client.Object.Delete(context.Background(), name)
  210. assert.Nil(s.T(), err, "DeleteObject Failed")
  211. }
  212. func (s *CosTestSuite) TestPutGetDeleteObjectByFile_10MB() {
  213. // Create tmp file
  214. filePath := "tmpfile" + time.Now().Format(time.RFC3339)
  215. newfile, err := os.Create(filePath)
  216. assert.Nil(s.T(), err, "create tmp file Failed")
  217. defer newfile.Close()
  218. name := "test/objectPutByFile" + time.Now().Format(time.RFC3339)
  219. b := make([]byte, 1024*1024*10)
  220. _, err = rand.Read(b)
  221. newfile.Write(b)
  222. _, err = s.Client.Object.PutFromFile(context.Background(), name, filePath, nil)
  223. assert.Nil(s.T(), err, "PutObject Failed")
  224. // Over write tmp file
  225. _, err = s.Client.Object.GetToFile(context.Background(), name, filePath, nil)
  226. assert.Nil(s.T(), err, "HeadObject Failed")
  227. _, err = s.Client.Object.Delete(context.Background(), name)
  228. assert.Nil(s.T(), err, "DeleteObject Failed")
  229. // remove the local tmp file
  230. err = os.Remove(filePath)
  231. assert.Nil(s.T(), err, "remove local file Failed")
  232. }
  233. func (s *CosTestSuite) TestPutGetDeleteObjectSpecialName() {
  234. f := strings.NewReader("test")
  235. name := s.SepFileName + time.Now().Format(time.RFC3339)
  236. _, err := s.Client.Object.Put(context.Background(), name, f, nil)
  237. assert.Nil(s.T(), err, "PutObject Failed")
  238. resp, err := s.Client.Object.Get(context.Background(), name, nil)
  239. assert.Nil(s.T(), err, "GetObject Failed")
  240. defer resp.Body.Close()
  241. bs, _ := ioutil.ReadAll(resp.Body)
  242. assert.Equal(s.T(), "test", string(bs), "GetObject failed content wrong")
  243. _, err = s.Client.Object.Delete(context.Background(), name)
  244. assert.Nil(s.T(), err, "DeleteObject Failed")
  245. }
  246. func (s *CosTestSuite) TestPutObjectToNonExistBucket() {
  247. u := "http://gosdknonexistbucket-" + s.Appid + ".cos." + s.Region + ".myqcloud.com"
  248. iu, _ := url.Parse(u)
  249. ib := &cos.BaseURL{BucketURL: iu}
  250. client := cos.NewClient(ib, &http.Client{
  251. Transport: &cos.AuthorizationTransport{
  252. SecretID: os.Getenv("COS_SECRETID"),
  253. SecretKey: os.Getenv("COS_SECRETKEY"),
  254. },
  255. })
  256. name := "test/objectPut.go"
  257. f := strings.NewReader("test")
  258. r, err := client.Object.Put(context.Background(), name, f, nil)
  259. assert.NotNil(s.T(), err, "PutObject ToNonExistBucket Failed")
  260. assert.Equal(s.T(), 404, r.StatusCode, "PutObject ToNonExistBucket, not 404")
  261. }
  262. func (s *CosTestSuite) TestPutGetObjectACL() {
  263. name := "test/objectACL.go" + time.Now().Format(time.RFC3339)
  264. f := strings.NewReader("test")
  265. _, err := s.Client.Object.Put(context.Background(), name, f, nil)
  266. assert.Nil(s.T(), err, "PutObject Failed")
  267. // Put acl
  268. opt := &cos.ObjectPutACLOptions{
  269. Header: &cos.ACLHeaderOptions{
  270. XCosACL: "public-read",
  271. },
  272. }
  273. _, err = s.Client.Object.PutACL(context.Background(), name, opt)
  274. assert.Nil(s.T(), err, "PutObjectACL Failed")
  275. v, _, err := s.Client.Object.GetACL(context.Background(), name)
  276. assert.Nil(s.T(), err, "GetObjectACL Failed")
  277. assert.Equal(s.T(), 2, len(v.AccessControlList), "GetLifecycle wrong number rules")
  278. _, err = s.Client.Object.Delete(context.Background(), name)
  279. assert.Nil(s.T(), err, "DeleteObject Failed")
  280. }
  281. func (s *CosTestSuite) TestCopyObject() {
  282. u := "http://gosdkcopytest-" + s.Appid + ".cos.ap-beijing-1.myqcloud.com"
  283. iu, _ := url.Parse(u)
  284. ib := &cos.BaseURL{BucketURL: iu}
  285. c := cos.NewClient(ib, &http.Client{
  286. Transport: &cos.AuthorizationTransport{
  287. SecretID: os.Getenv("COS_SECRETID"),
  288. SecretKey: os.Getenv("COS_SECRETKEY"),
  289. },
  290. })
  291. opt := &cos.BucketPutOptions{
  292. XCosACL: "public-read",
  293. }
  294. // Notice in intranet the bucket host sometimes has i/o timeout problem
  295. r, err := c.Bucket.Put(context.Background(), opt)
  296. if err != nil && r.StatusCode == 409 {
  297. fmt.Println("BucketAlreadyOwnedByYou")
  298. } else if err != nil {
  299. assert.Nil(s.T(), err, "PutBucket Failed")
  300. }
  301. source := "test/objectMove1" + time.Now().Format(time.RFC3339)
  302. expected := "test"
  303. f := strings.NewReader(expected)
  304. _, err = c.Object.Put(context.Background(), source, f, nil)
  305. assert.Nil(s.T(), err, "PutObject Failed")
  306. time.Sleep(3 * time.Second)
  307. // Copy file
  308. soruceURL := fmt.Sprintf("%s/%s", iu.Host, source)
  309. dest := source
  310. //opt := &cos.ObjectCopyOptions{}
  311. _, _, err = s.Client.Object.Copy(context.Background(), dest, soruceURL, nil)
  312. assert.Nil(s.T(), err, "PutObjectCopy Failed")
  313. // Check content
  314. resp, err := s.Client.Object.Get(context.Background(), dest, nil)
  315. assert.Nil(s.T(), err, "GetObject Failed")
  316. bs, _ := ioutil.ReadAll(resp.Body)
  317. resp.Body.Close()
  318. result := string(bs)
  319. assert.Equal(s.T(), expected, result, "PutObjectCopy Failed, wrong content")
  320. }
  321. func (s *CosTestSuite) TestCreateAbortMultipartUpload() {
  322. name := "test_multipart" + time.Now().Format(time.RFC3339)
  323. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  324. assert.Nil(s.T(), err, "InitiateMultipartUpload Failed")
  325. _, err = s.Client.Object.AbortMultipartUpload(context.Background(), name, v.UploadID)
  326. assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  327. }
  328. func (s *CosTestSuite) TestCreateCompleteMultipartUpload() {
  329. name := "test/test_complete_upload" + time.Now().Format(time.RFC3339)
  330. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  331. uploadID := v.UploadID
  332. blockSize := 1024 * 1024 * 3
  333. opt := &cos.CompleteMultipartUploadOptions{}
  334. for i := 1; i < 3; i++ {
  335. b := make([]byte, blockSize)
  336. _, err := rand.Read(b)
  337. content := fmt.Sprintf("%X", b)
  338. f := strings.NewReader(content)
  339. resp, err := s.Client.Object.UploadPart(
  340. context.Background(), name, uploadID, i, f, nil,
  341. )
  342. assert.Nil(s.T(), err, "UploadPart Failed")
  343. etag := resp.Header.Get("Etag")
  344. opt.Parts = append(opt.Parts, cos.Object{
  345. PartNumber: i, ETag: etag},
  346. )
  347. }
  348. _, _, err = s.Client.Object.CompleteMultipartUpload(
  349. context.Background(), name, uploadID, opt,
  350. )
  351. assert.Nil(s.T(), err, "CompleteMultipartUpload Failed")
  352. }
  353. // End of api test
  354. // All methods that begin with "Test" are run as tests within a
  355. // suite.
  356. // In order for 'go test' to run this suite, we need to create
  357. // a normal test function and pass our suite to suite.Run
  358. func TestCosTestSuite(t *testing.T) {
  359. suite.Run(t, new(CosTestSuite))
  360. }
  361. func (s *CosTestSuite) TearDownSuite() {
  362. // Clean the file in bucket
  363. // r, _, err := s.Client.Bucket.ListMultipartUploads(context.Background(), nil)
  364. // assert.Nil(s.T(), err, "ListMultipartUploads Failed")
  365. // for _, p := range r.Uploads {
  366. // // Abort
  367. // _, err = s.Client.Object.AbortMultipartUpload(context.Background(), p.Key, p.UploadID)
  368. // assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  369. // }
  370. // // Delete objects
  371. // opt := &cos.BucketGetOptions{
  372. // MaxKeys: 500,
  373. // }
  374. // v, _, err := s.Client.Bucket.Get(context.Background(), opt)
  375. // assert.Nil(s.T(), err, "GetBucket Failed")
  376. // for _, c := range v.Contents {
  377. // _, err := s.Client.Object.Delete(context.Background(), c.Key)
  378. // assert.Nil(s.T(), err, "DeleteObject Failed")
  379. // }
  380. // When clean up these infos, can not solve the concurrent test problem
  381. fmt.Println("tear down~")
  382. }