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

     1  //go:build go1.13 && integration && perftest
     2  // +build go1.13,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/awstesting"
    16  	"github.com/aavshr/aws-sdk-go/awstesting/integration"
    17  	"github.com/aavshr/aws-sdk-go/internal/sdkio"
    18  	"github.com/aavshr/aws-sdk-go/service/s3"
    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  	uploadPartSize int64
    33  }
    34  
    35  func (b *BenchmarkConfig) SetupFlags(prefix string, flagSet *flag.FlagSet) {
    36  	flagSet.StringVar(&b.bucket, "bucket", "", "Bucket to use for benchmark")
    37  	flagSet.StringVar(&b.tempdir, "temp", os.TempDir(), "location to create temporary files")
    38  
    39  	flagSet.StringVar(&b.sizes, "size",
    40  		fmt.Sprintf("%d,%d",
    41  			5*sdkio.MebiByte,
    42  			1*sdkio.GibiByte), "file sizes to benchmark separated by comma")
    43  
    44  	flagSet.StringVar(&b.parts, "part",
    45  		fmt.Sprintf("%d,%d,%d",
    46  			s3manager.DefaultDownloadPartSize,
    47  			25*sdkio.MebiByte,
    48  			100*sdkio.MebiByte), "part sizes to benchmark separated by comma")
    49  
    50  	flagSet.StringVar(&b.concurrency, "concurrency",
    51  		fmt.Sprintf("%d,%d,%d",
    52  			s3manager.DefaultDownloadConcurrency,
    53  			2*s3manager.DefaultDownloadConcurrency,
    54  			100),
    55  		"part sizes to benchmark separated comma")
    56  
    57  	flagSet.StringVar(&b.bufferSize, "buffer", fmt.Sprintf("%d,%d", 0, 1*sdkio.MebiByte), "part sizes to benchmark separated comma")
    58  	flagSet.Int64Var(&b.uploadPartSize, "upload-part-size", 0, "upload part size, defaults to download part size if not specified")
    59  	b.clientConfig.SetupFlags(prefix, flagSet)
    60  }
    61  
    62  func (b *BenchmarkConfig) BufferSizes() []int {
    63  	ints, err := b.stringToInt(b.bufferSize)
    64  	if err != nil {
    65  		panic(fmt.Sprintf("failed to parse file sizes: %v", err))
    66  	}
    67  
    68  	return ints
    69  }
    70  
    71  func (b *BenchmarkConfig) FileSizes() []int64 {
    72  	ints, err := b.stringToInt64(b.sizes)
    73  	if err != nil {
    74  		panic(fmt.Sprintf("failed to parse file sizes: %v", err))
    75  	}
    76  
    77  	return ints
    78  }
    79  
    80  func (b *BenchmarkConfig) PartSizes() []int64 {
    81  	ints, err := b.stringToInt64(b.parts)
    82  	if err != nil {
    83  		panic(fmt.Sprintf("failed to parse part sizes: %v", err))
    84  	}
    85  
    86  	return ints
    87  }
    88  
    89  func (b *BenchmarkConfig) Concurrences() []int {
    90  	ints, err := b.stringToInt(b.concurrency)
    91  	if err != nil {
    92  		panic(fmt.Sprintf("failed to parse part sizes: %v", err))
    93  	}
    94  
    95  	return ints
    96  }
    97  
    98  func (b *BenchmarkConfig) stringToInt(s string) ([]int, error) {
    99  	int64s, err := b.stringToInt64(s)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	var ints []int
   105  	for i := range int64s {
   106  		ints = append(ints, int(int64s[i]))
   107  	}
   108  
   109  	return ints, nil
   110  }
   111  
   112  func (b *BenchmarkConfig) stringToInt64(s string) ([]int64, error) {
   113  	var sizes []int64
   114  
   115  	split := strings.Split(s, ",")
   116  
   117  	for _, size := range split {
   118  		size = strings.Trim(size, " ")
   119  		i, err := strconv.ParseInt(size, 10, 64)
   120  		if err != nil {
   121  			return nil, fmt.Errorf("invalid integer %s: %v", size, err)
   122  		}
   123  
   124  		sizes = append(sizes, i)
   125  	}
   126  
   127  	return sizes, nil
   128  }
   129  
   130  func BenchmarkDownload(b *testing.B) {
   131  	baseSdkConfig := SDKConfig{}
   132  
   133  	for _, fileSize := range benchConfig.FileSizes() {
   134  		b.Run(fmt.Sprintf("%s File", integration.SizeToName(int(fileSize))), func(b *testing.B) {
   135  			for _, partSize := range benchConfig.PartSizes() {
   136  				if partSize > fileSize {
   137  					continue
   138  				}
   139  				uploadPartSize := getUploadPartSize(fileSize, benchConfig.uploadPartSize, partSize)
   140  				b.Run(fmt.Sprintf("%s PartSize", integration.SizeToName(int(partSize))), func(b *testing.B) {
   141  					b.Logf("setting up s3 file size")
   142  					key, err := setupDownloadTest(benchConfig.bucket, fileSize, uploadPartSize)
   143  					if err != nil {
   144  						b.Fatalf("failed to setup download test: %v", err)
   145  					}
   146  					for _, concurrency := range benchConfig.Concurrences() {
   147  						b.Run(fmt.Sprintf("%d Concurrency", concurrency), func(b *testing.B) {
   148  							for _, bufferSize := range benchConfig.BufferSizes() {
   149  								var name string
   150  								if bufferSize == 0 {
   151  									name = "unbuffered"
   152  								} else {
   153  									name = fmt.Sprintf("%s buffer", integration.SizeToName(bufferSize))
   154  								}
   155  								b.Run(name, func(b *testing.B) {
   156  									sdkConfig := baseSdkConfig
   157  									sdkConfig.Concurrency = concurrency
   158  									sdkConfig.PartSize = partSize
   159  									if bufferSize > 0 {
   160  										sdkConfig.BufferProvider = s3manager.NewPooledBufferedWriterReadFromProvider(bufferSize)
   161  									}
   162  
   163  									b.ResetTimer()
   164  									for i := 0; i < b.N; i++ {
   165  										benchDownload(b, benchConfig.bucket, key, &awstesting.DiscardAt{}, sdkConfig, benchConfig.clientConfig)
   166  									}
   167  								})
   168  							}
   169  						})
   170  					}
   171  					b.Log("removing test file")
   172  					err = teardownDownloadTest(benchConfig.bucket, key)
   173  					if err != nil {
   174  						b.Fatalf("failed to cleanup test file: %v", err)
   175  					}
   176  				})
   177  			}
   178  		})
   179  	}
   180  }
   181  
   182  func benchDownload(b *testing.B, bucket, key string, body io.WriterAt, sdkConfig SDKConfig, clientConfig ClientConfig) {
   183  	downloader := newDownloader(clientConfig, sdkConfig)
   184  	_, err := downloader.Download(body, &s3.GetObjectInput{
   185  		Bucket: &bucket,
   186  		Key:    &key,
   187  	})
   188  	if err != nil {
   189  		b.Fatalf("failed to download object, %v", err)
   190  	}
   191  }
   192  
   193  func TestMain(m *testing.M) {
   194  	benchConfig.SetupFlags("", flag.CommandLine)
   195  	flag.Parse()
   196  	os.Exit(m.Run())
   197  }