@@ -2,8 +2,12 @@ package mio
22
33import (
44 "context"
5+ "io"
56 "net/url"
7+ "path"
8+ "runtime"
69 "testing"
10+ "time"
711
812 "github.com/minio/minio-go/v7"
913 "github.com/minio/minio-go/v7/pkg/credentials"
@@ -80,3 +84,174 @@ func TestMinio(t *testing.T) {
8084 storage .RunSplitMergeMWTests (t , stg )
8185 })
8286}
87+
88+ // TestUploadGCS shows how it's possible to upload corrupted file
89+ // without getting any error from the minio library.
90+ //
91+ // To simulate network interruption use:
92+ // tc qdisc add dev eth0 root netem loss 100%
93+ //
94+ // To revert it to normal use:
95+ // tc qdisc del dev eth0 root netem
96+ func TestUploadGCS (t * testing.T ) {
97+ t .Skip ("for manual invocation, it will be deleted after GCS HMAC is deprecated" )
98+
99+ ep := "storage.googleapis.com"
100+ bucket := "gcs-bucket"
101+ prefix := "test-prefix"
102+ accessKeyID := "key-id"
103+ secretAccessKey := "secret-key"
104+
105+ fname := time .Now ().Format ("2006-01-02T15:04:05" )
106+
107+ mc , err := minio .New (ep , & minio.Options {
108+ Creds : credentials .NewStaticV2 (accessKeyID , secretAccessKey , "" ),
109+ Secure : true ,
110+ })
111+ if err != nil {
112+ t .Fatalf ("minio client creation for GCS: %v" , err )
113+ }
114+ t .Log ("minio client created" )
115+
116+ t .Logf ("uploading file: %s" , fname )
117+
118+ infR := NewInfiniteCustomReader ()
119+ r := io .LimitReader (infR , targetSizeBytes )
120+
121+ putOpts := minio.PutObjectOptions {
122+ PartSize : uint64 (defaultPartSize ),
123+ NumThreads : uint (max (runtime .NumCPU ()/ 2 , 1 )),
124+ }
125+ info , err := mc .PutObject (
126+ context .Background (),
127+ bucket ,
128+ path .Join (prefix , fname ),
129+ r ,
130+ - 1 ,
131+ putOpts ,
132+ )
133+ if err != nil {
134+ t .Fatalf ("put object: %v" , err )
135+ }
136+
137+ t .Logf ("upload info: %#v" , info )
138+ }
139+
140+ func TestUploadAWSSigV2 (t * testing.T ) {
141+ t .Skip ("for manual invocation, it will be deleted after GCS HMAC is deprecated" )
142+
143+ ep := "s3.amazonaws.com"
144+ region := "eu-central-1"
145+ bucket := "aws-bucket"
146+ prefix := "test-prefix"
147+ accessKeyID := "key-id"
148+ secretAccessKey := "secret-key"
149+
150+ fname := time .Now ().Format ("2006-01-02T15:04:05" )
151+
152+ mc , err := minio .New (ep , & minio.Options {
153+ Region : region ,
154+ Creds : credentials .NewStaticV2 (accessKeyID , secretAccessKey , "" ),
155+ Secure : true ,
156+ })
157+ if err != nil {
158+ t .Fatalf ("minio client creation for aws: %v" , err )
159+ }
160+ t .Log ("minio client created for aws with sigV2" )
161+
162+ t .Logf ("uploading file: %s" , fname )
163+
164+ infR := NewInfiniteCustomReader ()
165+ r := io .LimitReader (infR , targetSizeBytes )
166+
167+ putOpts := minio.PutObjectOptions {
168+ PartSize : uint64 (defaultPartSize ),
169+ NumThreads : uint (max (runtime .NumCPU ()/ 2 , 1 )),
170+ }
171+ info , err := mc .PutObject (
172+ context .Background (),
173+ bucket ,
174+ path .Join (prefix , fname ),
175+ r ,
176+ - 1 ,
177+ putOpts ,
178+ )
179+ if err != nil {
180+ t .Fatalf ("put object: %v" , err )
181+ }
182+
183+ t .Logf ("upload info: %#v" , info )
184+ }
185+
186+ func TestUploadAWSSigV4 (t * testing.T ) {
187+ t .Skip ("for manual invocation, it will be deleted after GCS HMAC is deprecated" )
188+
189+ ep := "s3.amazonaws.com"
190+ region := "eu-central-1"
191+ bucket := "aws-bucket"
192+ prefix := "test-prefix"
193+ accessKeyID := "key-id"
194+ secretAccessKey := "secret-key"
195+
196+ fname := time .Now ().Format ("2006-01-02T15:04:05" )
197+
198+ mc , err := minio .New (ep , & minio.Options {
199+ Region : region ,
200+ Creds : credentials .NewStaticV4 (accessKeyID , secretAccessKey , "" ),
201+ Secure : true ,
202+ })
203+ if err != nil {
204+ t .Fatalf ("minio client creation for aws: %v" , err )
205+ }
206+ t .Log ("minio client created for aws with sigV4" )
207+
208+ t .Logf ("uploading file: %s ...." , fname )
209+
210+ infR := NewInfiniteCustomReader ()
211+ r := io .LimitReader (infR , targetSizeBytes )
212+
213+ putOpts := minio.PutObjectOptions {
214+ PartSize : uint64 (defaultPartSize ),
215+ NumThreads : uint (max (runtime .NumCPU ()/ 2 , 1 )),
216+ }
217+ info , err := mc .PutObject (
218+ context .Background (),
219+ bucket ,
220+ path .Join (prefix , fname ),
221+ r ,
222+ - 1 ,
223+ putOpts ,
224+ )
225+ if err != nil {
226+ t .Fatalf ("put object: %v" , err )
227+ }
228+
229+ t .Logf ("upload info: %#v" , info )
230+ }
231+
232+ const targetSizeBytes = 1000 * 1024 * 1024
233+
234+ type InfiniteCustomReader struct {
235+ pattern []byte
236+ patternIndex int
237+ }
238+
239+ func NewInfiniteCustomReader () * InfiniteCustomReader {
240+ pattern := []byte {0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF , 0x11 , 0x22 }
241+
242+ return & InfiniteCustomReader {
243+ pattern : pattern ,
244+ patternIndex : 0 ,
245+ }
246+ }
247+
248+ func (r * InfiniteCustomReader ) Read (p []byte ) (int , error ) {
249+ readLen := len (p )
250+
251+ for i := range readLen {
252+ p [i ] = r .pattern [r .patternIndex ]
253+ r .patternIndex = (r .patternIndex + 1 ) % len (r .pattern )
254+ }
255+
256+ return readLen , nil
257+ }
0 commit comments