1// Bucket test
2
3package oss
4
5import (
6	"bytes"
7	"encoding/base64"
8	"errors"
9	"fmt"
10	"io"
11	"io/ioutil"
12	"math/rand"
13	"net/http"
14	"os"
15	"path/filepath"
16	"strconv"
17	"strings"
18	"time"
19
20	"github.com/baiyubin/aliyun-sts-go-sdk/sts"
21
22	. "gopkg.in/check.v1"
23)
24
25type OssBucketSuite struct {
26	client        *Client
27	bucket        *Bucket
28	archiveBucket *Bucket
29}
30
31var _ = Suite(&OssBucketSuite{})
32
33var (
34	pastDate   = time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
35	futureDate = time.Date(2049, time.January, 10, 23, 0, 0, 0, time.UTC)
36)
37
38// SetUpSuite runs once when the suite starts running.
39func (s *OssBucketSuite) SetUpSuite(c *C) {
40	client, err := New(endpoint, accessID, accessKey)
41	c.Assert(err, IsNil)
42	s.client = client
43
44	s.client.CreateBucket(bucketName)
45
46	err = s.client.CreateBucket(archiveBucketName, StorageClass(StorageArchive))
47	c.Assert(err, IsNil)
48
49	time.Sleep(5 * time.Second)
50
51	bucket, err := s.client.Bucket(bucketName)
52	c.Assert(err, IsNil)
53	s.bucket = bucket
54
55	archiveBucket, err := s.client.Bucket(archiveBucketName)
56	c.Assert(err, IsNil)
57	s.archiveBucket = archiveBucket
58
59	testLogger.Println("test bucket started")
60}
61
62// TearDownSuite runs before each test or benchmark starts running.
63func (s *OssBucketSuite) TearDownSuite(c *C) {
64	for _, bucket := range []*Bucket{s.bucket, s.archiveBucket} {
65		// Delete multipart
66		lmu, err := bucket.ListMultipartUploads()
67		c.Assert(err, IsNil)
68
69		for _, upload := range lmu.Uploads {
70			imur := InitiateMultipartUploadResult{Bucket: bucketName, Key: upload.Key, UploadID: upload.UploadID}
71			err = bucket.AbortMultipartUpload(imur)
72			c.Assert(err, IsNil)
73		}
74
75		// Delete objects
76		lor, err := bucket.ListObjects()
77		c.Assert(err, IsNil)
78
79		for _, object := range lor.Objects {
80			err = bucket.DeleteObject(object.Key)
81			c.Assert(err, IsNil)
82		}
83	}
84
85	testLogger.Println("test bucket completed")
86}
87
88// SetUpTest runs after each test or benchmark runs.
89func (s *OssBucketSuite) SetUpTest(c *C) {
90	err := removeTempFiles("../oss", ".jpg")
91	c.Assert(err, IsNil)
92}
93
94// TearDownTest runs once after all tests or benchmarks have finished running.
95func (s *OssBucketSuite) TearDownTest(c *C) {
96	err := removeTempFiles("../oss", ".jpg")
97	c.Assert(err, IsNil)
98
99	err = removeTempFiles("../oss", ".txt")
100	c.Assert(err, IsNil)
101
102	err = removeTempFiles("../oss", ".temp")
103	c.Assert(err, IsNil)
104
105	err = removeTempFiles("../oss", ".txt1")
106	c.Assert(err, IsNil)
107
108	err = removeTempFiles("../oss", ".txt2")
109	c.Assert(err, IsNil)
110}
111
112// TestPutObject
113func (s *OssBucketSuite) TestPutObject(c *C) {
114	objectName := objectNamePrefix + "tpo"
115	objectValue := "大江东去,浪淘尽,千古风流人物。 故垒西边,人道是、三国周郎赤壁。 乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。" +
116		"遥想公谨当年,小乔初嫁了,雄姿英发。 羽扇纶巾,谈笑间、樯橹灰飞烟灭。故国神游,多情应笑我,早生华发,人生如梦,一尊还酹江月。"
117
118	// Put string
119	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
120	c.Assert(err, IsNil)
121
122	// Check
123	body, err := s.bucket.GetObject(objectName)
124	c.Assert(err, IsNil)
125	str, err := readBody(body)
126	c.Assert(err, IsNil)
127	c.Assert(str, Equals, objectValue)
128
129	acl, err := s.bucket.GetObjectACL(objectName)
130	c.Assert(err, IsNil)
131	testLogger.Println("aclRes:", acl)
132	c.Assert(acl.ACL, Equals, "default")
133
134	err = s.bucket.DeleteObject(objectName)
135	c.Assert(err, IsNil)
136
137	// Put bytes
138	err = s.bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
139	c.Assert(err, IsNil)
140
141	// Check
142	body, err = s.bucket.GetObject(objectName)
143	c.Assert(err, IsNil)
144	str, err = readBody(body)
145	c.Assert(err, IsNil)
146	c.Assert(str, Equals, objectValue)
147
148	err = s.bucket.DeleteObject(objectName)
149	c.Assert(err, IsNil)
150
151	// Put file
152	err = createFileAndWrite(objectName+".txt", []byte(objectValue))
153	c.Assert(err, IsNil)
154	fd, err := os.Open(objectName + ".txt")
155	c.Assert(err, IsNil)
156
157	err = s.bucket.PutObject(objectName, fd)
158	c.Assert(err, IsNil)
159	os.Remove(objectName + ".txt")
160
161	// Check
162	body, err = s.bucket.GetObject(objectName)
163	c.Assert(err, IsNil)
164	str, err = readBody(body)
165	c.Assert(err, IsNil)
166	c.Assert(str, Equals, objectValue)
167
168	err = s.bucket.DeleteObject(objectName)
169	c.Assert(err, IsNil)
170
171	// Put with properties
172	objectName = objectNamePrefix + "tpox"
173	options := []Option{
174		Expires(futureDate),
175		ObjectACL(ACLPublicRead),
176		Meta("myprop", "mypropval"),
177	}
178	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue), options...)
179	c.Assert(err, IsNil)
180
181	// Check
182	body, err = s.bucket.GetObject(objectName)
183	c.Assert(err, IsNil)
184	str, err = readBody(body)
185	c.Assert(err, IsNil)
186	c.Assert(str, Equals, objectValue)
187
188	acl, err = s.bucket.GetObjectACL(objectName)
189	c.Assert(err, IsNil)
190	testLogger.Println("GetObjectACL:", acl)
191	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
192
193	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
194	c.Assert(err, IsNil)
195	testLogger.Println("GetObjectDetailedMeta:", meta)
196	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
197
198	err = s.bucket.DeleteObject(objectName)
199	c.Assert(err, IsNil)
200}
201
202func (s *OssBucketSuite) TestSignURL(c *C) {
203	objectName := objectNamePrefix + randStr(5)
204	objectValue := randStr(20)
205
206	filePath := randLowStr(10)
207	content := "复写object"
208	createFile(filePath, content, c)
209
210	notExistfilePath := randLowStr(10)
211	os.Remove(notExistfilePath)
212
213	// Sign URL for put
214	str, err := s.bucket.SignURL(objectName, HTTPPut, 60)
215	c.Assert(err, IsNil)
216	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
217	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
218	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
219
220	// Error put object with URL
221	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue), ContentType("image/tiff"))
222	c.Assert(err, NotNil)
223	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
224
225	err = s.bucket.PutObjectFromFileWithURL(str, filePath, ContentType("image/tiff"))
226	c.Assert(err, NotNil)
227	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
228
229	// Put object with URL
230	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
231	c.Assert(err, IsNil)
232
233	acl, err := s.bucket.GetObjectACL(objectName)
234	c.Assert(err, IsNil)
235	c.Assert(acl.ACL, Equals, "default")
236
237	// Get object meta
238	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
239	c.Assert(err, IsNil)
240	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "application/octet-stream")
241	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "")
242
243	// Sign URL for function GetObjectWithURL
244	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
245	c.Assert(err, IsNil)
246	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
247	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
248	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
249
250	// Get object with URL
251	body, err := s.bucket.GetObjectWithURL(str)
252	c.Assert(err, IsNil)
253	str, err = readBody(body)
254	c.Assert(err, IsNil)
255	c.Assert(str, Equals, objectValue)
256
257	// Sign URL for function PutObjectWithURL
258	options := []Option{
259		ObjectACL(ACLPublicRead),
260		Meta("myprop", "mypropval"),
261		ContentType("image/tiff"),
262		ResponseContentEncoding("deflate"),
263	}
264	str, err = s.bucket.SignURL(objectName, HTTPPut, 60, options...)
265	c.Assert(err, IsNil)
266	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
267	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
268	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
269
270	// Put object with URL from file
271	// Without option, error
272	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
273	c.Assert(err, NotNil)
274	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
275
276	err = s.bucket.PutObjectFromFileWithURL(str, filePath)
277	c.Assert(err, NotNil)
278	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
279
280	// With option, error file
281	err = s.bucket.PutObjectFromFileWithURL(str, notExistfilePath, options...)
282	c.Assert(err, NotNil)
283
284	// With option
285	err = s.bucket.PutObjectFromFileWithURL(str, filePath, options...)
286	c.Assert(err, IsNil)
287
288	// Get object meta
289	meta, err = s.bucket.GetObjectDetailedMeta(objectName)
290	c.Assert(err, IsNil)
291	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
292	c.Assert(meta.Get(HTTPHeaderContentType), Equals, "image/tiff")
293
294	acl, err = s.bucket.GetObjectACL(objectName)
295	c.Assert(err, IsNil)
296	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
297
298	// Sign URL for function GetObjectToFileWithURL
299	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
300	c.Assert(err, IsNil)
301
302	// Get object to file with URL
303	newFile := randStr(10)
304	err = s.bucket.GetObjectToFileWithURL(str, newFile)
305	c.Assert(err, IsNil)
306	eq, err := compareFiles(filePath, newFile)
307	c.Assert(err, IsNil)
308	c.Assert(eq, Equals, true)
309	os.Remove(newFile)
310
311	// Get object to file error
312	err = s.bucket.GetObjectToFileWithURL(str, newFile, options...)
313	c.Assert(err, NotNil)
314	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
315	_, err = os.Stat(newFile)
316	c.Assert(err, NotNil)
317
318	// Get object error
319	body, err = s.bucket.GetObjectWithURL(str, options...)
320	c.Assert(err, NotNil)
321	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
322	c.Assert(body, IsNil)
323
324	// Sign URL for function GetObjectToFileWithURL
325	options = []Option{
326		Expires(futureDate),
327		ObjectACL(ACLPublicRead),
328		Meta("myprop", "mypropval"),
329		ContentType("image/tiff"),
330		ResponseContentEncoding("deflate"),
331	}
332	str, err = s.bucket.SignURL(objectName, HTTPGet, 60, options...)
333	c.Assert(err, IsNil)
334
335	// Get object to file with URL and options
336	err = s.bucket.GetObjectToFileWithURL(str, newFile, options...)
337	c.Assert(err, IsNil)
338	eq, err = compareFiles(filePath, newFile)
339	c.Assert(err, IsNil)
340	c.Assert(eq, Equals, true)
341	os.Remove(newFile)
342
343	// Get object to file error
344	err = s.bucket.GetObjectToFileWithURL(str, newFile)
345	c.Assert(err, NotNil)
346	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
347	_, err = os.Stat(newFile)
348	c.Assert(err, NotNil)
349
350	// Get object error
351	body, err = s.bucket.GetObjectWithURL(str)
352	c.Assert(err, NotNil)
353	c.Assert(err.(ServiceError).Code, Equals, "SignatureDoesNotMatch")
354	c.Assert(body, IsNil)
355
356	err = s.bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
357	c.Assert(err, IsNil)
358	str, err = s.bucket.SignURL(objectName, HTTPGet, 3600, AcceptEncoding("gzip"))
359	c.Assert(err, IsNil)
360	s.bucket.GetObjectToFileWithURL(str, newFile)
361	c.Assert(err, IsNil)
362
363	os.Remove(filePath)
364	os.Remove(newFile)
365
366	// Sign URL error
367	str, err = s.bucket.SignURL(objectName, HTTPGet, -1)
368	c.Assert(err, NotNil)
369
370	err = s.bucket.DeleteObject(objectName)
371	c.Assert(err, IsNil)
372
373	// Invalid URL parse
374	str = randStr(20)
375
376	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
377	c.Assert(err, NotNil)
378
379	err = s.bucket.GetObjectToFileWithURL(str, newFile)
380	c.Assert(err, NotNil)
381}
382
383func (s *OssBucketSuite) TestSignURLWithEscapedKey(c *C) {
384	// Key with '/'
385	objectName := "zyimg/86/e8/653b5dc97bb0022051a84c632bc4"
386	objectValue := "弃我去者,昨日之日不可留;乱我心者,今日之日多烦忧。长风万里送秋雁,对此可以酣高楼。蓬莱文章建安骨,中间小谢又清发。" +
387		"俱怀逸兴壮思飞,欲上青天揽明月。抽刀断水水更流,举杯销愁愁更愁。人生在世不称意,明朝散发弄扁舟。"
388
389	// Sign URL for function PutObjectWithURL
390	str, err := s.bucket.SignURL(objectName, HTTPPut, 60)
391	c.Assert(err, IsNil)
392	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
393	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
394	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
395
396	// Put object with URL
397	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
398	c.Assert(err, IsNil)
399
400	// Sign URL for function GetObjectWithURL
401	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
402	c.Assert(err, IsNil)
403	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
404	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
405	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
406
407	// Get object with URL
408	body, err := s.bucket.GetObjectWithURL(str)
409	c.Assert(err, IsNil)
410	str, err = readBody(body)
411	c.Assert(err, IsNil)
412	c.Assert(str, Equals, objectValue)
413
414	// Key with escaped chars
415	objectName = "<>[]()`?.,!@#$%^&'/*-_=+~:;"
416
417	// Sign URL for funciton PutObjectWithURL
418	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
419	c.Assert(err, IsNil)
420	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
421	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
422	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
423
424	// Put object with URL
425	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
426	c.Assert(err, IsNil)
427
428	// Sign URL for function GetObjectWithURL
429	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
430	c.Assert(err, IsNil)
431	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
432	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
433	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
434
435	// Get object with URL
436	body, err = s.bucket.GetObjectWithURL(str)
437	c.Assert(err, IsNil)
438	str, err = readBody(body)
439	c.Assert(err, IsNil)
440	c.Assert(str, Equals, objectValue)
441
442	// Key with Chinese chars
443	objectName = "风吹柳花满店香,吴姬压酒劝客尝。金陵子弟来相送,欲行不行各尽觞。请君试问东流水,别意与之谁短长。"
444
445	// Sign URL for function PutObjectWithURL
446	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
447	c.Assert(err, IsNil)
448	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
449	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
450	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
451
452	// Put object with URL
453	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
454	c.Assert(err, IsNil)
455
456	// Sign URL for get function GetObjectWithURL
457	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
458	c.Assert(err, IsNil)
459	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
460	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
461	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
462
463	// Get object with URL
464	body, err = s.bucket.GetObjectWithURL(str)
465	c.Assert(err, IsNil)
466	str, err = readBody(body)
467	c.Assert(err, IsNil)
468	c.Assert(str, Equals, objectValue)
469
470	// Key
471	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
472
473	// Sign URL for function PutObjectWithURL
474	str, err = s.bucket.SignURL(objectName, HTTPPut, 60)
475	c.Assert(err, IsNil)
476
477	// Put object with URL
478	err = s.bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
479	c.Assert(err, IsNil)
480
481	// Sign URL for function GetObjectWithURL
482	str, err = s.bucket.SignURL(objectName, HTTPGet, 60)
483	c.Assert(err, IsNil)
484
485	// Get object with URL
486	body, err = s.bucket.GetObjectWithURL(str)
487	c.Assert(err, IsNil)
488	str, err = readBody(body)
489	c.Assert(err, IsNil)
490	c.Assert(str, Equals, objectValue)
491
492	// Put object
493	err = s.bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
494	c.Assert(err, IsNil)
495
496	// Get object
497	body, err = s.bucket.GetObject(objectName)
498	c.Assert(err, IsNil)
499	str, err = readBody(body)
500	c.Assert(err, IsNil)
501	c.Assert(str, Equals, objectValue)
502
503	// Delete object
504	err = s.bucket.DeleteObject(objectName)
505	c.Assert(err, IsNil)
506}
507
508func (s *OssBucketSuite) TestSignURLWithEscapedKeyAndPorxy(c *C) {
509	// Key with '/'
510	objectName := "zyimg/86/e8/653b5dc97bb0022051a84c632bc4"
511	objectValue := "弃我去者,昨日之日不可留;乱我心者,今日之日多烦忧。长风万里送秋雁,对此可以酣高楼。蓬莱文章建安骨,中间小谢又清发。" +
512		"俱怀逸兴壮思飞,欲上青天揽明月。抽刀断水水更流,举杯销愁愁更愁。人生在世不称意,明朝散发弄扁舟。"
513
514	client, err := New(endpoint, accessID, accessKey, AuthProxy(proxyHost, proxyUser, proxyPasswd))
515	bucket, err := client.Bucket(bucketName)
516
517	// Sign URL for put
518	str, err := bucket.SignURL(objectName, HTTPPut, 60)
519	c.Assert(err, IsNil)
520	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
521	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
522	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
523
524	// Put object with URL
525	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
526	c.Assert(err, IsNil)
527
528	// Sign URL for function GetObjectWithURL
529	str, err = bucket.SignURL(objectName, HTTPGet, 60)
530	c.Assert(err, IsNil)
531	c.Assert(strings.Contains(str, HTTPParamExpires+"="), Equals, true)
532	c.Assert(strings.Contains(str, HTTPParamAccessKeyID+"="), Equals, true)
533	c.Assert(strings.Contains(str, HTTPParamSignature+"="), Equals, true)
534
535	// Get object with URL
536	body, err := bucket.GetObjectWithURL(str)
537	c.Assert(err, IsNil)
538	str, err = readBody(body)
539	c.Assert(err, IsNil)
540	c.Assert(str, Equals, objectValue)
541
542	// Key with Chinese chars
543	objectName = "test/此情无计可消除/才下眉头/却上 心头/。,;:‘’“”?()『』【】《》!@#¥%……&×/test+ =-_*&^%$#@!`~[]{}()<>|\\/?.,;.txt"
544
545	// Sign URL for function PutObjectWithURL
546	str, err = bucket.SignURL(objectName, HTTPPut, 60)
547	c.Assert(err, IsNil)
548
549	// Put object with URL
550	err = bucket.PutObjectWithURL(str, strings.NewReader(objectValue))
551	c.Assert(err, IsNil)
552
553	// Sign URL for function GetObjectWithURL
554	str, err = bucket.SignURL(objectName, HTTPGet, 60)
555	c.Assert(err, IsNil)
556
557	// Get object with URL
558	body, err = bucket.GetObjectWithURL(str)
559	c.Assert(err, IsNil)
560	str, err = readBody(body)
561	c.Assert(err, IsNil)
562	c.Assert(str, Equals, objectValue)
563
564	// Put object
565	err = bucket.PutObject(objectName, bytes.NewReader([]byte(objectValue)))
566	c.Assert(err, IsNil)
567
568	// Get object
569	body, err = bucket.GetObject(objectName)
570	c.Assert(err, IsNil)
571	str, err = readBody(body)
572	c.Assert(err, IsNil)
573	c.Assert(str, Equals, objectValue)
574
575	// Delete object
576	err = bucket.DeleteObject(objectName)
577	c.Assert(err, IsNil)
578}
579
580// TestPutObjectType
581func (s *OssBucketSuite) TestPutObjectType(c *C) {
582	objectName := objectNamePrefix + "tptt"
583	objectValue := "乱石穿空,惊涛拍岸,卷起千堆雪。 江山如画,一时多少豪杰。"
584
585	// Put
586	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
587	c.Assert(err, IsNil)
588
589	// Check
590	time.Sleep(time.Second)
591	body, err := s.bucket.GetObject(objectName)
592	c.Assert(err, IsNil)
593	str, err := readBody(body)
594	c.Assert(err, IsNil)
595	c.Assert(str, Equals, objectValue)
596
597	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
598	c.Assert(err, IsNil)
599	c.Assert(meta.Get("Content-Type"), Equals, "application/octet-stream")
600
601	err = s.bucket.DeleteObject(objectName)
602	c.Assert(err, IsNil)
603
604	// Put
605	err = s.bucket.PutObject(objectName+".txt", strings.NewReader(objectValue))
606	c.Assert(err, IsNil)
607
608	meta, err = s.bucket.GetObjectDetailedMeta(objectName + ".txt")
609	c.Assert(err, IsNil)
610	c.Assert(meta.Get("Content-Type"), Equals, "text/plain; charset=utf-8")
611
612	err = s.bucket.DeleteObject(objectName + ".txt")
613	c.Assert(err, IsNil)
614
615	// Put
616	err = s.bucket.PutObject(objectName+".apk", strings.NewReader(objectValue))
617	c.Assert(err, IsNil)
618
619	meta, err = s.bucket.GetObjectDetailedMeta(objectName + ".apk")
620	c.Assert(err, IsNil)
621	c.Assert(meta.Get("Content-Type"), Equals, "application/vnd.android.package-archive")
622
623	err = s.bucket.DeleteObject(objectName + ".txt")
624	c.Assert(err, IsNil)
625}
626
627// TestPutObject
628func (s *OssBucketSuite) TestPutObjectKeyChars(c *C) {
629	objectName := objectNamePrefix + "tpokc"
630	objectValue := "白日依山尽,黄河入海流。欲穷千里目,更上一层楼。"
631
632	// Put
633	objectKey := objectName + "十步杀一人,千里不留行。事了拂衣去,深藏身与名"
634	err := s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
635	c.Assert(err, IsNil)
636
637	// Check
638	body, err := s.bucket.GetObject(objectKey)
639	c.Assert(err, IsNil)
640	str, err := readBody(body)
641	c.Assert(err, IsNil)
642	c.Assert(str, Equals, objectValue)
643
644	err = s.bucket.DeleteObject(objectKey)
645	c.Assert(err, IsNil)
646
647	// Put
648	objectKey = objectName + "ごきげん如何ですかおれの顔をよく拝んでおけ"
649	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
650	c.Assert(err, IsNil)
651
652	// Check
653	body, err = s.bucket.GetObject(objectKey)
654	c.Assert(err, IsNil)
655	str, err = readBody(body)
656	c.Assert(err, IsNil)
657	c.Assert(str, Equals, objectValue)
658
659	err = s.bucket.DeleteObject(objectKey)
660	c.Assert(err, IsNil)
661
662	// Put
663	objectKey = objectName + "~!@#$%^&*()_-+=|\\[]{}<>,./?"
664	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
665	c.Assert(err, IsNil)
666
667	// Check
668	body, err = s.bucket.GetObject(objectKey)
669	c.Assert(err, IsNil)
670	str, err = readBody(body)
671	c.Assert(err, IsNil)
672	c.Assert(str, Equals, objectValue)
673
674	err = s.bucket.DeleteObject(objectKey)
675	c.Assert(err, IsNil)
676
677	// Put
678	objectKey = "go/中国 日本 +-#&=*"
679	err = s.bucket.PutObject(objectKey, strings.NewReader(objectValue))
680	c.Assert(err, IsNil)
681
682	// Check
683	body, err = s.bucket.GetObject(objectKey)
684	c.Assert(err, IsNil)
685	str, err = readBody(body)
686	c.Assert(err, IsNil)
687	c.Assert(str, Equals, objectValue)
688
689	err = s.bucket.DeleteObject(objectKey)
690	c.Assert(err, IsNil)
691}
692
693// TestPutObjectNegative
694func (s *OssBucketSuite) TestPutObjectNegative(c *C) {
695	objectName := objectNamePrefix + "tpon"
696	objectValue := "大江东去,浪淘尽,千古风流人物。 "
697
698	// Put
699	objectName = objectNamePrefix + "tpox"
700	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue),
701		Meta("meta-my", "myprop"))
702	c.Assert(err, IsNil)
703
704	// Check meta
705	body, err := s.bucket.GetObject(objectName)
706	c.Assert(err, IsNil)
707	str, err := readBody(body)
708	c.Assert(err, IsNil)
709	c.Assert(str, Equals, objectValue)
710
711	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
712	c.Assert(err, IsNil)
713	c.Assert(meta.Get("X-Oss-Meta-My"), Not(Equals), "myprop")
714	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "")
715
716	err = s.bucket.DeleteObject(objectName)
717	c.Assert(err, IsNil)
718
719	// Invalid option
720	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue),
721		IfModifiedSince(pastDate))
722	c.Assert(err, NotNil)
723
724	err = s.bucket.PutObjectFromFile(objectName, "bucket.go", IfModifiedSince(pastDate))
725	c.Assert(err, NotNil)
726
727	err = s.bucket.PutObjectFromFile(objectName, "/tmp/xxx")
728	c.Assert(err, NotNil)
729}
730
731// TestPutObjectFromFile
732func (s *OssBucketSuite) TestPutObjectFromFile(c *C) {
733	objectName := objectNamePrefix + "tpoff"
734	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
735	newFile := "newpic11.jpg"
736
737	// Put
738	err := s.bucket.PutObjectFromFile(objectName, localFile)
739	c.Assert(err, IsNil)
740
741	// Check
742	err = s.bucket.GetObjectToFile(objectName, newFile)
743	c.Assert(err, IsNil)
744	eq, err := compareFiles(localFile, newFile)
745	c.Assert(err, IsNil)
746	c.Assert(eq, Equals, true)
747
748	acl, err := s.bucket.GetObjectACL(objectName)
749	c.Assert(err, IsNil)
750	testLogger.Println("aclRes:", acl)
751	c.Assert(acl.ACL, Equals, "default")
752
753	err = s.bucket.DeleteObject(objectName)
754	c.Assert(err, IsNil)
755
756	// Put with properties
757	options := []Option{
758		Expires(futureDate),
759		ObjectACL(ACLPublicRead),
760		Meta("myprop", "mypropval"),
761	}
762	os.Remove(newFile)
763	err = s.bucket.PutObjectFromFile(objectName, localFile, options...)
764	c.Assert(err, IsNil)
765
766	// Check
767	err = s.bucket.GetObjectToFile(objectName, newFile)
768	c.Assert(err, IsNil)
769	eq, err = compareFiles(localFile, newFile)
770	c.Assert(err, IsNil)
771	c.Assert(eq, Equals, true)
772
773	acl, err = s.bucket.GetObjectACL(objectName)
774	c.Assert(err, IsNil)
775	testLogger.Println("GetObjectACL:", acl)
776	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
777
778	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
779	c.Assert(err, IsNil)
780	testLogger.Println("GetObjectDetailedMeta:", meta)
781	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
782
783	err = s.bucket.DeleteObject(objectName)
784	c.Assert(err, IsNil)
785	os.Remove(newFile)
786}
787
788// TestPutObjectFromFile
789func (s *OssBucketSuite) TestPutObjectFromFileType(c *C) {
790	objectName := objectNamePrefix + "tpoffwm"
791	localFile := "../sample/BingWallpaper-2015-11-07.jpg"
792	newFile := "newpic11.jpg"
793
794	// Put
795	err := s.bucket.PutObjectFromFile(objectName, localFile)
796	c.Assert(err, IsNil)
797
798	// Check
799	err = s.bucket.GetObjectToFile(objectName, newFile)
800	c.Assert(err, IsNil)
801	eq, err := compareFiles(localFile, newFile)
802	c.Assert(err, IsNil)
803	c.Assert(eq, Equals, true)
804
805	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
806	c.Assert(err, IsNil)
807	c.Assert(meta.Get("Content-Type"), Equals, "image/jpeg")
808
809	err = s.bucket.DeleteObject(objectName)
810	c.Assert(err, IsNil)
811	os.Remove(newFile)
812}
813
814// TestGetObject
815func (s *OssBucketSuite) TestGetObject(c *C) {
816	objectName := objectNamePrefix + "tgo"
817	objectValue := "长忆观潮,满郭人争江上望。来疑沧海尽成空,万面鼓声中。弄潮儿向涛头立,手把红旗旗不湿。别来几向梦中看,梦觉尚心寒。"
818
819	// Put
820	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
821	c.Assert(err, IsNil)
822
823	// Check
824	body, err := s.bucket.GetObject(objectName)
825	c.Assert(err, IsNil)
826	data, err := ioutil.ReadAll(body)
827	body.Close()
828	str := string(data)
829	c.Assert(str, Equals, objectValue)
830	testLogger.Println("GetObjec:", str)
831
832	// Range
833	var subObjectValue = string(([]byte(objectValue))[15:36])
834	body, err = s.bucket.GetObject(objectName, Range(15, 35))
835	c.Assert(err, IsNil)
836	data, err = ioutil.ReadAll(body)
837	body.Close()
838	str = string(data)
839	c.Assert(str, Equals, subObjectValue)
840	testLogger.Println("GetObject:", str, ",", subObjectValue)
841
842	// If-Modified-Since
843	_, err = s.bucket.GetObject(objectName, IfModifiedSince(futureDate))
844	c.Assert(err, NotNil)
845
846	// If-Unmodified-Since
847	body, err = s.bucket.GetObject(objectName, IfUnmodifiedSince(futureDate))
848	c.Assert(err, IsNil)
849	data, err = ioutil.ReadAll(body)
850	body.Close()
851	c.Assert(string(data), Equals, objectValue)
852
853	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
854	c.Assert(err, IsNil)
855
856	// If-Match
857	body, err = s.bucket.GetObject(objectName, IfMatch(meta.Get("Etag")))
858	c.Assert(err, IsNil)
859	data, err = ioutil.ReadAll(body)
860	body.Close()
861	c.Assert(string(data), Equals, objectValue)
862
863	// If-None-Match
864	_, err = s.bucket.GetObject(objectName, IfNoneMatch(meta.Get("Etag")))
865	c.Assert(err, NotNil)
866
867	// process
868	err = s.bucket.PutObjectFromFile(objectName, "../sample/BingWallpaper-2015-11-07.jpg")
869	c.Assert(err, IsNil)
870	_, err = s.bucket.GetObject(objectName, Process("image/format,png"))
871	c.Assert(err, IsNil)
872
873	err = s.bucket.DeleteObject(objectName)
874	c.Assert(err, IsNil)
875}
876
877// TestGetObjectNegative
878func (s *OssBucketSuite) TestGetObjectToWriterNegative(c *C) {
879	objectName := objectNamePrefix + "tgotwn"
880	objectValue := "长忆观潮,满郭人争江上望。"
881
882	// Object not exist
883	_, err := s.bucket.GetObject("NotExist")
884	c.Assert(err, NotNil)
885
886	// Constraint invalid
887	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
888	c.Assert(err, IsNil)
889
890	// Out of range
891	_, err = s.bucket.GetObject(objectName, Range(15, 1000))
892	c.Assert(err, IsNil)
893
894	// Not exist
895	err = s.bucket.GetObjectToFile(objectName, "/root/123abc9874")
896	c.Assert(err, NotNil)
897
898	// Invalid option
899	_, err = s.bucket.GetObject(objectName, ACL(ACLPublicRead))
900	c.Assert(err, IsNil)
901
902	err = s.bucket.GetObjectToFile(objectName, "newpic15.jpg", ACL(ACLPublicRead))
903	c.Assert(err, IsNil)
904
905	err = s.bucket.DeleteObject(objectName)
906	c.Assert(err, IsNil)
907}
908
909// TestGetObjectToFile
910func (s *OssBucketSuite) TestGetObjectToFile(c *C) {
911	objectName := objectNamePrefix + "tgotf"
912	objectValue := "江南好,风景旧曾谙;日出江花红胜火,春来江水绿如蓝。能不忆江南?江南忆,最忆是杭州;山寺月中寻桂子,郡亭枕上看潮头。何日更重游!"
913	newFile := "newpic15.jpg"
914
915	// Put
916	var val = []byte(objectValue)
917	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue))
918	c.Assert(err, IsNil)
919
920	// Check
921	err = s.bucket.GetObjectToFile(objectName, newFile)
922	c.Assert(err, IsNil)
923	eq, err := compareFileData(newFile, val)
924	c.Assert(err, IsNil)
925	c.Assert(eq, Equals, true)
926	os.Remove(newFile)
927
928	// Range
929	err = s.bucket.GetObjectToFile(objectName, newFile, Range(15, 35))
930	c.Assert(err, IsNil)
931	eq, err = compareFileData(newFile, val[15:36])
932	c.Assert(err, IsNil)
933	c.Assert(eq, Equals, true)
934	os.Remove(newFile)
935
936	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("15-35"))
937	c.Assert(err, IsNil)
938	eq, err = compareFileData(newFile, val[15:36])
939	c.Assert(err, IsNil)
940	c.Assert(eq, Equals, true)
941	os.Remove(newFile)
942
943	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("15-"))
944	c.Assert(err, IsNil)
945	eq, err = compareFileData(newFile, val[15:])
946	c.Assert(err, IsNil)
947	c.Assert(eq, Equals, true)
948	os.Remove(newFile)
949
950	err = s.bucket.GetObjectToFile(objectName, newFile, NormalizedRange("-10"))
951	c.Assert(err, IsNil)
952	eq, err = compareFileData(newFile, val[(len(val)-10):len(val)])
953	c.Assert(err, IsNil)
954	c.Assert(eq, Equals, true)
955	os.Remove(newFile)
956
957	// If-Modified-Since
958	err = s.bucket.GetObjectToFile(objectName, newFile, IfModifiedSince(futureDate))
959	c.Assert(err, NotNil)
960
961	// If-Unmodified-Since
962	err = s.bucket.GetObjectToFile(objectName, newFile, IfUnmodifiedSince(futureDate))
963	c.Assert(err, IsNil)
964	eq, err = compareFileData(newFile, val)
965	c.Assert(err, IsNil)
966	c.Assert(eq, Equals, true)
967	os.Remove(newFile)
968
969	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
970	c.Assert(err, IsNil)
971	testLogger.Println("GetObjectDetailedMeta:", meta)
972
973	// If-Match
974	err = s.bucket.GetObjectToFile(objectName, newFile, IfMatch(meta.Get("Etag")))
975	c.Assert(err, IsNil)
976	eq, err = compareFileData(newFile, val)
977	c.Assert(err, IsNil)
978	c.Assert(eq, Equals, true)
979
980	// If-None-Match
981	err = s.bucket.GetObjectToFile(objectName, newFile, IfNoneMatch(meta.Get("Etag")))
982	c.Assert(err, NotNil)
983
984	// Accept-Encoding:gzip
985	err = s.bucket.PutObjectFromFile(objectName, "../sample/The Go Programming Language.html")
986	c.Assert(err, IsNil)
987	err = s.bucket.GetObjectToFile(objectName, newFile, AcceptEncoding("gzip"))
988	c.Assert(err, IsNil)
989
990	os.Remove(newFile)
991	err = s.bucket.DeleteObject(objectName)
992	c.Assert(err, IsNil)
993}
994
995// TestListObjects
996func (s *OssBucketSuite) TestListObjects(c *C) {
997	objectName := objectNamePrefix + "tlo"
998
999	// List empty bucket
1000	lor, err := s.bucket.ListObjects()
1001	c.Assert(err, IsNil)
1002	left := len(lor.Objects)
1003
1004	// Put three objects
1005	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
1006	c.Assert(err, IsNil)
1007	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
1008	c.Assert(err, IsNil)
1009	err = s.bucket.PutObject(objectName+"3", strings.NewReader(""))
1010	c.Assert(err, IsNil)
1011
1012	// List
1013	lor, err = s.bucket.ListObjects()
1014	c.Assert(err, IsNil)
1015	c.Assert(len(lor.Objects), Equals, left+3)
1016
1017	// List with prefix
1018	lor, err = s.bucket.ListObjects(Prefix(objectName + "2"))
1019	c.Assert(err, IsNil)
1020	c.Assert(len(lor.Objects), Equals, 1)
1021
1022	lor, err = s.bucket.ListObjects(Prefix(objectName + "22"))
1023	c.Assert(err, IsNil)
1024	c.Assert(len(lor.Objects), Equals, 0)
1025
1026	// List with max keys
1027	lor, err = s.bucket.ListObjects(Prefix(objectName), MaxKeys(2))
1028	c.Assert(err, IsNil)
1029	c.Assert(len(lor.Objects), Equals, 2)
1030
1031	// List with marker
1032	lor, err = s.bucket.ListObjects(Marker(objectName+"1"), MaxKeys(1))
1033	c.Assert(err, IsNil)
1034	c.Assert(len(lor.Objects), Equals, 1)
1035
1036	err = s.bucket.DeleteObject(objectName + "1")
1037	c.Assert(err, IsNil)
1038	err = s.bucket.DeleteObject(objectName + "2")
1039	c.Assert(err, IsNil)
1040	err = s.bucket.DeleteObject(objectName + "3")
1041	c.Assert(err, IsNil)
1042}
1043
1044// TestListObjects
1045func (s *OssBucketSuite) TestListObjectsEncodingType(c *C) {
1046	objectName := objectNamePrefix + "床前明月光,疑是地上霜。举头望明月,低头思故乡。" + "tloet"
1047
1048	for i := 0; i < 10; i++ {
1049		err := s.bucket.PutObject(objectName+strconv.Itoa(i), strings.NewReader(""))
1050		c.Assert(err, IsNil)
1051	}
1052
1053	lor, err := s.bucket.ListObjects(Prefix(objectNamePrefix + "床前明月光,"))
1054	c.Assert(err, IsNil)
1055	c.Assert(len(lor.Objects), Equals, 10)
1056
1057	lor, err = s.bucket.ListObjects(Prefix(objectNamePrefix + "床前明月光,"))
1058	c.Assert(err, IsNil)
1059	c.Assert(len(lor.Objects), Equals, 10)
1060
1061	lor, err = s.bucket.ListObjects(Marker(objectNamePrefix + "床前明月光,疑是地上霜。举头望明月,低头思故乡。"))
1062	c.Assert(err, IsNil)
1063	c.Assert(len(lor.Objects), Equals, 10)
1064
1065	lor, err = s.bucket.ListObjects(Prefix(objectNamePrefix + "床前明月光"))
1066	c.Assert(err, IsNil)
1067	for i, obj := range lor.Objects {
1068		c.Assert(obj.Key, Equals, objectNamePrefix+"床前明月光,疑是地上霜。举头望明月,低头思故乡。tloet"+strconv.Itoa(i))
1069	}
1070
1071	for i := 0; i < 10; i++ {
1072		err = s.bucket.DeleteObject(objectName + strconv.Itoa(i))
1073		c.Assert(err, IsNil)
1074	}
1075
1076	// Special characters
1077	objectName = "go go ` ~ ! @ # $ % ^ & * () - _ + =[] {} \\ | < > , . ? / 0"
1078	err = s.bucket.PutObject(objectName, strings.NewReader("明月几时有,把酒问青天"))
1079	c.Assert(err, IsNil)
1080
1081	lor, err = s.bucket.ListObjects(Prefix(objectName))
1082	c.Assert(err, IsNil)
1083	c.Assert(len(lor.Objects), Equals, 1)
1084
1085	err = s.bucket.DeleteObject(objectName)
1086	c.Assert(err, IsNil)
1087
1088	objectName = "go/中国  日本  +-#&=*"
1089	err = s.bucket.PutObject(objectName, strings.NewReader("明月几时有,把酒问青天"))
1090	c.Assert(err, IsNil)
1091
1092	lor, err = s.bucket.ListObjects(Prefix(objectName))
1093	c.Assert(err, IsNil)
1094	c.Assert(len(lor.Objects), Equals, 1)
1095
1096	err = s.bucket.DeleteObject(objectName)
1097	c.Assert(err, IsNil)
1098}
1099
1100// TestIsBucketExist
1101func (s *OssBucketSuite) TestIsObjectExist(c *C) {
1102	objectName := objectNamePrefix + "tibe"
1103
1104	// Put three objects
1105	err := s.bucket.PutObject(objectName+"1", strings.NewReader(""))
1106	c.Assert(err, IsNil)
1107	err = s.bucket.PutObject(objectName+"11", strings.NewReader(""))
1108	c.Assert(err, IsNil)
1109	err = s.bucket.PutObject(objectName+"111", strings.NewReader(""))
1110	c.Assert(err, IsNil)
1111
1112	// Exist
1113	exist, err := s.bucket.IsObjectExist(objectName + "11")
1114	c.Assert(err, IsNil)
1115	c.Assert(exist, Equals, true)
1116
1117	exist, err = s.bucket.IsObjectExist(objectName + "1")
1118	c.Assert(err, IsNil)
1119	c.Assert(exist, Equals, true)
1120
1121	exist, err = s.bucket.IsObjectExist(objectName + "111")
1122	c.Assert(err, IsNil)
1123	c.Assert(exist, Equals, true)
1124
1125	// Not exist
1126	exist, err = s.bucket.IsObjectExist(objectName + "1111")
1127	c.Assert(err, IsNil)
1128	c.Assert(exist, Equals, false)
1129
1130	exist, err = s.bucket.IsObjectExist(objectName)
1131	c.Assert(err, IsNil)
1132	c.Assert(exist, Equals, false)
1133
1134	err = s.bucket.DeleteObject(objectName + "1")
1135	c.Assert(err, IsNil)
1136	err = s.bucket.DeleteObject(objectName + "11")
1137	c.Assert(err, IsNil)
1138	err = s.bucket.DeleteObject(objectName + "111")
1139	c.Assert(err, IsNil)
1140}
1141
1142// TestDeleteObject
1143func (s *OssBucketSuite) TestDeleteObject(c *C) {
1144	objectName := objectNamePrefix + "tdo"
1145
1146	err := s.bucket.PutObject(objectName, strings.NewReader(""))
1147	c.Assert(err, IsNil)
1148
1149	lor, err := s.bucket.ListObjects(Prefix(objectName))
1150	c.Assert(err, IsNil)
1151	c.Assert(len(lor.Objects), Equals, 1)
1152
1153	// Delete
1154	err = s.bucket.DeleteObject(objectName)
1155	c.Assert(err, IsNil)
1156
1157	// Duplicate delete
1158	err = s.bucket.DeleteObject(objectName)
1159	c.Assert(err, IsNil)
1160
1161	lor, err = s.bucket.ListObjects(Prefix(objectName))
1162	c.Assert(err, IsNil)
1163	c.Assert(len(lor.Objects), Equals, 0)
1164}
1165
1166// TestDeleteObjects
1167func (s *OssBucketSuite) TestDeleteObjects(c *C) {
1168	objectName := objectNamePrefix + "tdos"
1169
1170	// Delete objects
1171	err := s.bucket.PutObject(objectName, strings.NewReader(""))
1172	c.Assert(err, IsNil)
1173
1174	res, err := s.bucket.DeleteObjects([]string{objectName})
1175	c.Assert(err, IsNil)
1176	c.Assert(len(res.DeletedObjects), Equals, 1)
1177
1178	lor, err := s.bucket.ListObjects(Prefix(objectName))
1179	c.Assert(err, IsNil)
1180	c.Assert(len(lor.Objects), Equals, 0)
1181
1182	// Delete objects
1183	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
1184	c.Assert(err, IsNil)
1185
1186	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
1187	c.Assert(err, IsNil)
1188
1189	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"})
1190	c.Assert(err, IsNil)
1191	c.Assert(len(res.DeletedObjects), Equals, 2)
1192
1193	lor, err = s.bucket.ListObjects(Prefix(objectName))
1194	c.Assert(err, IsNil)
1195	c.Assert(len(lor.Objects), Equals, 0)
1196
1197	// Delete 0
1198	_, err = s.bucket.DeleteObjects([]string{})
1199	c.Assert(err, NotNil)
1200
1201	// DeleteObjectsQuiet
1202	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
1203	c.Assert(err, IsNil)
1204
1205	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
1206	c.Assert(err, IsNil)
1207
1208	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"},
1209		DeleteObjectsQuiet(false))
1210	c.Assert(err, IsNil)
1211	c.Assert(len(res.DeletedObjects), Equals, 2)
1212
1213	lor, err = s.bucket.ListObjects(Prefix(objectName))
1214	c.Assert(err, IsNil)
1215	c.Assert(len(lor.Objects), Equals, 0)
1216
1217	// DeleteObjectsQuiet
1218	err = s.bucket.PutObject(objectName+"1", strings.NewReader(""))
1219	c.Assert(err, IsNil)
1220
1221	err = s.bucket.PutObject(objectName+"2", strings.NewReader(""))
1222	c.Assert(err, IsNil)
1223
1224	res, err = s.bucket.DeleteObjects([]string{objectName + "1", objectName + "2"},
1225		DeleteObjectsQuiet(true))
1226	c.Assert(err, IsNil)
1227	c.Assert(len(res.DeletedObjects), Equals, 0)
1228
1229	lor, err = s.bucket.ListObjects(Prefix(objectName))
1230	c.Assert(err, IsNil)
1231	c.Assert(len(lor.Objects), Equals, 0)
1232
1233	// EncodingType
1234	err = s.bucket.PutObject("中国人", strings.NewReader(""))
1235	c.Assert(err, IsNil)
1236
1237	res, err = s.bucket.DeleteObjects([]string{"中国人"})
1238	c.Assert(err, IsNil)
1239	c.Assert(len(res.DeletedObjects), Equals, 1)
1240	c.Assert(res.DeletedObjects[0], Equals, "中国人")
1241
1242	// EncodingType
1243	err = s.bucket.PutObject("中国人", strings.NewReader(""))
1244	c.Assert(err, IsNil)
1245
1246	res, err = s.bucket.DeleteObjects([]string{"中国人"}, DeleteObjectsQuiet(false))
1247	c.Assert(err, IsNil)
1248	c.Assert(len(res.DeletedObjects), Equals, 1)
1249	c.Assert(res.DeletedObjects[0], Equals, "中国人")
1250
1251	// EncodingType
1252	err = s.bucket.PutObject("中国人", strings.NewReader(""))
1253	c.Assert(err, IsNil)
1254
1255	res, err = s.bucket.DeleteObjects([]string{"中国人"}, DeleteObjectsQuiet(true))
1256	c.Assert(err, IsNil)
1257	c.Assert(len(res.DeletedObjects), Equals, 0)
1258
1259	// Special characters
1260	key := "A ' < > \" & ~ ` ! @ # $ % ^ & * ( ) [] {} - _ + = / | \\ ? . , : ; A"
1261	err = s.bucket.PutObject(key, strings.NewReader("value"))
1262	c.Assert(err, IsNil)
1263
1264	_, err = s.bucket.DeleteObjects([]string{key})
1265	c.Assert(err, IsNil)
1266
1267	ress, err := s.bucket.ListObjects(Prefix(key))
1268	c.Assert(err, IsNil)
1269	c.Assert(len(ress.Objects), Equals, 0)
1270
1271	// Not exist
1272	_, err = s.bucket.DeleteObjects([]string{"NotExistObject"})
1273	c.Assert(err, IsNil)
1274}
1275
1276// TestSetObjectMeta
1277func (s *OssBucketSuite) TestSetObjectMeta(c *C) {
1278	objectName := objectNamePrefix + "tsom"
1279
1280	err := s.bucket.PutObject(objectName, strings.NewReader(""))
1281	c.Assert(err, IsNil)
1282
1283	err = s.bucket.SetObjectMeta(objectName,
1284		Expires(futureDate),
1285		Meta("myprop", "mypropval"))
1286	c.Assert(err, IsNil)
1287
1288	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
1289	c.Assert(err, IsNil)
1290	testLogger.Println("Meta:", meta)
1291	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
1292	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
1293
1294	acl, err := s.bucket.GetObjectACL(objectName)
1295	c.Assert(err, IsNil)
1296	c.Assert(acl.ACL, Equals, "default")
1297
1298	// Invalid option
1299	err = s.bucket.SetObjectMeta(objectName, AcceptEncoding("url"))
1300	c.Assert(err, IsNil)
1301
1302	// Invalid option value
1303	err = s.bucket.SetObjectMeta(objectName, ServerSideEncryption("invalid"))
1304	c.Assert(err, NotNil)
1305
1306	err = s.bucket.DeleteObject(objectName)
1307	c.Assert(err, IsNil)
1308
1309	// Not exist
1310	err = s.bucket.SetObjectMeta(objectName, Expires(futureDate))
1311	c.Assert(err, NotNil)
1312}
1313
1314// TestGetObjectMeta
1315func (s *OssBucketSuite) TestGetObjectMeta(c *C) {
1316	objectName := objectNamePrefix + "tgom"
1317
1318	// Put
1319	err := s.bucket.PutObject(objectName, strings.NewReader(""))
1320	c.Assert(err, IsNil)
1321
1322	meta, err := s.bucket.GetObjectMeta(objectName)
1323	c.Assert(err, IsNil)
1324	c.Assert(len(meta) > 0, Equals, true)
1325
1326	err = s.bucket.DeleteObject(objectName)
1327	c.Assert(err, IsNil)
1328
1329	_, err = s.bucket.GetObjectMeta("NotExistObject")
1330	c.Assert(err, NotNil)
1331}
1332
1333// TestGetObjectDetailedMeta
1334func (s *OssBucketSuite) TestGetObjectDetailedMeta(c *C) {
1335	objectName := objectNamePrefix + "tgodm"
1336
1337	// Put
1338	err := s.bucket.PutObject(objectName, strings.NewReader(""),
1339		Expires(futureDate), Meta("myprop", "mypropval"))
1340	c.Assert(err, IsNil)
1341
1342	// Check
1343	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
1344	c.Assert(err, IsNil)
1345	testLogger.Println("GetObjectDetailedMeta:", meta)
1346	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
1347	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
1348	c.Assert(meta.Get("Content-Length"), Equals, "0")
1349	c.Assert(len(meta.Get("Date")) > 0, Equals, true)
1350	c.Assert(len(meta.Get("X-Oss-Request-Id")) > 0, Equals, true)
1351	c.Assert(len(meta.Get("Last-Modified")) > 0, Equals, true)
1352
1353	// IfModifiedSince/IfModifiedSince
1354	_, err = s.bucket.GetObjectDetailedMeta(objectName, IfModifiedSince(futureDate))
1355	c.Assert(err, NotNil)
1356
1357	meta, err = s.bucket.GetObjectDetailedMeta(objectName, IfUnmodifiedSince(futureDate))
1358	c.Assert(err, IsNil)
1359	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
1360	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
1361
1362	// IfMatch/IfNoneMatch
1363	_, err = s.bucket.GetObjectDetailedMeta(objectName, IfNoneMatch(meta.Get("Etag")))
1364	c.Assert(err, NotNil)
1365
1366	meta, err = s.bucket.GetObjectDetailedMeta(objectName, IfMatch(meta.Get("Etag")))
1367	c.Assert(err, IsNil)
1368	c.Assert(meta.Get("Expires"), Equals, futureDate.Format(http.TimeFormat))
1369	c.Assert(meta.Get("X-Oss-Meta-Myprop"), Equals, "mypropval")
1370
1371	err = s.bucket.DeleteObject(objectName)
1372	c.Assert(err, IsNil)
1373
1374	_, err = s.bucket.GetObjectDetailedMeta("NotExistObject")
1375	c.Assert(err, NotNil)
1376}
1377
1378// TestSetAndGetObjectAcl
1379func (s *OssBucketSuite) TestSetAndGetObjectAcl(c *C) {
1380	objectName := objectNamePrefix + "tsgba"
1381
1382	err := s.bucket.PutObject(objectName, strings.NewReader(""))
1383	c.Assert(err, IsNil)
1384
1385	// Default
1386	acl, err := s.bucket.GetObjectACL(objectName)
1387	c.Assert(err, IsNil)
1388	c.Assert(acl.ACL, Equals, "default")
1389
1390	// Set ACL_PUBLIC_RW
1391	err = s.bucket.SetObjectACL(objectName, ACLPublicReadWrite)
1392	c.Assert(err, IsNil)
1393
1394	acl, err = s.bucket.GetObjectACL(objectName)
1395	c.Assert(err, IsNil)
1396	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
1397
1398	// Set ACL_PRIVATE
1399	err = s.bucket.SetObjectACL(objectName, ACLPrivate)
1400	c.Assert(err, IsNil)
1401
1402	acl, err = s.bucket.GetObjectACL(objectName)
1403	c.Assert(err, IsNil)
1404	c.Assert(acl.ACL, Equals, string(ACLPrivate))
1405
1406	// Set ACL_PUBLIC_R
1407	err = s.bucket.SetObjectACL(objectName, ACLPublicRead)
1408	c.Assert(err, IsNil)
1409
1410	acl, err = s.bucket.GetObjectACL(objectName)
1411	c.Assert(err, IsNil)
1412	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
1413
1414	err = s.bucket.DeleteObject(objectName)
1415	c.Assert(err, IsNil)
1416}
1417
1418// TestSetAndGetObjectAclNegative
1419func (s *OssBucketSuite) TestSetAndGetObjectAclNegative(c *C) {
1420	objectName := objectNamePrefix + "tsgban"
1421
1422	// Object not exist
1423	err := s.bucket.SetObjectACL(objectName, ACLPublicRead)
1424	c.Assert(err, NotNil)
1425}
1426
1427// TestCopyObject
1428func (s *OssBucketSuite) TestCopyObject(c *C) {
1429	objectName := objectNamePrefix + "tco"
1430	objectValue := "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯?"
1431
1432	err := s.bucket.PutObject(objectName, strings.NewReader(objectValue),
1433		ACL(ACLPublicRead), Meta("my", "myprop"))
1434	c.Assert(err, IsNil)
1435
1436	// Copy
1437	var objectNameDest = objectName + "dest"
1438	_, err = s.bucket.CopyObject(objectName, objectNameDest)
1439	c.Assert(err, IsNil)
1440
1441	// Check
1442	lor, err := s.bucket.ListObjects(Prefix(objectName))
1443	c.Assert(err, IsNil)
1444	testLogger.Println("objects:", lor.Objects)
1445	c.Assert(len(lor.Objects), Equals, 2)
1446
1447	body, err := s.bucket.GetObject(objectName)
1448	c.Assert(err, IsNil)
1449	str, err := readBody(body)
1450	c.Assert(err, IsNil)
1451	c.Assert(str, Equals, objectValue)
1452
1453	err = s.bucket.DeleteObject(objectNameDest)
1454	c.Assert(err, IsNil)
1455
1456	// Copy with constraints x-oss-copy-source-if-modified-since
1457	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfModifiedSince(futureDate))
1458	c.Assert(err, NotNil)
1459	testLogger.Println("CopyObject:", err)
1460
1461	// Copy with constraints x-oss-copy-source-if-unmodified-since
1462	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfUnmodifiedSince(futureDate))
1463	c.Assert(err, IsNil)
1464
1465	// Check
1466	lor, err = s.bucket.ListObjects(Prefix(objectName))
1467	c.Assert(err, IsNil)
1468	testLogger.Println("objects:", lor.Objects)
1469	c.Assert(len(lor.Objects), Equals, 2)
1470
1471	body, err = s.bucket.GetObject(objectName)
1472	c.Assert(err, IsNil)
1473	str, err = readBody(body)
1474	c.Assert(err, IsNil)
1475	c.Assert(str, Equals, objectValue)
1476
1477	err = s.bucket.DeleteObject(objectNameDest)
1478	c.Assert(err, IsNil)
1479
1480	// Copy with constraints x-oss-copy-source-if-match
1481	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
1482	c.Assert(err, IsNil)
1483	testLogger.Println("GetObjectDetailedMeta:", meta)
1484
1485	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfMatch(meta.Get("Etag")))
1486	c.Assert(err, IsNil)
1487
1488	// Check
1489	body, err = s.bucket.GetObject(objectName)
1490	c.Assert(err, IsNil)
1491	str, err = readBody(body)
1492	c.Assert(err, IsNil)
1493	c.Assert(str, Equals, objectValue)
1494
1495	err = s.bucket.DeleteObject(objectNameDest)
1496	c.Assert(err, IsNil)
1497
1498	// Copy with constraints x-oss-copy-source-if-none-match
1499	_, err = s.bucket.CopyObject(objectName, objectNameDest, CopySourceIfNoneMatch(meta.Get("Etag")))
1500	c.Assert(err, NotNil)
1501
1502	// Copy with constraints x-oss-metadata-directive
1503	_, err = s.bucket.CopyObject(objectName, objectNameDest, Meta("my", "mydestprop"),
1504		MetadataDirective(MetaCopy))
1505	c.Assert(err, IsNil)
1506
1507	// Check
1508	body, err = s.bucket.GetObject(objectName)
1509	c.Assert(err, IsNil)
1510	str, err = readBody(body)
1511	c.Assert(err, IsNil)
1512	c.Assert(str, Equals, objectValue)
1513
1514	destMeta, err := s.bucket.GetObjectDetailedMeta(objectNameDest)
1515	c.Assert(err, IsNil)
1516	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
1517
1518	acl, err := s.bucket.GetObjectACL(objectNameDest)
1519	c.Assert(err, IsNil)
1520	c.Assert(acl.ACL, Equals, "default")
1521
1522	err = s.bucket.DeleteObject(objectNameDest)
1523	c.Assert(err, IsNil)
1524
1525	// Copy with constraints x-oss-metadata-directive and self defined dest object meta
1526	options := []Option{
1527		ObjectACL(ACLPublicReadWrite),
1528		Meta("my", "mydestprop"),
1529		MetadataDirective(MetaReplace),
1530	}
1531	_, err = s.bucket.CopyObject(objectName, objectNameDest, options...)
1532	c.Assert(err, IsNil)
1533
1534	// Check
1535	body, err = s.bucket.GetObject(objectName)
1536	c.Assert(err, IsNil)
1537	str, err = readBody(body)
1538	c.Assert(err, IsNil)
1539	c.Assert(str, Equals, objectValue)
1540
1541	destMeta, err = s.bucket.GetObjectDetailedMeta(objectNameDest)
1542	c.Assert(err, IsNil)
1543	c.Assert(destMeta.Get("X-Oss-Meta-My"), Equals, "mydestprop")
1544
1545	acl, err = s.bucket.GetObjectACL(objectNameDest)
1546	c.Assert(err, IsNil)
1547	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
1548
1549	err = s.bucket.DeleteObject(objectNameDest)
1550	c.Assert(err, IsNil)
1551
1552	err = s.bucket.DeleteObject(objectName)
1553	c.Assert(err, IsNil)
1554}
1555
1556// TestCopyObjectToOrFrom
1557func (s *OssBucketSuite) TestCopyObjectToOrFrom(c *C) {
1558	objectName := objectNamePrefix + "tcotof" + randLowStr(5)
1559	objectValue := "男儿何不带吴钩,收取关山五十州。请君暂上凌烟阁,若个书生万户侯?"
1560	destBucketName := bucketName + "-dest" + randLowStr(5)
1561	objectNameDest := objectName + "dest"
1562
1563	err := s.client.CreateBucket(destBucketName)
1564	c.Assert(err, IsNil)
1565
1566	destBucket, err := s.client.Bucket(destBucketName)
1567	c.Assert(err, IsNil)
1568
1569	err = s.bucket.PutObject(objectName, strings.NewReader(objectValue))
1570	c.Assert(err, IsNil)
1571
1572	// Copy from
1573	_, err = destBucket.CopyObjectFrom(bucketName, objectName, objectNameDest)
1574	c.Assert(err, IsNil)
1575
1576	// Check
1577	body, err := destBucket.GetObject(objectNameDest)
1578	c.Assert(err, IsNil)
1579	str, err := readBody(body)
1580	c.Assert(err, IsNil)
1581	c.Assert(str, Equals, objectValue)
1582
1583	err = s.bucket.DeleteObject(objectName)
1584	c.Assert(err, IsNil)
1585
1586	// Copy to
1587	_, err = destBucket.CopyObjectTo(bucketName, objectName, objectNameDest)
1588	c.Assert(err, IsNil)
1589
1590	// Check
1591	body, err = s.bucket.GetObject(objectName)
1592	c.Assert(err, IsNil)
1593	str, err = readBody(body)
1594	c.Assert(err, IsNil)
1595	c.Assert(str, Equals, objectValue)
1596
1597	// Clean
1598	err = destBucket.DeleteObject(objectNameDest)
1599	c.Assert(err, IsNil)
1600
1601	err = s.bucket.DeleteObject(objectName)
1602	c.Assert(err, IsNil)
1603
1604	err = s.client.DeleteBucket(destBucketName)
1605	c.Assert(err, IsNil)
1606}
1607
1608// TestCopyObjectToOrFromNegative
1609func (s *OssBucketSuite) TestCopyObjectToOrFromNegative(c *C) {
1610	objectName := objectNamePrefix + "tcotofn"
1611	destBucket := bucketName + "-destn"
1612	objectNameDest := objectName + "destn"
1613
1614	// Object not exist
1615	_, err := s.bucket.CopyObjectTo(bucketName, objectName, objectNameDest)
1616	c.Assert(err, NotNil)
1617
1618	// Bucket not exist
1619	_, err = s.bucket.CopyObjectFrom(destBucket, objectNameDest, objectName)
1620	c.Assert(err, NotNil)
1621}
1622
1623// TestAppendObject
1624func (s *OssBucketSuite) TestAppendObject(c *C) {
1625	objectName := objectNamePrefix + "tao"
1626	objectValue := "昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。"
1627	var val = []byte(objectValue)
1628	var localFile = "testx.txt"
1629	var nextPos int64
1630	var midPos = 1 + rand.Intn(len(val)-1)
1631
1632	var err = createFileAndWrite(localFile+"1", val[0:midPos])
1633	c.Assert(err, IsNil)
1634	err = createFileAndWrite(localFile+"2", val[midPos:])
1635	c.Assert(err, IsNil)
1636
1637	// String append
1638	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,"), nextPos)
1639	c.Assert(err, IsNil)
1640	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("却道海棠依旧。知否?知否?应是绿肥红瘦。"), nextPos)
1641	c.Assert(err, IsNil)
1642
1643	body, err := s.bucket.GetObject(objectName)
1644	c.Assert(err, IsNil)
1645	str, err := readBody(body)
1646	c.Assert(err, IsNil)
1647	c.Assert(str, Equals, objectValue)
1648
1649	err = s.bucket.DeleteObject(objectName)
1650	c.Assert(err, IsNil)
1651
1652	// Byte append
1653	nextPos = 0
1654	nextPos, err = s.bucket.AppendObject(objectName, bytes.NewReader(val[0:midPos]), nextPos)
1655	c.Assert(err, IsNil)
1656	nextPos, err = s.bucket.AppendObject(objectName, bytes.NewReader(val[midPos:]), nextPos)
1657	c.Assert(err, IsNil)
1658
1659	body, err = s.bucket.GetObject(objectName)
1660	c.Assert(err, IsNil)
1661	str, err = readBody(body)
1662	c.Assert(err, IsNil)
1663	c.Assert(str, Equals, objectValue)
1664
1665	err = s.bucket.DeleteObject(objectName)
1666	c.Assert(err, IsNil)
1667
1668	// File append
1669	options := []Option{
1670		ObjectACL(ACLPublicReadWrite),
1671		Meta("my", "myprop"),
1672	}
1673
1674	fd, err := os.Open(localFile + "1")
1675	c.Assert(err, IsNil)
1676	defer fd.Close()
1677	nextPos = 0
1678	nextPos, err = s.bucket.AppendObject(objectName, fd, nextPos, options...)
1679	c.Assert(err, IsNil)
1680
1681	meta, err := s.bucket.GetObjectDetailedMeta(objectName)
1682	c.Assert(err, IsNil)
1683	testLogger.Println("GetObjectDetailedMeta:", meta, ",", nextPos)
1684	c.Assert(meta.Get("X-Oss-Object-Type"), Equals, "Appendable")
1685	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
1686	c.Assert(meta.Get("x-oss-Meta-Mine"), Equals, "")
1687	c.Assert(meta.Get("X-Oss-Next-Append-Position"), Equals, strconv.FormatInt(nextPos, 10))
1688
1689	acl, err := s.bucket.GetObjectACL(objectName)
1690	c.Assert(err, IsNil)
1691	testLogger.Println("GetObjectACL:", acl)
1692	c.Assert(acl.ACL, Equals, string(ACLPublicReadWrite))
1693
1694	// Second append
1695	options = []Option{
1696		ObjectACL(ACLPublicRead),
1697		Meta("my", "myproptwo"),
1698		Meta("mine", "mypropmine"),
1699	}
1700	fd, err = os.Open(localFile + "2")
1701	c.Assert(err, IsNil)
1702	defer fd.Close()
1703	nextPos, err = s.bucket.AppendObject(objectName, fd, nextPos, options...)
1704	c.Assert(err, IsNil)
1705
1706	body, err = s.bucket.GetObject(objectName)
1707	c.Assert(err, IsNil)
1708	str, err = readBody(body)
1709	c.Assert(err, IsNil)
1710	c.Assert(str, Equals, objectValue)
1711
1712	meta, err = s.bucket.GetObjectDetailedMeta(objectName)
1713	c.Assert(err, IsNil)
1714	testLogger.Println("GetObjectDetailedMeta xxx:", meta)
1715	c.Assert(meta.Get("X-Oss-Object-Type"), Equals, "Appendable")
1716	c.Assert(meta.Get("X-Oss-Meta-My"), Equals, "myprop")
1717	c.Assert(meta.Get("x-Oss-Meta-Mine"), Equals, "")
1718	c.Assert(meta.Get("X-Oss-Next-Append-Position"), Equals, strconv.FormatInt(nextPos, 10))
1719
1720	acl, err = s.bucket.GetObjectACL(objectName)
1721	c.Assert(err, IsNil)
1722	c.Assert(acl.ACL, Equals, string(ACLPublicRead))
1723
1724	err = s.bucket.DeleteObject(objectName)
1725	c.Assert(err, IsNil)
1726}
1727
1728// TestAppendObjectNegative
1729func (s *OssBucketSuite) TestAppendObjectNegative(c *C) {
1730	objectName := objectNamePrefix + "taon"
1731	nextPos := int64(0)
1732
1733	nextPos, err := s.bucket.AppendObject(objectName, strings.NewReader("ObjectValue"), nextPos)
1734	c.Assert(err, IsNil)
1735
1736	nextPos, err = s.bucket.AppendObject(objectName, strings.NewReader("ObjectValue"), 0)
1737	c.Assert(err, NotNil)
1738
1739	err = s.bucket.DeleteObject(objectName)
1740	c.Assert(err, IsNil)
1741}
1742
1743// TestContentType
1744func (s *OssBucketSuite) TestAddContentType(c *C) {
1745	opts := addContentType(nil, "abc.txt")
1746	typ, err := findOption(opts, HTTPHeaderContentType, "")
1747	c.Assert(err, IsNil)
1748	c.Assert(typ, Equals, "text/plain; charset=utf-8")
1749
1750	opts = addContentType(nil)
1751	typ, err = findOption(opts, HTTPHeaderContentType, "")
1752	c.Assert(err, IsNil)
1753	c.Assert(len(opts), Equals, 1)
1754	c.Assert(typ, Equals, "application/octet-stream")
1755
1756	opts = addContentType(nil, "abc.txt", "abc.pdf")
1757	typ, err = findOption(opts, HTTPHeaderContentType, "")
1758	c.Assert(err, IsNil)
1759	c.Assert(typ, Equals, "text/plain; charset=utf-8")
1760
1761	opts = addContentType(nil, "abc", "abc.txt", "abc.pdf")
1762	typ, err = findOption(opts, HTTPHeaderContentType, "")
1763	c.Assert(err, IsNil)
1764	c.Assert(typ, Equals, "text/plain; charset=utf-8")
1765
1766	opts = addContentType(nil, "abc", "abc", "edf")
1767	typ, err = findOption(opts, HTTPHeaderContentType, "")
1768	c.Assert(err, IsNil)
1769	c.Assert(typ, Equals, "application/octet-stream")
1770
1771	opts = addContentType([]Option{Meta("meta", "my")}, "abc", "abc.txt", "abc.pdf")
1772	typ, err = findOption(opts, HTTPHeaderContentType, "")
1773	c.Assert(err, IsNil)
1774	c.Assert(len(opts), Equals, 2)
1775	c.Assert(typ, Equals, "text/plain; charset=utf-8")
1776}
1777
1778func (s *OssBucketSuite) TestGetConfig(c *C) {
1779	client, err := New(endpoint, accessID, accessKey, UseCname(true),
1780		Timeout(11, 12), SecurityToken("token"), EnableMD5(false))
1781	c.Assert(err, IsNil)
1782
1783	bucket, err := client.Bucket(bucketName)
1784	c.Assert(err, IsNil)
1785
1786	c.Assert(bucket.getConfig().HTTPTimeout.ConnectTimeout, Equals, time.Second*11)
1787	c.Assert(bucket.getConfig().HTTPTimeout.ReadWriteTimeout, Equals, time.Second*12)
1788	c.Assert(bucket.getConfig().HTTPTimeout.HeaderTimeout, Equals, time.Second*12)
1789	c.Assert(bucket.getConfig().HTTPTimeout.IdleConnTimeout, Equals, time.Second*12)
1790	c.Assert(bucket.getConfig().HTTPTimeout.LongTimeout, Equals, time.Second*12*10)
1791
1792	c.Assert(bucket.getConfig().SecurityToken, Equals, "token")
1793	c.Assert(bucket.getConfig().IsCname, Equals, true)
1794	c.Assert(bucket.getConfig().IsEnableMD5, Equals, false)
1795}
1796
1797func (s *OssBucketSuite) TestSTSToken(c *C) {
1798	objectName := objectNamePrefix + "tst"
1799	objectValue := "红藕香残玉簟秋。轻解罗裳,独上兰舟。云中谁寄锦书来?雁字回时,月满西楼。"
1800
1801	stsClient := sts.NewClient(stsaccessID, stsaccessKey, stsARN, "oss_test_sess")
1802
1803	resp, err := stsClient.AssumeRole(1800)
1804	c.Assert(err, IsNil)
1805
1806	client, err := New(endpoint, resp.Credentials.AccessKeyId, resp.Credentials.AccessKeySecret,
1807		SecurityToken(resp.Credentials.SecurityToken))
1808	c.Assert(err, IsNil)
1809
1810	bucket, err := client.Bucket(bucketName)
1811	c.Assert(err, IsNil)
1812
1813	// Put
1814	err = bucket.PutObject(objectName, strings.NewReader(objectValue))
1815	c.Assert(err, IsNil)
1816
1817	// Get
1818	body, err := bucket.GetObject(objectName)
1819	c.Assert(err, IsNil)
1820	str, err := readBody(body)
1821	c.Assert(err, IsNil)
1822	c.Assert(str, Equals, objectValue)
1823
1824	// List
1825	lor, err := bucket.ListObjects()
1826	c.Assert(err, IsNil)
1827	testLogger.Println("Objects:", lor.Objects)
1828
1829	// Put with URL
1830	signedURL, err := bucket.SignURL(objectName, HTTPPut, 3600)
1831	c.Assert(err, IsNil)
1832
1833	err = bucket.PutObjectWithURL(signedURL, strings.NewReader(objectValue))
1834	c.Assert(err, IsNil)
1835
1836	// Get with URL
1837	signedURL, err = bucket.SignURL(objectName, HTTPGet, 3600)
1838	c.Assert(err, IsNil)
1839
1840	body, err = bucket.GetObjectWithURL(signedURL)
1841	c.Assert(err, IsNil)
1842	str, err = readBody(body)
1843	c.Assert(err, IsNil)
1844	c.Assert(str, Equals, objectValue)
1845
1846	// Delete
1847	err = bucket.DeleteObject(objectName)
1848	c.Assert(err, IsNil)
1849}
1850
1851func (s *OssBucketSuite) TestSTSTonekNegative(c *C) {
1852	objectName := objectNamePrefix + "tstg"
1853	localFile := objectName + ".jpg"
1854
1855	client, err := New(endpoint, accessID, accessKey, SecurityToken("Invalid"))
1856	c.Assert(err, IsNil)
1857
1858	_, err = client.ListBuckets()
1859	c.Assert(err, NotNil)
1860
1861	bucket, err := client.Bucket(bucketName)
1862	c.Assert(err, IsNil)
1863
1864	err = bucket.PutObject(objectName, strings.NewReader(""))
1865	c.Assert(err, NotNil)
1866
1867	err = bucket.PutObjectFromFile(objectName, "")
1868	c.Assert(err, NotNil)
1869
1870	_, err = bucket.GetObject(objectName)
1871	c.Assert(err, NotNil)
1872
1873	err = bucket.GetObjectToFile(objectName, "")
1874	c.Assert(err, NotNil)
1875
1876	_, err = bucket.ListObjects()
1877	c.Assert(err, NotNil)
1878
1879	err = bucket.SetObjectACL(objectName, ACLPublicRead)
1880	c.Assert(err, NotNil)
1881
1882	_, err = bucket.GetObjectACL(objectName)
1883	c.Assert(err, NotNil)
1884
1885	err = bucket.UploadFile(objectName, localFile, MinPartSize)
1886	c.Assert(err, NotNil)
1887
1888	err = bucket.DownloadFile(objectName, localFile, MinPartSize)
1889	c.Assert(err, NotNil)
1890
1891	_, err = bucket.IsObjectExist(objectName)
1892	c.Assert(err, NotNil)
1893
1894	_, err = bucket.ListMultipartUploads()
1895	c.Assert(err, NotNil)
1896
1897	err = bucket.DeleteObject(objectName)
1898	c.Assert(err, NotNil)
1899
1900	_, err = bucket.DeleteObjects([]string{objectName})
1901	c.Assert(err, NotNil)
1902
1903	err = client.DeleteBucket(bucketName)
1904	c.Assert(err, NotNil)
1905}
1906
1907func (s *OssBucketSuite) TestUploadBigFile(c *C) {
1908	objectName := objectNamePrefix + "tubf"
1909	bigFile := "D:\\tmp\\bigfile.zip"
1910	newFile := "D:\\tmp\\newbigfile.zip"
1911
1912	exist, err := isFileExist(bigFile)
1913	c.Assert(err, IsNil)
1914	if !exist {
1915		return
1916	}
1917
1918	// Put
1919	start := GetNowSec()
1920	err = s.bucket.PutObjectFromFile(objectName, bigFile)
1921	c.Assert(err, IsNil)
1922	end := GetNowSec()
1923	testLogger.Println("Put big file:", bigFile, "use sec:", end-start)
1924
1925	// Check
1926	start = GetNowSec()
1927	err = s.bucket.GetObjectToFile(objectName, newFile)
1928	c.Assert(err, IsNil)
1929	end = GetNowSec()
1930	testLogger.Println("Get big file:", bigFile, "use sec:", end-start)
1931
1932	start = GetNowSec()
1933	eq, err := compareFiles(bigFile, newFile)
1934	c.Assert(err, IsNil)
1935	c.Assert(eq, Equals, true)
1936	end = GetNowSec()
1937	testLogger.Println("Compare big file:", bigFile, "use sec:", end-start)
1938
1939	err = s.bucket.DeleteObject(objectName)
1940	c.Assert(err, IsNil)
1941}
1942
1943func (s *OssBucketSuite) TestSymlink(c *C) {
1944	objectName := objectNamePrefix + "符号链接"
1945	targetObjectName := objectNamePrefix + "符号链接目标文件"
1946
1947	err := s.bucket.DeleteObject(objectName)
1948	c.Assert(err, IsNil)
1949
1950	err = s.bucket.DeleteObject(targetObjectName)
1951	c.Assert(err, IsNil)
1952
1953	meta, err := s.bucket.GetSymlink(objectName)
1954	c.Assert(err, NotNil)
1955
1956	// Put symlink
1957	err = s.bucket.PutSymlink(objectName, targetObjectName)
1958	c.Assert(err, IsNil)
1959
1960	err = s.bucket.PutObject(targetObjectName, strings.NewReader("target"))
1961	c.Assert(err, IsNil)
1962
1963	err = s.bucket.PutSymlink(objectName, targetObjectName)
1964	c.Assert(err, IsNil)
1965
1966	meta, err = s.bucket.GetSymlink(objectName)
1967	c.Assert(err, IsNil)
1968	c.Assert(meta.Get(HTTPHeaderOssSymlinkTarget), Equals, targetObjectName)
1969
1970	// List object
1971	lor, err := s.bucket.ListObjects()
1972	c.Assert(err, IsNil)
1973	exist, v := s.getObject(lor.Objects, objectName)
1974	c.Assert(exist, Equals, true)
1975	c.Assert(v.Type, Equals, "Symlink")
1976
1977	body, err := s.bucket.GetObject(objectName)
1978	c.Assert(err, IsNil)
1979	str, err := readBody(body)
1980	c.Assert(err, IsNil)
1981	c.Assert(str, Equals, "target")
1982
1983	meta, err = s.bucket.GetSymlink(targetObjectName)
1984	c.Assert(err, NotNil)
1985
1986	err = s.bucket.PutObject(objectName, strings.NewReader("src"))
1987	c.Assert(err, IsNil)
1988
1989	body, err = s.bucket.GetObject(objectName)
1990	c.Assert(err, IsNil)
1991	str, err = readBody(body)
1992	c.Assert(err, IsNil)
1993	c.Assert(str, Equals, "src")
1994
1995	err = s.bucket.DeleteObject(objectName)
1996	c.Assert(err, IsNil)
1997
1998	err = s.bucket.DeleteObject(targetObjectName)
1999	c.Assert(err, IsNil)
2000
2001	// Put symlink again
2002	objectName = objectNamePrefix + "symlink"
2003	targetObjectName = objectNamePrefix + "symlink-target"
2004
2005	err = s.bucket.PutSymlink(objectName, targetObjectName)
2006	c.Assert(err, IsNil)
2007
2008	err = s.bucket.PutObject(targetObjectName, strings.NewReader("target1"))
2009	c.Assert(err, IsNil)
2010
2011	meta, err = s.bucket.GetSymlink(objectName)
2012	c.Assert(err, IsNil)
2013	c.Assert(meta.Get(HTTPHeaderOssSymlinkTarget), Equals, targetObjectName)
2014
2015	body, err = s.bucket.GetObject(objectName)
2016	c.Assert(err, IsNil)
2017	str, err = readBody(body)
2018	c.Assert(err, IsNil)
2019	c.Assert(str, Equals, "target1")
2020
2021	err = s.bucket.DeleteObject(objectName)
2022	c.Assert(err, IsNil)
2023
2024	err = s.bucket.DeleteObject(targetObjectName)
2025	c.Assert(err, IsNil)
2026}
2027
2028// TestRestoreObject
2029func (s *OssBucketSuite) TestRestoreObject(c *C) {
2030	objectName := objectNamePrefix + "restore"
2031
2032	// List objects
2033	lor, err := s.archiveBucket.ListObjects()
2034	c.Assert(err, IsNil)
2035	left := len(lor.Objects)
2036
2037	// Put object
2038	err = s.archiveBucket.PutObject(objectName, strings.NewReader(""))
2039	c.Assert(err, IsNil)
2040
2041	// List
2042	lor, err = s.archiveBucket.ListObjects()
2043	c.Assert(err, IsNil)
2044	c.Assert(len(lor.Objects), Equals, left+1)
2045	for _, object := range lor.Objects {
2046		c.Assert(object.StorageClass, Equals, string(StorageArchive))
2047		c.Assert(object.Type, Equals, "Normal")
2048	}
2049
2050	// Head object
2051	meta, err := s.archiveBucket.GetObjectDetailedMeta(objectName)
2052	c.Assert(err, IsNil)
2053	_, ok := meta["X-Oss-Restore"]
2054	c.Assert(ok, Equals, false)
2055	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
2056
2057	// Error restore object
2058	err = s.archiveBucket.RestoreObject("notexistobject")
2059	c.Assert(err, NotNil)
2060
2061	// Restore object
2062	err = s.archiveBucket.RestoreObject(objectName)
2063	c.Assert(err, IsNil)
2064
2065	// Head object
2066	meta, err = s.archiveBucket.GetObjectDetailedMeta(objectName)
2067	c.Assert(err, IsNil)
2068	c.Assert(meta.Get("X-Oss-Restore"), Equals, "ongoing-request=\"true\"")
2069	c.Assert(meta.Get("X-Oss-Storage-Class"), Equals, "Archive")
2070}
2071
2072// TestProcessObject
2073func (s *OssBucketSuite) TestProcessObject(c *C) {
2074	objectName := objectNamePrefix + "_process_src.jpg"
2075	err := s.bucket.PutObjectFromFile(objectName, "../sample/BingWallpaper-2015-11-07.jpg")
2076	c.Assert(err, IsNil)
2077
2078	// If bucket-name not specified, it is saved to the current bucket by default.
2079	destObjName := objectNamePrefix + "_process_dest_1.jpg"
2080	process := fmt.Sprintf("image/resize,w_100|sys/saveas,o_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)))
2081	result, err := s.bucket.ProcessObject(objectName, process)
2082	c.Assert(err, IsNil)
2083	exist, _ := s.bucket.IsObjectExist(destObjName)
2084	c.Assert(exist, Equals, true)
2085	c.Assert(result.Bucket, Equals, "")
2086	c.Assert(result.Object, Equals, destObjName)
2087
2088	destObjName = objectNamePrefix + "_process_dest_1.jpg"
2089	process = fmt.Sprintf("image/resize,w_100|sys/saveas,o_%v,b_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)), base64.URLEncoding.EncodeToString([]byte(s.bucket.BucketName)))
2090	result, err = s.bucket.ProcessObject(objectName, process)
2091	c.Assert(err, IsNil)
2092	exist, _ = s.bucket.IsObjectExist(destObjName)
2093	c.Assert(exist, Equals, true)
2094	c.Assert(result.Bucket, Equals, s.bucket.BucketName)
2095	c.Assert(result.Object, Equals, destObjName)
2096
2097	//no support process
2098	process = fmt.Sprintf("image/resize,w_100|saveas,o_%v,b_%v", base64.URLEncoding.EncodeToString([]byte(destObjName)), base64.URLEncoding.EncodeToString([]byte(s.bucket.BucketName)))
2099	result, err = s.bucket.ProcessObject(objectName, process)
2100	c.Assert(err, NotNil)
2101}
2102
2103// Private
2104func createFileAndWrite(fileName string, data []byte) error {
2105	os.Remove(fileName)
2106
2107	fo, err := os.Create(fileName)
2108	if err != nil {
2109		return err
2110	}
2111	defer fo.Close()
2112
2113	bytes, err := fo.Write(data)
2114	if err != nil {
2115		return err
2116	}
2117
2118	if bytes != len(data) {
2119		return fmt.Errorf(fmt.Sprintf("write %d bytes not equal data length %d", bytes, len(data)))
2120	}
2121
2122	return nil
2123}
2124
2125// Compare the content between fileL and fileR
2126func compareFiles(fileL string, fileR string) (bool, error) {
2127	finL, err := os.Open(fileL)
2128	if err != nil {
2129		return false, err
2130	}
2131	defer finL.Close()
2132
2133	finR, err := os.Open(fileR)
2134	if err != nil {
2135		return false, err
2136	}
2137	defer finR.Close()
2138
2139	statL, err := finL.Stat()
2140	if err != nil {
2141		return false, err
2142	}
2143
2144	statR, err := finR.Stat()
2145	if err != nil {
2146		return false, err
2147	}
2148
2149	if statL.Size() != statR.Size() {
2150		return false, nil
2151	}
2152
2153	size := statL.Size()
2154	if size > 102400 {
2155		size = 102400
2156	}
2157
2158	bufL := make([]byte, size)
2159	bufR := make([]byte, size)
2160	for {
2161		n, _ := finL.Read(bufL)
2162		if 0 == n {
2163			break
2164		}
2165
2166		n, _ = finR.Read(bufR)
2167		if 0 == n {
2168			break
2169		}
2170
2171		if !bytes.Equal(bufL, bufR) {
2172			return false, nil
2173		}
2174	}
2175
2176	return true, nil
2177}
2178
2179// Compare the content of file and data
2180func compareFileData(file string, data []byte) (bool, error) {
2181	fin, err := os.Open(file)
2182	if err != nil {
2183		return false, err
2184	}
2185	defer fin.Close()
2186
2187	stat, err := fin.Stat()
2188	if err != nil {
2189		return false, err
2190	}
2191
2192	if stat.Size() != (int64)(len(data)) {
2193		return false, nil
2194	}
2195
2196	buf := make([]byte, stat.Size())
2197	n, err := fin.Read(buf)
2198	if err != nil {
2199		return false, err
2200	}
2201	if stat.Size() != (int64)(n) {
2202		return false, errors.New("read error")
2203	}
2204
2205	if !bytes.Equal(buf, data) {
2206		return false, nil
2207	}
2208
2209	return true, nil
2210}
2211
2212func walkDir(dirPth, suffix string) ([]string, error) {
2213	var files = []string{}
2214	suffix = strings.ToUpper(suffix)
2215	err := filepath.Walk(dirPth,
2216		func(filename string, fi os.FileInfo, err error) error {
2217			if err != nil {
2218				return err
2219			}
2220			if fi.IsDir() {
2221				return nil
2222			}
2223			if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
2224				files = append(files, filename)
2225			}
2226			return nil
2227		})
2228	return files, err
2229}
2230
2231func removeTempFiles(path string, prefix string) error {
2232	files, err := walkDir(path, prefix)
2233	if err != nil {
2234		return nil
2235	}
2236
2237	for _, file := range files {
2238		os.Remove(file)
2239	}
2240
2241	return nil
2242}
2243
2244func isFileExist(filename string) (bool, error) {
2245	_, err := os.Stat(filename)
2246	if err != nil && os.IsNotExist(err) {
2247		return false, nil
2248	} else if err != nil {
2249		return false, err
2250	} else {
2251		return true, nil
2252	}
2253}
2254
2255func readBody(body io.ReadCloser) (string, error) {
2256	data, err := ioutil.ReadAll(body)
2257	body.Close()
2258	if err != nil {
2259		return "", err
2260	}
2261	return string(data), nil
2262}
2263
2264func (s *OssBucketSuite) getObject(objects []ObjectProperties, object string) (bool, ObjectProperties) {
2265	for _, v := range objects {
2266		if v.Key == object {
2267			return true, v
2268		}
2269	}
2270	return false, ObjectProperties{}
2271}
2272
2273func (s *OssBucketSuite) detectUploadSpeed(bucket *Bucket, c *C) (upSpeed int) {
2274	objectName := objectNamePrefix + getUuid()
2275
2276	// 1M byte
2277	textBuffer := randStr(1024 * 1024)
2278
2279	// Put string
2280	startT := time.Now()
2281	err := bucket.PutObject(objectName, strings.NewReader(textBuffer))
2282	endT := time.Now()
2283
2284	c.Assert(err, IsNil)
2285	err = bucket.DeleteObject(objectName)
2286	c.Assert(err, IsNil)
2287
2288	// byte/s
2289	upSpeed = len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
2290	return upSpeed
2291}
2292
2293func (s *OssBucketSuite) TestPutSingleObjectLimitSpeed(c *C) {
2294
2295	// create client and bucket
2296	client, err := New(endpoint, accessID, accessKey)
2297	c.Assert(err, IsNil)
2298
2299	err = client.LimitUploadSpeed(1)
2300	if err != nil {
2301		// go version is less than go1.7,not support limit upload speed
2302		// doesn't run this test
2303		return
2304	} else {
2305		// set unlimited again
2306		client.LimitUploadSpeed(0)
2307	}
2308
2309	bucketName := bucketNamePrefix + randLowStr(5)
2310	err = client.CreateBucket(bucketName)
2311	c.Assert(err, IsNil)
2312
2313	bucket, err := client.Bucket(bucketName)
2314	c.Assert(err, IsNil)
2315
2316	//detect speed:byte/s
2317	detectSpeed := s.detectUploadSpeed(bucket, c)
2318
2319	var limitSpeed = 0
2320	if detectSpeed <= perTokenBandwidthSize*2 {
2321		limitSpeed = perTokenBandwidthSize
2322	} else {
2323		//this situation, the test works better
2324		limitSpeed = detectSpeed / 2
2325	}
2326
2327	// KB/s
2328	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
2329	c.Assert(err, IsNil)
2330
2331	objectName := objectNamePrefix + getUuid()
2332
2333	// 1M byte
2334	textBuffer := randStr(1024 * 1024)
2335
2336	// Put body
2337	startT := time.Now()
2338	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
2339	endT := time.Now()
2340
2341	realSpeed := int64(len(textBuffer)) * 1000 / (endT.UnixNano()/1000/1000 - startT.UnixNano()/1000/1000)
2342
2343	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
2344
2345	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
2346
2347	if detectSpeed > perTokenBandwidthSize {
2348		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
2349		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
2350	}
2351
2352	// Get object and compare content
2353	body, err := bucket.GetObject(objectName)
2354	c.Assert(err, IsNil)
2355	str, err := readBody(body)
2356	c.Assert(err, IsNil)
2357	c.Assert(str, Equals, textBuffer)
2358
2359	bucket.DeleteObject(objectName)
2360	client.DeleteBucket(bucketName)
2361	c.Assert(err, IsNil)
2362
2363	return
2364}
2365
2366func putObjectRoutin(bucket *Bucket, object string, textBuffer *string, notifyChan chan int) error {
2367	err := bucket.PutObject(object, strings.NewReader(*textBuffer))
2368	if err == nil {
2369		notifyChan <- 1
2370	} else {
2371		notifyChan <- 0
2372	}
2373	return err
2374}
2375
2376func (s *OssBucketSuite) TestPutManyObjectLimitSpeed(c *C) {
2377
2378	// create client and bucket
2379	client, err := New(endpoint, accessID, accessKey)
2380	c.Assert(err, IsNil)
2381
2382	err = client.LimitUploadSpeed(1)
2383	if err != nil {
2384		// go version is less than go1.7,not support limit upload speed
2385		// doesn't run this test
2386		return
2387	} else {
2388		// set unlimited
2389		client.LimitUploadSpeed(0)
2390	}
2391
2392	bucketName := bucketNamePrefix + randLowStr(5)
2393	err = client.CreateBucket(bucketName)
2394	c.Assert(err, IsNil)
2395
2396	bucket, err := client.Bucket(bucketName)
2397	c.Assert(err, IsNil)
2398
2399	//detect speed:byte/s
2400	detectSpeed := s.detectUploadSpeed(bucket, c)
2401	var limitSpeed = 0
2402	if detectSpeed <= perTokenBandwidthSize*2 {
2403		limitSpeed = perTokenBandwidthSize
2404	} else {
2405		limitSpeed = detectSpeed / 2
2406	}
2407
2408	// KB/s
2409	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
2410	c.Assert(err, IsNil)
2411
2412	// object1
2413	objectNameFirst := objectNamePrefix + getUuid()
2414	objectNameSecond := objectNamePrefix + getUuid()
2415
2416	// 1M byte
2417	textBuffer := randStr(1024 * 1024)
2418
2419	objectCount := 2
2420	notifyChan := make(chan int, objectCount)
2421
2422	//start routin
2423	startT := time.Now()
2424	go putObjectRoutin(bucket, objectNameFirst, &textBuffer, notifyChan)
2425	go putObjectRoutin(bucket, objectNameSecond, &textBuffer, notifyChan)
2426
2427	// wait routin end
2428	sum := int(0)
2429	for j := 0; j < objectCount; j++ {
2430		result := <-notifyChan
2431		sum += result
2432	}
2433	endT := time.Now()
2434
2435	realSpeed := len(textBuffer) * 2 * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
2436	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
2437
2438	if detectSpeed > perTokenBandwidthSize {
2439		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
2440		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
2441	}
2442	c.Assert(sum, Equals, 2)
2443
2444	// Get object and compare content
2445	body, err := bucket.GetObject(objectNameFirst)
2446	c.Assert(err, IsNil)
2447	str, err := readBody(body)
2448	c.Assert(err, IsNil)
2449	c.Assert(str, Equals, textBuffer)
2450
2451	body, err = bucket.GetObject(objectNameSecond)
2452	c.Assert(err, IsNil)
2453	str, err = readBody(body)
2454	c.Assert(err, IsNil)
2455	c.Assert(str, Equals, textBuffer)
2456
2457	// clear bucket and object
2458	bucket.DeleteObject(objectNameFirst)
2459	bucket.DeleteObject(objectNameSecond)
2460	client.DeleteBucket(bucketName)
2461
2462	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
2463
2464	return
2465}
2466
2467func (s *OssBucketSuite) TestPutMultipartObjectLimitSpeed(c *C) {
2468
2469	// create client and bucket
2470	client, err := New(endpoint, accessID, accessKey)
2471	c.Assert(err, IsNil)
2472
2473	err = client.LimitUploadSpeed(1)
2474	if err != nil {
2475		// go version is less than go1.7,not support limit upload speed
2476		// doesn't run this test
2477		return
2478	} else {
2479		// set unlimited
2480		client.LimitUploadSpeed(0)
2481	}
2482
2483	bucketName := bucketNamePrefix + randLowStr(5)
2484	err = client.CreateBucket(bucketName)
2485	c.Assert(err, IsNil)
2486
2487	bucket, err := client.Bucket(bucketName)
2488	c.Assert(err, IsNil)
2489
2490	//detect speed:byte/s
2491	detectSpeed := s.detectUploadSpeed(bucket, c)
2492
2493	var limitSpeed = 0
2494	if detectSpeed <= perTokenBandwidthSize*2 {
2495		limitSpeed = perTokenBandwidthSize
2496	} else {
2497		//this situation, the test works better
2498		limitSpeed = detectSpeed / 2
2499	}
2500
2501	// KB/s
2502	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
2503	c.Assert(err, IsNil)
2504
2505	objectName := objectNamePrefix + getUuid()
2506	fileName := "." + string(os.PathSeparator) + objectName
2507
2508	// 1M byte
2509	fileSize := 0
2510	textBuffer := randStr(1024 * 1024)
2511	if detectSpeed < perTokenBandwidthSize {
2512		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
2513		f, err := os.Stat(fileName)
2514		c.Assert(err, IsNil)
2515
2516		fileSize = int(f.Size())
2517		c.Assert(fileSize, Equals, len(textBuffer))
2518
2519	} else {
2520		loopCount := 5
2521		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
2522		c.Assert(err, IsNil)
2523
2524		for i := 0; i < loopCount; i++ {
2525			f.Write([]byte(textBuffer))
2526		}
2527
2528		fileInfo, err := f.Stat()
2529		c.Assert(err, IsNil)
2530
2531		fileSize = int(fileInfo.Size())
2532		c.Assert(fileSize, Equals, len(textBuffer)*loopCount)
2533
2534		f.Close()
2535	}
2536
2537	// Put body
2538	startT := time.Now()
2539	err = bucket.UploadFile(objectName, fileName, 100*1024, Routines(3), Checkpoint(true, ""))
2540	endT := time.Now()
2541
2542	c.Assert(err, IsNil)
2543	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
2544	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
2545
2546	if detectSpeed > perTokenBandwidthSize {
2547		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
2548		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
2549	}
2550
2551	// Get object and compare content
2552	body, err := bucket.GetObject(objectName)
2553	c.Assert(err, IsNil)
2554	str, err := readBody(body)
2555	c.Assert(err, IsNil)
2556
2557	fileBody, err := ioutil.ReadFile(fileName)
2558	c.Assert(err, IsNil)
2559	c.Assert(str, Equals, string(fileBody))
2560
2561	// delete bucket、object、file
2562	bucket.DeleteObject(objectName)
2563	client.DeleteBucket(bucketName)
2564	os.Remove(fileName)
2565
2566	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
2567
2568	return
2569}
2570
2571func (s *OssBucketSuite) TestPutObjectFromFileLimitSpeed(c *C) {
2572	// create client and bucket
2573	client, err := New(endpoint, accessID, accessKey)
2574	c.Assert(err, IsNil)
2575
2576	err = client.LimitUploadSpeed(1)
2577	if err != nil {
2578		// go version is less than go1.7,not support limit upload speed
2579		// doesn't run this test
2580		return
2581	} else {
2582		// set unlimited
2583		client.LimitUploadSpeed(0)
2584	}
2585
2586	bucketName := bucketNamePrefix + randLowStr(5)
2587	err = client.CreateBucket(bucketName)
2588	c.Assert(err, IsNil)
2589
2590	bucket, err := client.Bucket(bucketName)
2591	c.Assert(err, IsNil)
2592
2593	//detect speed:byte/s
2594	detectSpeed := s.detectUploadSpeed(bucket, c)
2595
2596	var limitSpeed = 0
2597	if detectSpeed <= perTokenBandwidthSize*2 {
2598		limitSpeed = perTokenBandwidthSize
2599	} else {
2600		//this situation, the test works better
2601		limitSpeed = detectSpeed / 2
2602	}
2603
2604	// KB/s
2605	err = client.LimitUploadSpeed(limitSpeed / perTokenBandwidthSize)
2606	c.Assert(err, IsNil)
2607
2608	objectName := objectNamePrefix + getUuid()
2609	fileName := "." + string(os.PathSeparator) + objectName
2610
2611	// 1M byte
2612	fileSize := 0
2613	textBuffer := randStr(1024 * 1024)
2614	if detectSpeed < perTokenBandwidthSize {
2615		ioutil.WriteFile(fileName, []byte(textBuffer), 0644)
2616		f, err := os.Stat(fileName)
2617		c.Assert(err, IsNil)
2618
2619		fileSize = int(f.Size())
2620		c.Assert(fileSize, Equals, len(textBuffer))
2621
2622	} else {
2623		loopCount := 2
2624		f, err := os.OpenFile(fileName, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
2625		c.Assert(err, IsNil)
2626
2627		for i := 0; i < loopCount; i++ {
2628			f.Write([]byte(textBuffer))
2629		}
2630
2631		fileInfo, err := f.Stat()
2632		c.Assert(err, IsNil)
2633
2634		fileSize = int(fileInfo.Size())
2635		c.Assert(fileSize, Equals, len(textBuffer)*loopCount)
2636
2637		f.Close()
2638	}
2639
2640	// Put body
2641	startT := time.Now()
2642	err = bucket.PutObjectFromFile(objectName, fileName)
2643	endT := time.Now()
2644
2645	c.Assert(err, IsNil)
2646	realSpeed := fileSize * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
2647	c.Assert(float64(realSpeed) < float64(limitSpeed)*1.1, Equals, true)
2648
2649	if detectSpeed > perTokenBandwidthSize {
2650		// the minimum uploas limit speed is perTokenBandwidthSize(1024 byte/s)
2651		c.Assert(float64(realSpeed) > float64(limitSpeed)*0.9, Equals, true)
2652	}
2653
2654	// Get object and compare content
2655	body, err := bucket.GetObject(objectName)
2656	c.Assert(err, IsNil)
2657	str, err := readBody(body)
2658	c.Assert(err, IsNil)
2659
2660	fileBody, err := ioutil.ReadFile(fileName)
2661	c.Assert(err, IsNil)
2662	c.Assert(str, Equals, string(fileBody))
2663
2664	// delete bucket、file、object
2665	bucket.DeleteObject(objectName)
2666	client.DeleteBucket(bucketName)
2667	os.Remove(fileName)
2668
2669	fmt.Printf("detect speed:%d,limit speed:%d,real speed:%d.\n", detectSpeed, limitSpeed, realSpeed)
2670
2671	return
2672}
2673
2674// upload speed limit parameters will not affect download speed
2675func (s *OssBucketSuite) TestUploadObjectLimitSpeed(c *C) {
2676	// create limit client and bucket
2677	client, err := New(endpoint, accessID, accessKey)
2678	c.Assert(err, IsNil)
2679
2680	tokenCount := 1
2681	err = client.LimitUploadSpeed(tokenCount)
2682	if err != nil {
2683		// go version is less than go1.7,not support limit upload speed
2684		// doesn't run this test
2685		return
2686	} else {
2687		// set unlimited
2688		client.LimitUploadSpeed(0)
2689	}
2690
2691	bucketName := bucketNamePrefix + randLowStr(5)
2692	err = client.CreateBucket(bucketName)
2693	c.Assert(err, IsNil)
2694
2695	bucket, err := client.Bucket(bucketName)
2696	c.Assert(err, IsNil)
2697
2698	//first:upload a object
2699	textBuffer := randStr(1024 * 100)
2700	objectName := objectNamePrefix + getUuid()
2701	err = bucket.PutObject(objectName, strings.NewReader(textBuffer))
2702	c.Assert(err, IsNil)
2703
2704	// limit upload speed
2705	err = client.LimitUploadSpeed(tokenCount)
2706	c.Assert(err, IsNil)
2707
2708	// then download the object
2709	startT := time.Now()
2710	body, err := bucket.GetObject(objectName)
2711	c.Assert(err, IsNil)
2712
2713	str, err := readBody(body)
2714	c.Assert(err, IsNil)
2715	endT := time.Now()
2716
2717	c.Assert(str, Equals, textBuffer)
2718
2719	// byte/s
2720	downloadSpeed := len(textBuffer) * 1000 / int(endT.UnixNano()/1000/1000-startT.UnixNano()/1000/1000)
2721
2722	// upload speed limit parameters will not affect download speed
2723	c.Assert(downloadSpeed > 2*tokenCount*perTokenBandwidthSize, Equals, true)
2724
2725	bucket.DeleteObject(objectName)
2726	client.DeleteBucket(bucketName)
2727}
2728
2729// test LimitUploadSpeed failure
2730func (s *OssBucketSuite) TestLimitUploadSpeedFail(c *C) {
2731	// create limit client and bucket
2732	client, err := New(endpoint, accessID, accessKey)
2733	c.Assert(err, IsNil)
2734
2735	err = client.LimitUploadSpeed(-1)
2736	c.Assert(err, NotNil)
2737
2738	client.Config = nil
2739	err = client.LimitUploadSpeed(100)
2740	c.Assert(err, NotNil)
2741}
2742