Skip to content

Commit 8a20b96

Browse files
committed
test s3 upload
Signed-off-by: Liang Zheng <zhengliang0901@gmail.com>
1 parent 93c8823 commit 8a20b96

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

s3-examples/retry.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
for i in {1..10000}; do
4+
./test_upload
5+
s3cmd get s3://test/test-upload --force
6+
#s3cmd get s3://test/test-upload /tmp/ --force && s3cmd rm s3://test/test-upload
7+
if [[ $? -ne 0 ]]; then
8+
echo "failed"
9+
exit 0
10+
fi
11+
./test_file
12+
done
13+

s3-examples/test_file.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"os"
7+
)
8+
9+
func main() {
10+
f, err := os.Open("test-upload")
11+
if err != nil {
12+
panic(err)
13+
}
14+
bytes, err := io.ReadAll(f)
15+
if err != nil {
16+
panic(err)
17+
}
18+
fmt.Println(len(bytes))
19+
20+
for i := 0; i < len(bytes); {
21+
fmt.Printf("%s ", string(bytes[i]))
22+
i += 1024 * 1024
23+
}
24+
fmt.Println()
25+
}

s3-examples/test_upload.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io"
7+
"log"
8+
"math"
9+
"math/rand"
10+
"runtime"
11+
"sync"
12+
"time"
13+
14+
"github.com/aws/aws-sdk-go/aws"
15+
"github.com/aws/aws-sdk-go/aws/credentials"
16+
"github.com/aws/aws-sdk-go/aws/session"
17+
"github.com/aws/aws-sdk-go/service/s3"
18+
)
19+
20+
func RetryUpload(svc *s3.S3, bucket, key string) error {
21+
var (
22+
byteSize int = 26 * 1024 * 1024 // 26M
23+
completedParts []*s3.CompletedPart
24+
)
25+
buffer := generateBytes(byteSize)
26+
27+
fmt.Println("start CreateMultipartUpload")
28+
resp, err := svc.CreateMultipartUpload(&s3.CreateMultipartUploadInput{
29+
Bucket: &bucket,
30+
Key: &key,
31+
})
32+
if err != nil {
33+
fmt.Println("failed to CreateMultipartUpload ")
34+
return err
35+
}
36+
log.Println("success to CreateMultipartUpload")
37+
38+
log.Println("start UploadPart PartNumber 1")
39+
// first update 8 MB
40+
fileBytes := buffer[0 : 8*1024*1024]
41+
uploadResult, err := svc.UploadPart(&s3.UploadPartInput{
42+
Body: bytes.NewReader(fileBytes),
43+
Bucket: &bucket,
44+
Key: &key,
45+
PartNumber: aws.Int64(int64(1)),
46+
UploadId: resp.UploadId,
47+
ContentLength: aws.Int64(int64(len(fileBytes))),
48+
})
49+
50+
if err != nil {
51+
log.Println("failed to UploadPart PartNumber 1")
52+
return err
53+
}
54+
55+
etag := uploadResult.ETag
56+
log.Printf("etag: %s\n", *etag)
57+
completedParts = append(completedParts, &s3.CompletedPart{
58+
ETag: etag,
59+
PartNumber: aws.Int64(int64(1)),
60+
})
61+
log.Println("success to UploadPart PartNumber 1")
62+
63+
var wg sync.WaitGroup
64+
wg.Add(3)
65+
f := func(bytes io.ReadSeeker) {
66+
defer wg.Done()
67+
68+
var buf = make([]byte, 64)
69+
var stk = buf[:runtime.Stack(buf, false)]
70+
log.Printf("start UploadPart PartNumber 2, goroutine id: %s\n", string(stk))
71+
// second part
72+
uploadResult2, err := svc.UploadPart(&s3.UploadPartInput{
73+
Body: bytes,
74+
Bucket: &bucket,
75+
Key: &key,
76+
PartNumber: aws.Int64(int64(2)),
77+
UploadId: resp.UploadId,
78+
ContentLength: aws.Int64(int64(16 * 1024 * 1024)), // 16M
79+
})
80+
if err != nil {
81+
log.Printf("Failed to UploadPart PartNumber 2, goroutine id: %s, error: %s\n", string(stk), err.Error())
82+
return
83+
}
84+
log.Printf("success to UploadPart PartNumber 2, goroutine id: %s\n", string(stk))
85+
completedParts = append(completedParts, &s3.CompletedPart{
86+
ETag: uploadResult2.ETag,
87+
PartNumber: aws.Int64(int64(2)),
88+
})
89+
90+
}
91+
92+
go f(bytes.NewReader(buffer[8*1024*1024 : 24*1024*1024]))
93+
// go f(bytes.NewReader(buffer[:16*1024*1024]))
94+
// go f(bytes.NewReader(buffer[2*1024*1024 : 18*1024*1024]))
95+
96+
go f(bytes.NewReader(buffer[2*1024*1024 : 8*1024*1024]))
97+
go f(bytes.NewReader(buffer[19*1024*1024 : 26*1024*1024]))
98+
99+
wg.Wait()
100+
101+
log.Println("CompleteMultipartUpload start")
102+
_, err = svc.CompleteMultipartUpload(&s3.CompleteMultipartUploadInput{
103+
Bucket: &bucket,
104+
Key: &key,
105+
UploadId: resp.UploadId,
106+
MultipartUpload: &s3.CompletedMultipartUpload{
107+
Parts: completedParts,
108+
},
109+
})
110+
if err != nil {
111+
log.Println("failed to CompleteMultipartUpload")
112+
return err
113+
}
114+
log.Println("CompleteMultipartUpload success ")
115+
116+
return nil
117+
}
118+
119+
func generateBytes(size int) []byte {
120+
str := []byte("0123456789abcdefghijklmnopqrstuvwxyz")
121+
ceil := math.Ceil(float64(size) / (1024 * 1024))
122+
var generateBytes []byte
123+
for i := 0; i < int(ceil); i++ {
124+
j := i
125+
if j > len(str) {
126+
j = int(math.Mod(float64(j), float64(len(str))))
127+
}
128+
generateBytes = append(generateBytes, bytes.Repeat([]byte{str[j]}, 1024*1024)...)
129+
}
130+
return generateBytes
131+
}
132+
133+
// Read(p []byte) (n int, err error)
134+
func generateRandomBytes(size int) ([]byte, error) {
135+
rndSrc := rand.NewSource(time.Now().UnixNano())
136+
rng := rand.New(rndSrc)
137+
random := make([]byte, size)
138+
var (
139+
err error
140+
n = 0
141+
retry = 3
142+
)
143+
for i := 0; i < retry && n != size; i++ {
144+
n, err = io.ReadFull(rng, random)
145+
}
146+
if err != nil {
147+
return nil, err
148+
}
149+
return random, nil
150+
}
151+
152+
func main() {
153+
// str1 := string(generateBytes(10))
154+
// str2 := string(generateBytes(1024*1024 + 1))
155+
// fmt.Println(string(str2))
156+
// fmt.Println(len(str1))
157+
// fmt.Println(len(str2))
158+
159+
svc := s3.New(session.Must(session.NewSession(&aws.Config{
160+
Credentials: credentials.NewStaticCredentials("testy", "testy", ""),
161+
Endpoint: aws.String("http://10.9.8.95:80"),
162+
Region: aws.String("us-east-1"),
163+
S3ForcePathStyle: aws.Bool(true),
164+
})))
165+
err := RetryUpload(svc, "test", "test-upload")
166+
if err != nil {
167+
log.Panic(err.Error())
168+
}
169+
}

0 commit comments

Comments
 (0)