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.

497 lines
13 KiB

  1. package cos
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/rand"
  6. "encoding/json"
  7. "encoding/xml"
  8. "fmt"
  9. "hash/crc64"
  10. "io/ioutil"
  11. "net/http"
  12. "os"
  13. "reflect"
  14. "strconv"
  15. "testing"
  16. "time"
  17. )
  18. func TestCIService_EncodePicOperations(t *testing.T) {
  19. opt := &PicOperations{
  20. IsPicInfo: 1,
  21. Rules: []PicOperationsRules{
  22. {
  23. FileId: "example.jpg",
  24. Rule: "imageView2/format/png",
  25. },
  26. },
  27. }
  28. res := EncodePicOperations(opt)
  29. jsonStr := `{"is_pic_info":1,"rules":[{"fileid":"example.jpg","rule":"imageView2/format/png"}]}`
  30. if jsonStr != res {
  31. t.Fatalf("EncodePicOperations Failed, returned:%v, want:%v", res, jsonStr)
  32. }
  33. }
  34. func TestCIService_ImageProcess(t *testing.T) {
  35. setup()
  36. defer teardown()
  37. name := "test.jpg"
  38. opt := &ImageProcessOptions{
  39. IsPicInfo: 1,
  40. Rules: []PicOperationsRules{
  41. {
  42. FileId: "format.jpg",
  43. Rule: "imageView2/format/png",
  44. },
  45. },
  46. }
  47. mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
  48. testMethod(t, r, "POST")
  49. vs := values{
  50. "image_process": "",
  51. }
  52. testFormValues(t, r, vs)
  53. header := r.Header.Get("Pic-Operations")
  54. body := new(ImageProcessOptions)
  55. err := json.Unmarshal([]byte(header), body)
  56. want := opt
  57. if err != nil {
  58. t.Errorf("CI.ImageProcess Failed: %v", err)
  59. }
  60. if !reflect.DeepEqual(want, body) {
  61. t.Errorf("CI.ImageProcess Failed, wanted:%v, body:%v", want, body)
  62. }
  63. fmt.Fprint(w, `<UploadResult>
  64. <OriginalInfo>
  65. <Key>test.jpg</Key>
  66. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
  67. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  68. <ImageInfo>
  69. <Format>PNG</Format>
  70. <Width>103</Width>
  71. <Height>99</Height>
  72. <Quality>100</Quality>
  73. <Ave>0xa08162</Ave>
  74. <Orientation>0</Orientation>
  75. </ImageInfo>
  76. </OriginalInfo>
  77. <ProcessResults>
  78. <Object>
  79. <Key>format.jpg</Key>
  80. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
  81. <Format>PNG</Format>
  82. <Width>103</Width>
  83. <Height>99</Height>
  84. <Size>21351</Size>
  85. <Quality>100</Quality>
  86. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  87. </Object>
  88. </ProcessResults>
  89. </UploadResult>`)
  90. })
  91. want := &ImageProcessResult{
  92. XMLName: xml.Name{Local: "UploadResult"},
  93. OriginalInfo: &PicOriginalInfo{
  94. Key: "test.jpg",
  95. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
  96. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  97. ImageInfo: &PicImageInfo{
  98. Format: "PNG",
  99. Width: 103,
  100. Height: 99,
  101. Quality: 100,
  102. Ave: "0xa08162",
  103. Orientation: 0,
  104. },
  105. },
  106. ProcessResults: &PicProcessObject{
  107. Key: "format.jpg",
  108. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
  109. Format: "PNG",
  110. Width: 103,
  111. Height: 99,
  112. Size: 21351,
  113. Quality: 100,
  114. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  115. },
  116. }
  117. res, _, err := client.CI.ImageProcess(context.Background(), name, opt)
  118. if err != nil {
  119. t.Fatalf("CI.ImageProcess returned error: %v", err)
  120. }
  121. if !reflect.DeepEqual(res, want) {
  122. t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
  123. }
  124. }
  125. func TestCIService_ImageRecognition(t *testing.T) {
  126. setup()
  127. defer teardown()
  128. name := "test.jpg"
  129. detectType := "porn,terrorist,politics"
  130. mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
  131. testMethod(t, r, "GET")
  132. vs := values{
  133. "ci-process": "sensitive-content-recognition",
  134. "detect-type": "porn,terrorist,politics",
  135. }
  136. testFormValues(t, r, vs)
  137. fmt.Fprint(w, `<RecognitionResult>
  138. <PornInfo>
  139. <Code>0</Code>
  140. <Msg>OK</Msg>
  141. <HitFlag>0</HitFlag>
  142. <Score>0</Score>
  143. <Label/>
  144. </PornInfo>
  145. <TerroristInfo>
  146. <Code>0</Code>
  147. <Msg>OK</Msg>
  148. <HitFlag>0</HitFlag>
  149. <Score>0</Score>
  150. <Label/>
  151. </TerroristInfo>
  152. <PoliticsInfo>
  153. <Code>0</Code>
  154. <Msg>OK</Msg>
  155. <HitFlag>0</HitFlag>
  156. <Score>0</Score>
  157. <Label/>
  158. </PoliticsInfo>
  159. </RecognitionResult>`)
  160. })
  161. want := &ImageRecognitionResult{
  162. XMLName: xml.Name{Local: "RecognitionResult"},
  163. PornInfo: &RecognitionInfo{
  164. Code: 0,
  165. Msg: "OK",
  166. HitFlag: 0,
  167. Score: 0,
  168. },
  169. TerroristInfo: &RecognitionInfo{
  170. Code: 0,
  171. Msg: "OK",
  172. HitFlag: 0,
  173. Score: 0,
  174. },
  175. PoliticsInfo: &RecognitionInfo{
  176. Code: 0,
  177. Msg: "OK",
  178. HitFlag: 0,
  179. Score: 0,
  180. },
  181. }
  182. res, _, err := client.CI.ImageRecognition(context.Background(), name, detectType)
  183. if err != nil {
  184. t.Fatalf("CI.ImageRecognitionreturned error: %v", err)
  185. }
  186. if !reflect.DeepEqual(res, want) {
  187. t.Errorf("CI.ImageRecognition failed, return:%v, want:%v", res, want)
  188. }
  189. }
  190. func TestCIService_Put(t *testing.T) {
  191. setup()
  192. defer teardown()
  193. name := "test.jpg"
  194. data := make([]byte, 1024*1024*3)
  195. rand.Read(data)
  196. pic := &ImageProcessOptions{
  197. IsPicInfo: 1,
  198. Rules: []PicOperationsRules{
  199. {
  200. FileId: "format.jpg",
  201. Rule: "imageView2/format/png",
  202. },
  203. },
  204. }
  205. mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
  206. testMethod(t, r, "PUT")
  207. header := r.Header.Get("Pic-Operations")
  208. body := new(ImageProcessOptions)
  209. err := json.Unmarshal([]byte(header), body)
  210. want := pic
  211. if err != nil {
  212. t.Errorf("CI.Put Failed: %v", err)
  213. }
  214. if !reflect.DeepEqual(want, body) {
  215. t.Errorf("CI.Put Failed, wanted:%v, body:%v", want, body)
  216. }
  217. tb := crc64.MakeTable(crc64.ECMA)
  218. ht := crc64.New(tb)
  219. tr := TeeReader(r.Body, ht, 0, nil)
  220. bs, err := ioutil.ReadAll(tr)
  221. if err != nil {
  222. t.Errorf("CI.Put ReadAll Failed: %v", err)
  223. }
  224. if bytes.Compare(bs, data) != 0 {
  225. t.Errorf("CI.Put Failed, data isn't consistent")
  226. }
  227. crc := tr.Crc64()
  228. w.Header().Add("x-cos-hash-crc64ecma", strconv.FormatUint(crc, 10))
  229. fmt.Fprint(w, `<UploadResult>
  230. <OriginalInfo>
  231. <Key>test.jpg</Key>
  232. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
  233. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  234. <ImageInfo>
  235. <Format>PNG</Format>
  236. <Width>103</Width>
  237. <Height>99</Height>
  238. <Quality>100</Quality>
  239. <Ave>0xa08162</Ave>
  240. <Orientation>0</Orientation>
  241. </ImageInfo>
  242. </OriginalInfo>
  243. <ProcessResults>
  244. <Object>
  245. <Key>format.jpg</Key>
  246. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
  247. <Format>PNG</Format>
  248. <Width>103</Width>
  249. <Height>99</Height>
  250. <Size>21351</Size>
  251. <Quality>100</Quality>
  252. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  253. </Object>
  254. </ProcessResults>
  255. </UploadResult>`)
  256. })
  257. want := &ImageProcessResult{
  258. XMLName: xml.Name{Local: "UploadResult"},
  259. OriginalInfo: &PicOriginalInfo{
  260. Key: "test.jpg",
  261. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
  262. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  263. ImageInfo: &PicImageInfo{
  264. Format: "PNG",
  265. Width: 103,
  266. Height: 99,
  267. Quality: 100,
  268. Ave: "0xa08162",
  269. Orientation: 0,
  270. },
  271. },
  272. ProcessResults: &PicProcessObject{
  273. Key: "format.jpg",
  274. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
  275. Format: "PNG",
  276. Width: 103,
  277. Height: 99,
  278. Size: 21351,
  279. Quality: 100,
  280. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  281. },
  282. }
  283. f := bytes.NewReader(data)
  284. opt := &ObjectPutOptions{
  285. nil,
  286. &ObjectPutHeaderOptions{
  287. XOptionHeader: &http.Header{},
  288. },
  289. }
  290. opt.XOptionHeader.Add("Pic-Operations", EncodePicOperations(pic))
  291. res, _, err := client.CI.Put(context.Background(), name, f, opt)
  292. if err != nil {
  293. t.Fatalf("CI.Put returned error: %v", err)
  294. }
  295. if !reflect.DeepEqual(res, want) {
  296. t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
  297. }
  298. }
  299. func TestCIService_PutFromFile(t *testing.T) {
  300. setup()
  301. defer teardown()
  302. name := "test.jpg"
  303. filePath := "test.file" + time.Now().Format(time.RFC3339)
  304. newfile, err := os.Create(filePath)
  305. if err != nil {
  306. t.Fatalf("creat tmp file failed")
  307. }
  308. defer os.Remove(filePath)
  309. data := make([]byte, 1024*1024*3)
  310. rand.Read(data)
  311. newfile.Write(data)
  312. newfile.Close()
  313. pic := &ImageProcessOptions{
  314. IsPicInfo: 1,
  315. Rules: []PicOperationsRules{
  316. {
  317. FileId: "format.jpg",
  318. Rule: "imageView2/format/png",
  319. },
  320. },
  321. }
  322. mux.HandleFunc("/test.jpg", func(w http.ResponseWriter, r *http.Request) {
  323. testMethod(t, r, "PUT")
  324. header := r.Header.Get("Pic-Operations")
  325. body := new(ImageProcessOptions)
  326. err := json.Unmarshal([]byte(header), body)
  327. want := pic
  328. if err != nil {
  329. t.Errorf("CI.Put Failed: %v", err)
  330. }
  331. if !reflect.DeepEqual(want, body) {
  332. t.Errorf("CI.Put Failed, wanted:%v, body:%v", want, body)
  333. }
  334. tb := crc64.MakeTable(crc64.ECMA)
  335. ht := crc64.New(tb)
  336. tr := TeeReader(r.Body, ht, 0, nil)
  337. bs, err := ioutil.ReadAll(tr)
  338. if err != nil {
  339. t.Errorf("CI.Put ReadAll Failed: %v", err)
  340. }
  341. if bytes.Compare(bs, data) != 0 {
  342. t.Errorf("CI.Put Failed, data isn't consistent")
  343. }
  344. crc := tr.Crc64()
  345. w.Header().Add("x-cos-hash-crc64ecma", strconv.FormatUint(crc, 10))
  346. fmt.Fprint(w, `<UploadResult>
  347. <OriginalInfo>
  348. <Key>test.jpg</Key>
  349. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg</Location>
  350. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  351. <ImageInfo>
  352. <Format>PNG</Format>
  353. <Width>103</Width>
  354. <Height>99</Height>
  355. <Quality>100</Quality>
  356. <Ave>0xa08162</Ave>
  357. <Orientation>0</Orientation>
  358. </ImageInfo>
  359. </OriginalInfo>
  360. <ProcessResults>
  361. <Object>
  362. <Key>format.jpg</Key>
  363. <Location>example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg</Location>
  364. <Format>PNG</Format>
  365. <Width>103</Width>
  366. <Height>99</Height>
  367. <Size>21351</Size>
  368. <Quality>100</Quality>
  369. <ETag>&quot;8894dbe5e3ebfaf761e39b9d619c28f3327b8d85&quot;</ETag>
  370. </Object>
  371. </ProcessResults>
  372. </UploadResult>`)
  373. })
  374. want := &ImageProcessResult{
  375. XMLName: xml.Name{Local: "UploadResult"},
  376. OriginalInfo: &PicOriginalInfo{
  377. Key: "test.jpg",
  378. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/test.jpg",
  379. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  380. ImageInfo: &PicImageInfo{
  381. Format: "PNG",
  382. Width: 103,
  383. Height: 99,
  384. Quality: 100,
  385. Ave: "0xa08162",
  386. Orientation: 0,
  387. },
  388. },
  389. ProcessResults: &PicProcessObject{
  390. Key: "format.jpg",
  391. Location: "example-1250000000.cos.ap-guangzhou.myqcloud.com/format.jpg",
  392. Format: "PNG",
  393. Width: 103,
  394. Height: 99,
  395. Size: 21351,
  396. Quality: 100,
  397. ETag: "\"8894dbe5e3ebfaf761e39b9d619c28f3327b8d85\"",
  398. },
  399. }
  400. opt := &ObjectPutOptions{
  401. nil,
  402. &ObjectPutHeaderOptions{
  403. XOptionHeader: &http.Header{},
  404. },
  405. }
  406. opt.XOptionHeader.Add("Pic-Operations", EncodePicOperations(pic))
  407. res, _, err := client.CI.PutFromFile(context.Background(), name, filePath, opt)
  408. if err != nil {
  409. t.Fatalf("CI.Put returned error: %v", err)
  410. }
  411. if !reflect.DeepEqual(res, want) {
  412. t.Errorf("CI.ImageProcess failed, return:%v, want:%v", res, want)
  413. }
  414. }
  415. func TestBucketService_GetGuetzli(t *testing.T) {
  416. setup()
  417. defer teardown()
  418. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  419. testMethod(t, r, "GET")
  420. vs := values{
  421. "guetzli": "",
  422. }
  423. testFormValues(t, r, vs)
  424. fmt.Fprint(w, `<GuetzliStatus>on</GuetzliStatus>`)
  425. })
  426. res, _, err := client.CI.GetGuetzli(context.Background())
  427. if err != nil {
  428. t.Fatalf("CI.GetGuetzli returned error %v", err)
  429. }
  430. want := &GetGuetzliResult{
  431. XMLName: xml.Name{Local: "GuetzliStatus"},
  432. GuetzliStatus: "on",
  433. }
  434. if !reflect.DeepEqual(res, want) {
  435. t.Errorf("CI.GetGuetzli %+v, want %+v", res, want)
  436. }
  437. }
  438. func TestBucketService_PutGuetzli(t *testing.T) {
  439. setup()
  440. defer teardown()
  441. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  442. testMethod(t, r, "PUT")
  443. vs := values{
  444. "guetzli": "",
  445. }
  446. testFormValues(t, r, vs)
  447. })
  448. _, err := client.CI.PutGuetzli(context.Background())
  449. if err != nil {
  450. t.Fatalf("CI.PutGuetzli returned error: %v", err)
  451. }
  452. }
  453. func TestBucketService_DeleteGuetzli(t *testing.T) {
  454. setup()
  455. defer teardown()
  456. mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
  457. testMethod(t, r, "DELETE")
  458. vs := values{
  459. "guetzli": "",
  460. }
  461. testFormValues(t, r, vs)
  462. w.WriteHeader(http.StatusNoContent)
  463. })
  464. _, err := client.CI.DeleteGuetzli(context.Background())
  465. if err != nil {
  466. t.Fatalf("CI.PutGuetzli returned error: %v", err)
  467. }
  468. }