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.

485 lines
14 KiB

  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-" + 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. if err != nil {
  95. panic(err)
  96. }
  97. time.Sleep(3 * time.Second)
  98. _, err = client.Bucket.Head(context.Background())
  99. assert.Nil(s.T(), err, "HeadBucket Failed")
  100. if err == nil {
  101. _, err = client.Bucket.Delete(context.Background())
  102. assert.Nil(s.T(), err, "DeleteBucket Failed")
  103. }
  104. }
  105. func (s *CosTestSuite) TestPutBucketACLIllegal() {
  106. opt := &cos.BucketPutACLOptions{
  107. Header: &cos.ACLHeaderOptions{
  108. XCosACL: "public-read-writ",
  109. },
  110. }
  111. _, err := s.Client.Bucket.PutACL(context.Background(), opt)
  112. assert.NotNil(s.T(), err, "PutBucketACL illegal Failed")
  113. }
  114. func (s *CosTestSuite) TestPutGetBucketACLNormal() {
  115. // with header
  116. opt := &cos.BucketPutACLOptions{
  117. Header: &cos.ACLHeaderOptions{
  118. XCosACL: "private",
  119. },
  120. }
  121. _, err := s.Client.Bucket.PutACL(context.Background(), opt)
  122. assert.Nil(s.T(), err, "PutBucketACL normal Failed")
  123. v, _, err := s.Client.Bucket.GetACL(context.Background())
  124. assert.Nil(s.T(), err, "GetBucketACL normal Failed")
  125. assert.Equal(s.T(), 1, len(v.AccessControlList), "GetBucketACL normal Failed, must be private")
  126. }
  127. func (s *CosTestSuite) TestGetBucket() {
  128. opt := &cos.BucketGetOptions{
  129. Prefix: "中文",
  130. MaxKeys: 3,
  131. }
  132. _, _, err := s.Client.Bucket.Get(context.Background(), opt)
  133. assert.Nil(s.T(), err, "GetBucket Failed")
  134. }
  135. func (s *CosTestSuite) TestGetBucketLocation() {
  136. v, _, err := s.Client.Bucket.GetLocation(context.Background())
  137. assert.Nil(s.T(), err, "GetLocation Failed")
  138. assert.Equal(s.T(), s.Region, v.Location, "GetLocation wrong region")
  139. }
  140. func (s *CosTestSuite) TestPutGetDeleteCORS() {
  141. opt := &cos.BucketPutCORSOptions{
  142. Rules: []cos.BucketCORSRule{
  143. {
  144. AllowedOrigins: []string{"http://www.qq.com"},
  145. AllowedMethods: []string{"PUT", "GET"},
  146. AllowedHeaders: []string{"x-cos-meta-test", "x-cos-xx"},
  147. MaxAgeSeconds: 500,
  148. ExposeHeaders: []string{"x-cos-meta-test1"},
  149. },
  150. },
  151. }
  152. _, err := s.Client.Bucket.PutCORS(context.Background(), opt)
  153. assert.Nil(s.T(), err, "PutBucketCORS Failed")
  154. v, _, err := s.Client.Bucket.GetCORS(context.Background())
  155. assert.Nil(s.T(), err, "GetBucketCORS Failed")
  156. assert.Equal(s.T(), 1, len(v.Rules), "GetBucketCORS wrong number rules")
  157. }
  158. func (s *CosTestSuite) TestPutGetDeleteLifeCycle() {
  159. lc := &cos.BucketPutLifecycleOptions{
  160. Rules: []cos.BucketLifecycleRule{
  161. {
  162. ID: "1234",
  163. Filter: &cos.BucketLifecycleFilter{Prefix: "test"},
  164. Status: "Enabled",
  165. Transition: &cos.BucketLifecycleTransition{
  166. Days: 10,
  167. StorageClass: "Standard",
  168. },
  169. },
  170. },
  171. }
  172. _, err := s.Client.Bucket.PutLifecycle(context.Background(), lc)
  173. assert.Nil(s.T(), err, "PutBucketLifecycle Failed")
  174. _, r, err := s.Client.Bucket.GetLifecycle(context.Background())
  175. // Might cleaned by other case concrrent
  176. if err != nil && 404 != r.StatusCode {
  177. assert.Nil(s.T(), err, "GetBucketLifecycle Failed")
  178. }
  179. _, err = s.Client.Bucket.DeleteLifecycle(context.Background())
  180. assert.Nil(s.T(), err, "DeleteBucketLifecycle Failed")
  181. }
  182. func (s *CosTestSuite) TestListMultipartUploads() {
  183. // Create new upload
  184. name := "test_multipart" + time.Now().Format(time.RFC3339)
  185. flag := false
  186. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  187. assert.Nil(s.T(), err, "InitiateMultipartUpload Failed")
  188. id := v.UploadID
  189. // List
  190. r, _, err := s.Client.Bucket.ListMultipartUploads(context.Background(), nil)
  191. assert.Nil(s.T(), err, "ListMultipartUploads Failed")
  192. for _, p := range r.Uploads {
  193. if p.Key == name {
  194. assert.Equal(s.T(), id, p.UploadID, "ListMultipartUploads wrong uploadid")
  195. flag = true
  196. }
  197. }
  198. assert.Equal(s.T(), true, flag, "ListMultipartUploads wrong key")
  199. // Abort
  200. _, err = s.Client.Object.AbortMultipartUpload(context.Background(), name, id)
  201. assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  202. }
  203. // Object API
  204. func (s *CosTestSuite) TestPutHeadGetDeleteObject_10MB() {
  205. name := "test/objectPut" + time.Now().Format(time.RFC3339)
  206. b := make([]byte, 1024*1024*10)
  207. _, err := rand.Read(b)
  208. content := fmt.Sprintf("%X", b)
  209. f := strings.NewReader(content)
  210. _, err = s.Client.Object.Put(context.Background(), name, f, nil)
  211. assert.Nil(s.T(), err, "PutObject Failed")
  212. _, err = s.Client.Object.Head(context.Background(), name, nil)
  213. assert.Nil(s.T(), err, "HeadObject Failed")
  214. _, err = s.Client.Object.Delete(context.Background(), name)
  215. assert.Nil(s.T(), err, "DeleteObject Failed")
  216. }
  217. func (s *CosTestSuite) TestPutGetDeleteObjectByFile_10MB() {
  218. // Create tmp file
  219. filePath := "tmpfile" + time.Now().Format(time.RFC3339)
  220. newfile, err := os.Create(filePath)
  221. assert.Nil(s.T(), err, "create tmp file Failed")
  222. defer newfile.Close()
  223. name := "test/objectPutByFile" + time.Now().Format(time.RFC3339)
  224. b := make([]byte, 1024*1024*10)
  225. _, err = rand.Read(b)
  226. newfile.Write(b)
  227. _, err = s.Client.Object.PutFromFile(context.Background(), name, filePath, nil)
  228. assert.Nil(s.T(), err, "PutObject Failed")
  229. // Over write tmp file
  230. _, err = s.Client.Object.GetToFile(context.Background(), name, filePath, nil)
  231. assert.Nil(s.T(), err, "HeadObject Failed")
  232. _, err = s.Client.Object.Delete(context.Background(), name)
  233. assert.Nil(s.T(), err, "DeleteObject Failed")
  234. // remove the local tmp file
  235. err = os.Remove(filePath)
  236. assert.Nil(s.T(), err, "remove local file Failed")
  237. }
  238. func (s *CosTestSuite) TestPutGetDeleteObjectSpecialName() {
  239. f := strings.NewReader("test")
  240. name := s.SepFileName + time.Now().Format(time.RFC3339)
  241. _, err := s.Client.Object.Put(context.Background(), name, f, nil)
  242. assert.Nil(s.T(), err, "PutObject Failed")
  243. resp, err := s.Client.Object.Get(context.Background(), name, nil)
  244. assert.Nil(s.T(), err, "GetObject Failed")
  245. defer resp.Body.Close()
  246. bs, _ := ioutil.ReadAll(resp.Body)
  247. assert.Equal(s.T(), "test", string(bs), "GetObject failed content wrong")
  248. _, err = s.Client.Object.Delete(context.Background(), name)
  249. assert.Nil(s.T(), err, "DeleteObject Failed")
  250. }
  251. func (s *CosTestSuite) TestPutObjectToNonExistBucket() {
  252. u := "http://gosdknonexistbucket-" + s.Appid + ".cos." + s.Region + ".myqcloud.com"
  253. iu, _ := url.Parse(u)
  254. ib := &cos.BaseURL{BucketURL: iu}
  255. client := cos.NewClient(ib, &http.Client{
  256. Transport: &cos.AuthorizationTransport{
  257. SecretID: os.Getenv("COS_SECRETID"),
  258. SecretKey: os.Getenv("COS_SECRETKEY"),
  259. },
  260. })
  261. name := "test/objectPut.go"
  262. f := strings.NewReader("test")
  263. r, err := client.Object.Put(context.Background(), name, f, nil)
  264. assert.NotNil(s.T(), err, "PutObject ToNonExistBucket Failed")
  265. assert.Equal(s.T(), 404, r.StatusCode, "PutObject ToNonExistBucket, not 404")
  266. }
  267. func (s *CosTestSuite) TestPutGetObjectACL() {
  268. name := "test/objectACL.go" + time.Now().Format(time.RFC3339)
  269. f := strings.NewReader("test")
  270. _, err := s.Client.Object.Put(context.Background(), name, f, nil)
  271. assert.Nil(s.T(), err, "PutObject Failed")
  272. // Put acl
  273. opt := &cos.ObjectPutACLOptions{
  274. Header: &cos.ACLHeaderOptions{
  275. XCosACL: "public-read",
  276. },
  277. }
  278. _, err = s.Client.Object.PutACL(context.Background(), name, opt)
  279. assert.Nil(s.T(), err, "PutObjectACL Failed")
  280. v, _, err := s.Client.Object.GetACL(context.Background(), name)
  281. assert.Nil(s.T(), err, "GetObjectACL Failed")
  282. assert.Equal(s.T(), 2, len(v.AccessControlList), "GetLifecycle wrong number rules")
  283. _, err = s.Client.Object.Delete(context.Background(), name)
  284. assert.Nil(s.T(), err, "DeleteObject Failed")
  285. }
  286. func (s *CosTestSuite) TestPutObjectRestore() {
  287. name := "archivetest"
  288. putOpt := &cos.ObjectPutOptions{
  289. ObjectPutHeaderOptions: &cos.ObjectPutHeaderOptions{
  290. XCosStorageClass: "ARCHIVE",
  291. },
  292. }
  293. f := strings.NewReader("test")
  294. _, err := s.Client.Object.Put(context.Background(), name, f, putOpt)
  295. assert.Nil(s.T(), err, "PutObject Archive faild")
  296. opt := &cos.ObjectRestoreOptions{
  297. Days: 2,
  298. Tier: &cos.CASJobParameters{
  299. // Standard, Exepdited and Bulk
  300. Tier: "Expedited",
  301. },
  302. }
  303. resp, _ := s.Client.Object.PutRestore(context.Background(), name, opt)
  304. retCode := resp.StatusCode
  305. if retCode != 200 && retCode != 202 && retCode != 409 {
  306. right := false
  307. fmt.Println("PutObjectRestore get code is:", retCode)
  308. assert.Equal(s.T(), true, right, "PutObjectRestore Failed")
  309. }
  310. }
  311. func (s *CosTestSuite) TestCopyObject() {
  312. u := "http://gosdkcopytest-" + s.Appid + ".cos.ap-beijing-1.myqcloud.com"
  313. iu, _ := url.Parse(u)
  314. ib := &cos.BaseURL{BucketURL: iu}
  315. c := cos.NewClient(ib, &http.Client{
  316. Transport: &cos.AuthorizationTransport{
  317. SecretID: os.Getenv("COS_SECRETID"),
  318. SecretKey: os.Getenv("COS_SECRETKEY"),
  319. },
  320. })
  321. opt := &cos.BucketPutOptions{
  322. XCosACL: "public-read",
  323. }
  324. // Notice in intranet the bucket host sometimes has i/o timeout problem
  325. r, err := c.Bucket.Put(context.Background(), opt)
  326. if err != nil && r.StatusCode == 409 {
  327. fmt.Println("BucketAlreadyOwnedByYou")
  328. } else if err != nil {
  329. assert.Nil(s.T(), err, "PutBucket Failed")
  330. }
  331. source := "test/objectMove1" + time.Now().Format(time.RFC3339)
  332. expected := "test"
  333. f := strings.NewReader(expected)
  334. _, err = c.Object.Put(context.Background(), source, f, nil)
  335. assert.Nil(s.T(), err, "PutObject Failed")
  336. time.Sleep(3 * time.Second)
  337. // Copy file
  338. soruceURL := fmt.Sprintf("%s/%s", iu.Host, source)
  339. dest := source
  340. //opt := &cos.ObjectCopyOptions{}
  341. _, _, err = s.Client.Object.Copy(context.Background(), dest, soruceURL, nil)
  342. assert.Nil(s.T(), err, "PutObjectCopy Failed")
  343. // Check content
  344. resp, err := s.Client.Object.Get(context.Background(), dest, nil)
  345. assert.Nil(s.T(), err, "GetObject Failed")
  346. bs, _ := ioutil.ReadAll(resp.Body)
  347. resp.Body.Close()
  348. result := string(bs)
  349. assert.Equal(s.T(), expected, result, "PutObjectCopy Failed, wrong content")
  350. }
  351. func (s *CosTestSuite) TestCreateAbortMultipartUpload() {
  352. name := "test_multipart" + time.Now().Format(time.RFC3339)
  353. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  354. assert.Nil(s.T(), err, "InitiateMultipartUpload Failed")
  355. _, err = s.Client.Object.AbortMultipartUpload(context.Background(), name, v.UploadID)
  356. assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  357. }
  358. func (s *CosTestSuite) TestCreateCompleteMultipartUpload() {
  359. name := "test/test_complete_upload" + time.Now().Format(time.RFC3339)
  360. v, _, err := s.Client.Object.InitiateMultipartUpload(context.Background(), name, nil)
  361. uploadID := v.UploadID
  362. blockSize := 1024 * 1024 * 3
  363. opt := &cos.CompleteMultipartUploadOptions{}
  364. for i := 1; i < 3; i++ {
  365. b := make([]byte, blockSize)
  366. _, err := rand.Read(b)
  367. content := fmt.Sprintf("%X", b)
  368. f := strings.NewReader(content)
  369. resp, err := s.Client.Object.UploadPart(
  370. context.Background(), name, uploadID, i, f, nil,
  371. )
  372. assert.Nil(s.T(), err, "UploadPart Failed")
  373. etag := resp.Header.Get("Etag")
  374. opt.Parts = append(opt.Parts, cos.Object{
  375. PartNumber: i, ETag: etag},
  376. )
  377. }
  378. _, _, err = s.Client.Object.CompleteMultipartUpload(
  379. context.Background(), name, uploadID, opt,
  380. )
  381. assert.Nil(s.T(), err, "CompleteMultipartUpload Failed")
  382. }
  383. // End of api test
  384. // All methods that begin with "Test" are run as tests within a
  385. // suite.
  386. // In order for 'go test' to run this suite, we need to create
  387. // a normal test function and pass our suite to suite.Run
  388. func TestCosTestSuite(t *testing.T) {
  389. suite.Run(t, new(CosTestSuite))
  390. }
  391. func (s *CosTestSuite) TearDownSuite() {
  392. // Clean the file in bucket
  393. // r, _, err := s.Client.Bucket.ListMultipartUploads(context.Background(), nil)
  394. // assert.Nil(s.T(), err, "ListMultipartUploads Failed")
  395. // for _, p := range r.Uploads {
  396. // // Abort
  397. // _, err = s.Client.Object.AbortMultipartUpload(context.Background(), p.Key, p.UploadID)
  398. // assert.Nil(s.T(), err, "AbortMultipartUpload Failed")
  399. // }
  400. // // Delete objects
  401. // opt := &cos.BucketGetOptions{
  402. // MaxKeys: 500,
  403. // }
  404. // v, _, err := s.Client.Bucket.Get(context.Background(), opt)
  405. // assert.Nil(s.T(), err, "GetBucket Failed")
  406. // for _, c := range v.Contents {
  407. // _, err := s.Client.Object.Delete(context.Background(), c.Key)
  408. // assert.Nil(s.T(), err, "DeleteObject Failed")
  409. // }
  410. // When clean up these infos, can not solve the concurrent test problem
  411. fmt.Println("tear down~")
  412. }