1package oss_test
2
3import (
4	"bytes"
5	"io"
6	"io/ioutil"
7	"math/rand"
8	"net/http"
9	"strconv"
10	"sync"
11	//"net/http"
12	"testing"
13	"time"
14
15	"github.com/denverdino/aliyungo/oss"
16)
17
18var (
19	client           *oss.Client
20	assumeRoleClient *oss.Client
21	TestBucket       = strconv.FormatInt(time.Now().Unix(), 10)
22)
23
24func init() {
25	client = oss.NewOSSClient(TestRegion, false, TestAccessKeyID, TestAccessKeySecret, false)
26	assumeRoleClient = oss.NewOSSClientForAssumeRole(TestRegion, false, TestAccessKeyID, TestAccessKeySecret, TestSecurityToken, false)
27	assumeRoleClient.SetDebug(true)
28}
29
30func TestCreateBucket(t *testing.T) {
31	time.Sleep(20 * time.Second)
32	b := client.Bucket(TestBucket)
33	err := b.PutBucket(oss.Private)
34	if err != nil {
35		t.Errorf("Failed for PutBucket: %v", err)
36	}
37	t.Log("Wait a while for bucket creation ...")
38}
39
40func TestHead(t *testing.T) {
41
42	b := client.Bucket(TestBucket)
43	_, err := b.Head("name", nil)
44
45	if err == nil {
46		t.Errorf("Failed for Head: %v", err)
47	}
48}
49
50func TestPutObject(t *testing.T) {
51	const DISPOSITION = "attachment; filename=\"0x1a2b3c.jpg\""
52
53	b := client.Bucket(TestBucket)
54	err := b.Put("name", []byte("content"), "content-type", oss.Private, oss.Options{ContentDisposition: DISPOSITION})
55	if err != nil {
56		t.Errorf("Failed for Put: %v", err)
57	}
58}
59
60func TestGet(t *testing.T) {
61
62	b := client.Bucket(TestBucket)
63	data, err := b.Get("name")
64
65	if err != nil || string(data) != "content" {
66		t.Errorf("Failed for Get: %v", err)
67	}
68}
69
70func TestURL(t *testing.T) {
71
72	b := client.Bucket(TestBucket)
73	url := b.URL("name")
74
75	t.Log("URL: ", url)
76	//	/c.Assert(req.URL.Path, check.Equals, "/denverdino_test/name")
77}
78
79func TestGetReader(t *testing.T) {
80
81	b := client.Bucket(TestBucket)
82	rc, err := b.GetReader("name")
83	if err != nil {
84		t.Fatalf("Failed for GetReader: %v", err)
85	}
86	data, err := ioutil.ReadAll(rc)
87	rc.Close()
88	if err != nil || string(data) != "content" {
89		t.Errorf("Failed for ReadAll: %v", err)
90	}
91}
92
93func aTestGetNotFound(t *testing.T) {
94
95	b := client.Bucket("non-existent-bucket")
96	_, err := b.Get("non-existent")
97	if err == nil {
98		t.Fatalf("Failed for TestGetNotFound: %v", err)
99	}
100	ossErr, _ := err.(*oss.Error)
101	if ossErr.StatusCode != 404 || ossErr.BucketName != "non-existent-bucket" {
102		t.Errorf("Failed for TestGetNotFound: %v", err)
103	}
104
105}
106
107func TestPutCopy(t *testing.T) {
108	b := client.Bucket(TestBucket)
109	t.Log("Source: ", b.Path("name"))
110	res, err := b.PutCopy("newname", oss.Private, oss.CopyOptions{},
111		b.Path("name"))
112	if err == nil {
113		t.Logf("Copy result: %v", res)
114	} else {
115		t.Errorf("Failed for PutCopy: %v", err)
116	}
117}
118
119func TestPutObjectWithSSE(t *testing.T) {
120	const DISPOSITION = "attachment; filename=\"0x1a2b3c.jpg\""
121
122	b := client.Bucket(TestBucket)
123	err := b.Put("name-sse", []byte("content"), "content-type", oss.Private, oss.Options{
124		ContentDisposition:        DISPOSITION,
125		ServerSideEncryptionKeyID: TestServerSideEncryptionKeyID,
126	})
127	if err != nil {
128		t.Errorf("Failed for Put: %v", err)
129	}
130}
131
132func TestPutCopyWithSSE(t *testing.T) {
133	b := client.Bucket(TestBucket)
134	t.Log("Source: ", b.Path("name-sse"))
135	res, err := b.PutCopy("newname-sse", oss.Private, oss.CopyOptions{
136		ServerSideEncryptionKeyID: TestServerSideEncryptionKeyID,
137	},
138		b.Path("name"))
139	if err == nil {
140		t.Logf("Copy result: %v", res)
141	} else {
142		t.Errorf("Failed for PutCopy: %v", err)
143	}
144}
145
146func TestList(t *testing.T) {
147
148	b := client.Bucket(TestBucket)
149
150	data, err := b.List("n", "", "", 0)
151	if err != nil || len(data.Contents) != 4 {
152		t.Errorf("Failed for List: %v", err)
153	} else {
154		t.Logf("Contents = %++v", data)
155	}
156}
157
158func TestListWithDelimiter(t *testing.T) {
159
160	b := client.Bucket(TestBucket)
161
162	data, err := b.List("photos/2006/", "/", "some-marker", 1000)
163	if err != nil || len(data.Contents) != 0 {
164		t.Errorf("Failed for List: %v", err)
165	} else {
166		t.Logf("Contents = %++v", data)
167	}
168
169}
170
171func TestPutReader(t *testing.T) {
172
173	b := client.Bucket(TestBucket)
174	buf := bytes.NewBufferString("content")
175	err := b.PutReader("name", buf, int64(buf.Len()), "application/octet-stream", oss.Private, oss.Options{})
176	if err != nil {
177		t.Errorf("Failed for PutReader: %v", err)
178	}
179	TestGetReader(t)
180}
181
182var _fileSize int64 = 50 * 1024 * 1024
183var _offset int64 = 10 * 1024 * 1024
184
185func TestPutLargeFile(t *testing.T) {
186
187	reader := newRandReader(_fileSize)
188
189	b := client.Bucket(TestBucket)
190	err := b.PutReader("largefile", reader, _fileSize, "application/octet-stream", oss.Private, oss.Options{})
191	if err != nil {
192		t.Errorf("Failed for PutReader: %v", err)
193	}
194}
195
196func TestGetLargeFile(t *testing.T) {
197	b := client.Bucket(TestBucket)
198	headers := http.Header{}
199	resp, err := b.GetResponseWithHeaders("largefile", headers)
200	if err != nil {
201		t.Fatalf("Failed for GetResponseWithHeaders: %v", err)
202	}
203	if resp.ContentLength != _fileSize {
204		t.Errorf("Read file with incorrect ContentLength: %d", resp.ContentLength)
205
206	}
207	t.Logf("Large file response headers: %++v", resp.Header)
208
209	data, err := ioutil.ReadAll(resp.Body)
210
211	if err != nil {
212		t.Errorf("Failed for Read file: %v", err)
213	}
214
215	if len(data) != int(_fileSize) {
216		t.Errorf("Incorrect length for Read with offset: %v", len(data))
217	}
218	resp.Body.Close()
219}
220
221func TestGetLargeFileWithOffset(t *testing.T) {
222	b := client.Bucket(TestBucket)
223	headers := http.Header{}
224	headers.Add("Range", "bytes="+strconv.FormatInt(_offset, 10)+"-")
225	resp, err := b.GetResponseWithHeaders("largefile", headers)
226	if err != nil {
227		t.Fatalf("Failed for GetResponseWithHeaders: %v", err)
228	}
229	t.Logf("Large file response headers: %++v", resp.Header)
230
231	data, err := ioutil.ReadAll(resp.Body)
232	if err != nil {
233		t.Errorf("Failed for Read with offset: %v", err)
234	}
235	if len(data) != int(_fileSize-_offset) {
236		t.Errorf("Incorrect length for Read with offset: %v", len(data))
237	}
238	resp.Body.Close()
239}
240
241func TestSignedURL(t *testing.T) {
242	b := client.Bucket(TestBucket)
243	expires := time.Now().Add(20 * time.Minute)
244	url := b.SignedURL("largefile", expires)
245	resp, err := http.Get(url)
246	t.Logf("Large file response headers: %++v", resp.Header)
247
248	if err != nil {
249		t.Fatalf("Failed for GetResponseWithHeaders: %v", err)
250	}
251	data, err := ioutil.ReadAll(resp.Body)
252
253	if err != nil {
254		t.Errorf("Failed for Read file: %v", err)
255	}
256
257	if len(data) != int(_fileSize) {
258		t.Errorf("Incorrect length for Read with offset: %v", len(data))
259	}
260	resp.Body.Close()
261}
262
263func TestCopyLargeFile(t *testing.T) {
264	b := client.Bucket(TestBucket)
265	err := b.CopyLargeFile("largefile", "largefile2", "application/octet-stream", oss.Private, oss.Options{})
266	if err != nil {
267		t.Errorf("Failed for copy large file: %v", err)
268	}
269	t.Log("Large file copy successfully.")
270	len1, err := b.GetContentLength("largefile")
271
272	if err != nil {
273		t.Fatalf("Failed for Head file: %v", err)
274	}
275	len2, err := b.GetContentLength("largefile2")
276
277	if err != nil {
278		t.Fatalf("Failed for Head file: %v", err)
279	}
280
281	if len1 != len2 || len1 != _fileSize {
282		t.Fatalf("Content-Length should be equal %d != %d", len1, len2)
283	}
284
285	bytes1, err := b.Get("largefile")
286	if err != nil {
287		t.Fatalf("Failed for Get file: %v", err)
288	}
289	bytes2, err := b.Get("largefile2")
290	if err != nil {
291		t.Fatalf("Failed for Get file: %v", err)
292	}
293
294	if bytes.Compare(bytes1, bytes2) != 0 {
295		t.Fatal("The result should be equal")
296	}
297}
298
299func TestCopyLargeFileInParallel(t *testing.T) {
300	b := client.Bucket(TestBucket)
301	err := b.CopyLargeFileInParallel("largefile", "largefile3", "application/octet-stream", oss.Private, oss.Options{}, 10)
302	if err != nil {
303		t.Errorf("Failed for copy large file: %v", err)
304	}
305	t.Log("Large file copy successfully.")
306	len1, err := b.GetContentLength("largefile")
307
308	if err != nil {
309		t.Fatalf("Failed for Head file: %v", err)
310	}
311	len2, err := b.GetContentLength("largefile3")
312
313	if err != nil {
314		t.Fatalf("Failed for Head file: %v", err)
315	}
316
317	if len1 != len2 || len1 != _fileSize {
318		t.Fatalf("Content-Length should be equal %d != %d", len1, len2)
319	}
320
321	bytes1, err := b.Get("largefile")
322	if err != nil {
323		t.Fatalf("Failed for Get file: %v", err)
324	}
325	bytes2, err := b.Get("largefile3")
326	if err != nil {
327		t.Fatalf("Failed for Get file: %v", err)
328	}
329
330	if bytes.Compare(bytes1, bytes2) != 0 {
331		t.Fatal("The result should be equal")
332	}
333}
334
335func TestDelLargeObject(t *testing.T) {
336
337	b := client.Bucket(TestBucket)
338	err := b.Del("largefile")
339	if err != nil {
340		t.Errorf("Failed for Del largefile: %v", err)
341	}
342	err = b.Del("largefile2")
343	if err != nil {
344		t.Errorf("Failed for Del largefile2: %v", err)
345	}
346	err = b.Del("largefile3")
347	if err != nil {
348		t.Errorf("Failed for Del largefile2: %v", err)
349	}
350}
351
352func TestExists(t *testing.T) {
353
354	b := client.Bucket(TestBucket)
355	result, err := b.Exists("name")
356	if err != nil || result != true {
357		t.Errorf("Failed for Exists: %v", err)
358	}
359}
360
361func TestLocation(t *testing.T) {
362	b := client.Bucket(TestBucket)
363	result, err := b.Location()
364
365	if err != nil || result != string(TestRegion) {
366		t.Errorf("Failed for Location: %v %s", err, result)
367	}
368}
369
370func TestACL(t *testing.T) {
371	b := client.Bucket(TestBucket)
372	result, err := b.ACL()
373
374	if err != nil {
375		t.Errorf("Failed for ACL: %v", err)
376	} else {
377		t.Logf("AccessControlPolicy: %++v", result)
378	}
379}
380
381func TestDelObject(t *testing.T) {
382
383	b := client.Bucket(TestBucket)
384	err := b.Del("name")
385	if err != nil {
386		t.Errorf("Failed for Del: %v", err)
387	}
388}
389
390func TestDelMultiObjects(t *testing.T) {
391
392	b := client.Bucket(TestBucket)
393	objects := []oss.Object{
394		oss.Object{Key: "newname"},
395		oss.Object{Key: "name-sse"},
396		oss.Object{Key: "newname-sse"},
397	}
398	err := b.DelMulti(oss.Delete{
399		Quiet:   false,
400		Objects: objects,
401	})
402	if err != nil {
403		t.Errorf("Failed for DelMulti: %v", err)
404	}
405}
406
407func TestGetService(t *testing.T) {
408	bucketList, err := client.GetService()
409	if err != nil {
410		t.Errorf("Unable to get service: %v", err)
411	} else {
412		t.Logf("GetService: %++v", bucketList)
413	}
414}
415
416func TestGetBucketInfo(t *testing.T) {
417	b := client.Bucket(TestBucket)
418	resp, err := b.Info()
419	if err != nil {
420		t.Errorf("Failed for Info: %v", err)
421	} else {
422		t.Logf("Bucket Info: %v", resp)
423	}
424}
425
426func TestDelBucket(t *testing.T) {
427
428	b := client.Bucket(TestBucket)
429	err := b.DelBucket()
430	if err != nil {
431		t.Errorf("Failed for DelBucket: %v", err)
432	}
433}
434
435type randReader struct {
436	r int64
437	m sync.Mutex
438}
439
440func (rr *randReader) Read(p []byte) (n int, err error) {
441	rr.m.Lock()
442	defer rr.m.Unlock()
443	for i := 0; i < len(p) && rr.r > 0; i++ {
444		p[i] = byte(rand.Intn(255))
445		n++
446		rr.r--
447	}
448	if rr.r == 0 {
449		err = io.EOF
450	}
451	return
452}
453
454func newRandReader(n int64) *randReader {
455	return &randReader{r: n}
456}
457
458func TestNewOSSClientForAssumeRole_GetServices(t *testing.T) {
459	bucketList, err := assumeRoleClient.GetService()
460	if err != nil {
461		t.Fatalf("Error %++v", err)
462	} else {
463		t.Logf("GetService: %++v", bucketList)
464	}
465}
466