github.com/aavshr/aws-sdk-go@v1.41.3/awstesting/integration/performance/s3UploadManager/main_test.go (about)

     1  //go:build integration && perftest
     2  // +build integration,perftest
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"strconv"
    12  	"strings"
    13  	"testing"
    14  
    15  	"github.com/aavshr/aws-sdk-go/aws"
    16  	"github.com/aavshr/aws-sdk-go/awstesting"
    17  	"github.com/aavshr/aws-sdk-go/awstesting/integration"
    18  	"github.com/aavshr/aws-sdk-go/internal/sdkio"
    19  	"github.com/aavshr/aws-sdk-go/service/s3/s3manager"
    20  )
    21  
    22  var benchConfig BenchmarkConfig
    23  
    24  type BenchmarkConfig struct {
    25  	bucket       string
    26  	tempdir      string
    27  	clientConfig ClientConfig
    28  	sizes        string
    29  	parts        string
    30  	concurrency  string
    31  	bufferSize   string
    32  }
    33  
    34  func (b *BenchmarkConfig) SetupFlags(prefix string, flagSet *flag.FlagSet) {
    35  	flagSet.StringVar(&b.bucket, "bucket", "", "Bucket to use for benchmark")
    36  	flagSet.StringVar(&b.tempdir, "temp", os.TempDir(), "location to create temporary files")
    37  
    38  	flagSet.StringVar(&b.sizes, "size",
    39  		fmt.Sprintf("%d,%d",
    40  			5*sdkio.MebiByte,
    41  			1*sdkio.GibiByte), "file sizes to benchmark separated by comma")
    42  
    43  	flagSet.StringVar(&b.parts, "part",
    44  		fmt.Sprintf("%d,%d,%d",
    45  			s3manager.DefaultUploadPartSize,
    46  			25*sdkio.MebiByte,
    47  			100*sdkio.MebiByte), "part sizes to benchmark separated by comma")
    48  
    49  	flagSet.StringVar(&b.concurrency, "concurrency",
    50  		fmt.Sprintf("%d,%d,%d",
    51  			s3manager.DefaultUploadConcurrency,
    52  			2*s3manager.DefaultUploadConcurrency,
    53  			100),
    54  		"concurrences to benchmark separated comma")
    55  
    56  	flagSet.StringVar(&b.bufferSize, "buffer", fmt.Sprintf("%d,%d", 0, 1*sdkio.MebiByte), "part sizes to benchmark separated comma")
    57  	b.clientConfig.SetupFlags(prefix, flagSet)
    58  }
    59  
    60  func (b *BenchmarkConfig) BufferSizes() []int {
    61  	ints, err := b.stringToInt(b.bufferSize)
    62  	if err != nil {
    63  		panic(fmt.Sprintf("failed to parse file sizes: %v", err))
    64  	}
    65  
    66  	return ints
    67  }
    68  
    69  func (b *BenchmarkConfig) FileSizes() []int64 {
    70  	ints, err := b.stringToInt64(b.sizes)
    71  	if err != nil {
    72  		panic(fmt.Sprintf("failed to parse file sizes: %v", err))
    73  	}
    74  
    75  	return ints
    76  }
    77  
    78  func (b *BenchmarkConfig) PartSizes() []int64 {
    79  	ints, err := b.stringToInt64(b.parts)
    80  	if err != nil {
    81  		panic(fmt.Sprintf("failed to parse part sizes: %v", err))
    82  	}
    83  
    84  	return ints
    85  }
    86  
    87  func (b *BenchmarkConfig) Concurrences() []int {
    88  	ints, err := b.stringToInt(b.concurrency)
    89  	if err != nil {
    90  		panic(fmt.Sprintf("failed to parse part sizes: %v", err))
    91  	}
    92  
    93  	return ints
    94  }
    95  
    96  func (b *BenchmarkConfig) stringToInt(s string) ([]int, error) {
    97  	int64s, err := b.stringToInt64(s)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	var ints []int
   103  	for i := range int64s {
   104  		ints = append(ints, int(int64s[i]))
   105  	}
   106  
   107  	return ints, nil
   108  }
   109  
   110  func (b *BenchmarkConfig) stringToInt64(s string) ([]int64, error) {
   111  	var sizes []int64
   112  
   113  	split := strings.Split(s, ",")
   114  
   115  	for _, size := range split {
   116  		size = strings.Trim(size, " ")
   117  		i, err := strconv.ParseInt(size, 10, 64)
   118  		if err != nil {
   119  			return nil, fmt.Errorf("invalid integer %s: %v", size, err)
   120  		}
   121  
   122  		sizes = append(sizes, i)
   123  	}
   124  
   125  	return sizes, nil
   126  }
   127  
   128  func BenchmarkUpload(b *testing.B) {
   129  	baseSdkConfig := SDKConfig{WithUnsignedPayload: true}
   130  
   131  	for _, fileSize := range benchConfig.FileSizes() {
   132  		b.Run(fmt.Sprintf("%s File", integration.SizeToName(int(fileSize))), func(b *testing.B) {
   133  			for _, concurrency := range benchConfig.Concurrences() {
   134  				b.Run(fmt.Sprintf("%d Concurrency", concurrency), func(b *testing.B) {
   135  					for _, partSize := range benchConfig.PartSizes() {
   136  						if partSize > fileSize {
   137  							continue
   138  						}
   139  						partSize = getUploadPartSize(fileSize, partSize)
   140  						b.Run(fmt.Sprintf("%s PartSize", integration.SizeToName(int(partSize))), func(b *testing.B) {
   141  							for _, bufferSize := range benchConfig.BufferSizes() {
   142  								var name string
   143  								if bufferSize == 0 {
   144  									name = "Unbuffered"
   145  								} else {
   146  									name = fmt.Sprintf("%s Buffer", integration.SizeToName(bufferSize))
   147  								}
   148  								b.Run(name, func(b *testing.B) {
   149  									sdkConfig := baseSdkConfig
   150  
   151  									sdkConfig.Concurrency = concurrency
   152  									sdkConfig.PartSize = partSize
   153  									if bufferSize > 0 {
   154  										sdkConfig.BufferProvider = s3manager.NewBufferedReadSeekerWriteToPool(bufferSize)
   155  									}
   156  
   157  									for i := 0; i < b.N; i++ {
   158  										for {
   159  											b.ResetTimer()
   160  											reader := aws.ReadSeekCloser(io.LimitReader(&awstesting.EndlessReader{}, fileSize))
   161  											err := benchUpload(b, benchConfig.bucket, integration.UniqueID(), reader, sdkConfig, benchConfig.clientConfig)
   162  											if err != nil {
   163  												b.Logf("upload failed, retrying: %v", err)
   164  												continue
   165  											}
   166  											break
   167  										}
   168  									}
   169  								})
   170  							}
   171  						})
   172  					}
   173  				})
   174  			}
   175  		})
   176  	}
   177  }
   178  
   179  func benchUpload(b *testing.B, bucket, key string, reader io.ReadSeeker, sdkConfig SDKConfig, clientConfig ClientConfig) error {
   180  	uploader := newUploader(clientConfig, sdkConfig, SetUnsignedPayload)
   181  	_, err := uploader.Upload(&s3manager.UploadInput{
   182  		Bucket: &bucket,
   183  		Key:    &key,
   184  		Body:   reader,
   185  	})
   186  	if err != nil {
   187  		return err
   188  	}
   189  	return nil
   190  }
   191  
   192  func TestMain(m *testing.M) {
   193  	benchConfig.SetupFlags("", flag.CommandLine)
   194  	flag.Parse()
   195  	os.Exit(m.Run())
   196  }