@@ -2,13 +2,19 @@ package s3
22
33import (
44 "context"
5+ "io"
6+ "net/http"
7+ "path"
8+ "runtime"
59 "testing"
610 "time"
711
812 "github.com/aws/aws-sdk-go-v2/aws"
913 "github.com/aws/aws-sdk-go-v2/config"
1014 "github.com/aws/aws-sdk-go-v2/credentials"
15+ "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
1116 "github.com/aws/aws-sdk-go-v2/service/s3"
17+ "github.com/aws/aws-sdk-go-v2/service/s3/types"
1218 "github.com/testcontainers/testcontainers-go"
1319 "github.com/testcontainers/testcontainers-go/modules/minio"
1420
@@ -238,3 +244,86 @@ func TestToClientLogMode(t *testing.T) {
238244 })
239245 }
240246}
247+
248+ func BenchmarkAWSUpload (b * testing.B ) {
249+ fsize := int64 (500 * 1024 * 1024 )
250+ numThreds := max (runtime .GOMAXPROCS (0 ), 1 )
251+ partSize := defaultPartSize
252+ // partSize := int64(50 * 1024 * 1024)
253+ // partSize := int64(100 * 1024 * 1024)
254+
255+ region := "eu-central-1"
256+ bucket := ""
257+ prefix := ""
258+ accessKeyID := ""
259+ secretAccessKey := ""
260+
261+ cfgOpts := []func (* config.LoadOptions ) error {
262+ config .WithRegion (region ),
263+ config .WithHTTPClient (& http.Client {}),
264+ config .WithCredentialsProvider (
265+ credentials .NewStaticCredentialsProvider (accessKeyID , secretAccessKey , "" ),
266+ ),
267+ }
268+ awsCfg , err := config .LoadDefaultConfig (context .Background (), cfgOpts ... )
269+ if err != nil {
270+ b .Fatalf ("load default aws config: %v" , err )
271+ }
272+ s3Client := s3 .NewFromConfig (awsCfg )
273+ b .Logf ("aws s3 client: file size=%d bytes; part size=%d bytes; NumThreads=%d" ,
274+ fsize , partSize , numThreds )
275+
276+ b .ResetTimer ()
277+ b .SetBytes (fsize )
278+
279+ for b .Loop () {
280+ b .StopTimer ()
281+ infR := NewInfiniteCustomReader ()
282+ r := io .LimitReader (infR , fsize )
283+
284+ fname := time .Now ().Format ("2006-01-02T15:04:05" )
285+ b .Logf ("uploading file: %s ...." , fname )
286+
287+ putInput := & s3.PutObjectInput {
288+ Bucket : aws .String (bucket ),
289+ Key : aws .String (path .Join (prefix , fname )),
290+ Body : r ,
291+ StorageClass : types .StorageClass (types .StorageClassStandard ),
292+ }
293+
294+ b .StartTimer ()
295+ _ , err := manager .NewUploader (s3Client , func (u * manager.Uploader ) {
296+ u .PartSize = partSize
297+ u .LeavePartsOnError = true
298+ u .Concurrency = numThreds
299+ }).Upload (context .Background (), putInput )
300+ if err != nil {
301+ b .Fatalf ("put object: %v" , err )
302+ }
303+ }
304+ }
305+
306+ type InfiniteCustomReader struct {
307+ pattern []byte
308+ patternIndex int
309+ }
310+
311+ func NewInfiniteCustomReader () * InfiniteCustomReader {
312+ pattern := []byte {0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF , 0x11 , 0x22 }
313+
314+ return & InfiniteCustomReader {
315+ pattern : pattern ,
316+ patternIndex : 0 ,
317+ }
318+ }
319+
320+ func (r * InfiniteCustomReader ) Read (p []byte ) (int , error ) {
321+ readLen := len (p )
322+
323+ for i := range readLen {
324+ p [i ] = r .pattern [r .patternIndex ]
325+ r .patternIndex = (r .patternIndex + 1 ) % len (r .pattern )
326+ }
327+
328+ return readLen , nil
329+ }
0 commit comments