Repository: bojand/ghz
Pull request #296 (2021-08-06 00:03:26)

add max message size options
Addresses #69.

Adds CLI options `--max-recv-message-size` and `--max-send-message-size` which can be specified using [human readable value](https://pkg.go.dev/github.com/dustin/go-humanize#ParseBytes) such as `42 MB`.

Adds `WithDefaultCallOptions()` API option which can be used to specify the default call options (including max sizes).


Patch:
diff --git a/cmd/ghz/main.go b/cmd/ghz/main.go
index e22919f..cb6b11e 100644
--- a/cmd/ghz/main.go
+++ b/cmd/ghz/main.go
@@ -11,6 +11,7 @@ import (
 	"strings"
 
 	"github.com/alecthomas/kingpin"
+	"github.com/dustin/go-humanize"
 	"go.uber.org/zap"
 	"go.uber.org/zap/zapcore"
 
@@ -248,9 +249,6 @@ var (
 	debug      = kingpin.Flag("debug", "The path to debug log file.").
 			PlaceHolder(" ").IsSetByUser(&isDebugSet).String()
 
-	isHostSet = false
-	host      = kingpin.Arg("host", "Host and port to test.").String()
-
 	isEnableCompressionSet = false
 	enableCompression      = kingpin.Flag("enable-compression", "Enable Gzip compression on requests.").
 				Short('e').Default("false").IsSetByUser(&isEnableCompressionSet).Bool()
@@ -258,6 +256,19 @@ var (
 	isLBStrategySet = false
 	lbStrategy      = kingpin.Flag("lb-strategy", "Client load balancing strategy.").
 			PlaceHolder(" ").IsSetByUser(&isLBStrategySet).String()
+
+	// message size
+	isMaxRecvMsgSizeSet = false
+	maxRecvMsgSize      = kingpin.Flag("max-recv-message-size", "Maximum message size the client can receive.").
+				PlaceHolder(" ").IsSetByUser(&isMaxRecvMsgSizeSet).String()
+
+	isMaxSendMsgSizeSet = false
+	maxSendMsgSize      = kingpin.Flag("max-send-message-size", "Maximum message size the client can send.").
+				PlaceHolder(" ").IsSetByUser(&isMaxSendMsgSizeSet).String()
+
+	// host main argument
+	isHostSet = false
+	host      = kingpin.Arg("host", "Host and port to test.").String()
 )
 
 func main() {
@@ -397,14 +408,14 @@ func createConfigFromArgs(cfg *runner.Config) error {
 	*md = strings.TrimSpace(*md)
 	if *md != "" {
 		if err := json.Unmarshal([]byte(*md), &metadata); err != nil {
-			return fmt.Errorf("Error unmarshaling metadata '%v': %v", *md, err.Error())
+			return fmt.Errorf("error unmarshaling metadata '%v': %v", *md, err.Error())
 		}
 	}
 
 	var dataObj interface{}
 	if *data != "@" && strings.TrimSpace(*data) != "" {
 		if err := json.Unmarshal([]byte(*data), &dataObj); err != nil {
-			return fmt.Errorf("Error unmarshaling data '%v': %v", *data, err.Error())
+			return fmt.Errorf("error unmarshaling data '%v': %v", *data, err.Error())
 		}
 	}
 
@@ -412,7 +423,7 @@ func createConfigFromArgs(cfg *runner.Config) error {
 	*tags = strings.TrimSpace(*tags)
 	if *tags != "" {
 		if err := json.Unmarshal([]byte(*tags), &tagsMap); err != nil {
-			return fmt.Errorf("Error unmarshaling tags '%v': %v", *tags, err.Error())
+			return fmt.Errorf("error unmarshaling tags '%v': %v", *tags, err.Error())
 		}
 	}
 
@@ -420,7 +431,21 @@ func createConfigFromArgs(cfg *runner.Config) error {
 	*rmd = strings.TrimSpace(*rmd)
 	if *rmd != "" {
 		if err := json.Unmarshal([]byte(*rmd), &rmdMap); err != nil {
-			return fmt.Errorf("Error unmarshaling reflection metadata '%v': %v", *rmd, err.Error())
+			return fmt.Errorf("error unmarshaling reflection metadata '%v': %v", *rmd, err.Error())
+		}
+	}
+
+	if isMaxRecvMsgSizeSet {
+		_, err := humanize.ParseBytes(*maxRecvMsgSize)
+		if err != nil {
+			return errors.New("invalid max call recv message size: " + err.Error())
+		}
+	}
+
+	if isMaxSendMsgSizeSet {
+		_, err := humanize.ParseBytes(*maxSendMsgSize)
+		if err != nil {
+			return errors.New("invalid max call send message size: " + err.Error())
 		}
 	}
 
@@ -480,6 +505,8 @@ func createConfigFromArgs(cfg *runner.Config) error {
 	cfg.CMaxDuration = runner.Duration(*cMaxDuration)
 	cfg.CountErrors = *countErrors
 	cfg.LBStrategy = *lbStrategy
+	cfg.MaxCallRecvMsgSize = *maxRecvMsgSize
+	cfg.MaxCallSendMsgSize = *maxSendMsgSize
 
 	return nil
 }
@@ -723,6 +750,16 @@ func mergeConfig(dest *runner.Config, src *runner.Config) error {
 		dest.CMaxDuration = src.CMaxDuration
 	}
 
+	// message size
+
+	if isMaxRecvMsgSizeSet {
+		dest.MaxCallRecvMsgSize = src.MaxCallRecvMsgSize
+	}
+
+	if isMaxSendMsgSizeSet {
+		dest.MaxCallSendMsgSize = src.MaxCallSendMsgSize
+	}
+
 	return nil
 }
 
diff --git a/go.mod b/go.mod
index dac4cc4..f99cd53 100644
--- a/go.mod
+++ b/go.mod
@@ -6,6 +6,7 @@ require (
 	github.com/alecthomas/kingpin v1.3.8-0.20191105203113-8c96d1c22481
 	github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
 	github.com/bojand/hri v1.1.0
+	github.com/dustin/go-humanize v1.0.0
 	github.com/go-playground/locales v0.13.0 // indirect
 	github.com/go-playground/universal-translator v0.16.0 // indirect
 	github.com/go-playground/validator v9.30.0+incompatible
@@ -29,6 +30,6 @@ require (
 	golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208
 	golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0
 	google.golang.org/grpc v1.34.0
-	google.golang.org/protobuf v1.25.0 // indirect
+	google.golang.org/protobuf v1.25.0
 	gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
 )
diff --git a/go.sum b/go.sum
index bfdd900..0aa0bbe 100644
--- a/go.sum
+++ b/go.sum
@@ -47,11 +47,9 @@ github.com/bojand/hri v1.1.0 h1:OIv6AtbPjYv9A7qjUqylU11mbcP610JWsWCwvpc3w3U=
 github.com/bojand/hri v1.1.0/go.mod h1:qwGosuHpNn1S0nyw/mExN0+WZrDf4bQyWjhWh51y3VY=
 github.com/bombsimon/wsl/v3 v3.1.0 h1:E5SRssoBgtVFPcYWUOFJEcgaySgdtTNYzsSKDOY7ss8=
 github.com/bombsimon/wsl/v3 v3.1.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
-github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 h1:9kRtNpqLHbZVO/NNxhHp2ymxFxsHOe3x2efJGn//Tas=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -74,14 +72,14 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zA
 github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.7 h1:EARl0OvqMoxq/UMgMSCLnXzkaXbxzskluEBlMQCJPms=
 github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
-github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
 github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
@@ -138,7 +136,6 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -146,7 +143,6 @@ github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
 github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
 github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@@ -190,7 +186,6 @@ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
-github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@@ -301,13 +296,11 @@ github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUC
 github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
 github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw=
 github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
@@ -369,7 +362,6 @@ github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9oc
 github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -453,7 +445,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -508,7 +499,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -532,7 +522,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
 golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
 golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
@@ -554,7 +543,6 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -562,14 +550,12 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrS
 golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -594,7 +580,6 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
 golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -654,7 +639,6 @@ golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0 h1:SQvH+DjrwqD1hyyQU+K7Jeg
 golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -679,7 +663,6 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn
 google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a h1:Ob5/580gVHBJZgXnff1cZDbG+xLtMVE5mDRTe+nIsX4=
 google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
@@ -700,7 +683,6 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ
 google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
 google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
 google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
@@ -724,7 +706,6 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/runner/config.go b/runner/config.go
index 917c927..a320233 100644
--- a/runner/config.go
+++ b/runner/config.go
@@ -7,6 +7,8 @@ import (
 	"time"
 
 	"github.com/jinzhu/configor"
+
+	humanize "github.com/dustin/go-humanize"
 )
 
 // Duration is our duration with TOML support
@@ -112,6 +114,8 @@ type Config struct {
 	LoadStepDuration      Duration          `json:"load-step-duration" toml:"load-step-duration" yaml:"load-step-duration"`
 	LoadMaxDuration       Duration          `json:"load-max-duration" toml:"load-max-duration" yaml:"load-max-duration"`
 	LBStrategy            string            `json:"lb-strategy" toml:"lb-strategy" yaml:"lb-strategy"`
+	MaxCallRecvMsgSize    string            `json:"max-recv-message-size" toml:"max-recv-message-size" yaml:"max-recv-message-size"`
+	MaxCallSendMsgSize    string            `json:"max-send-message-size" toml:"max-send-message-size" yaml:"max-send-message-size"`
 }
 
 func checkData(data interface{}) error {
@@ -119,15 +123,15 @@ func checkData(data interface{}) error {
 	if !isObjData {
 		arrData, isArrData := data.([]interface{})
 		if !isArrData {
-			return errors.New("Unsupported type for Data")
+			return errors.New("unsupported type for Data")
 		}
 		if len(arrData) == 0 {
-			return errors.New("Data array must not be empty")
+			return errors.New("data array must not be empty")
 		}
 		for _, elem := range arrData {
 			_, isObjData = elem.(map[string]interface{})
 			if !isObjData {
-				return errors.New("Data array contains unsupported type")
+				return errors.New("data array contains unsupported type")
 			}
 		}
 
@@ -152,7 +156,7 @@ func LoadConfig(p string, c *Config) error {
 				for k, v := range objData {
 					sk, isString := k.(string)
 					if !isString {
-						return errors.New("Data key must string")
+						return errors.New("data key must string")
 					}
 					if len(sk) > 0 {
 						nd[sk] = v
@@ -174,5 +178,19 @@ func LoadConfig(p string, c *Config) error {
 		c.ZStop = "close"
 	}
 
+	if c.MaxCallRecvMsgSize != "" {
+		_, err = humanize.ParseBytes(c.MaxCallRecvMsgSize)
+		if err != nil {
+			return errors.New("invalid max call recv message size: " + err.Error())
+		}
+	}
+
+	if c.MaxCallSendMsgSize != "" {
+		_, err = humanize.ParseBytes(c.MaxCallSendMsgSize)
+		if err != nil {
+			return errors.New("invalid max call send message size: " + err.Error())
+		}
+	}
+
 	return nil
 }
diff --git a/runner/options.go b/runner/options.go
index 9fb08eb..9892ac2 100644
--- a/runner/options.go
+++ b/runner/options.go
@@ -18,7 +18,10 @@ import (
 	"github.com/bojand/ghz/load"
 	"github.com/jhump/protoreflect/desc"
 	"github.com/pkg/errors"
+	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
+
+	humanize "github.com/dustin/go-humanize"
 )
 
 // BinaryDataFunc is a function that can be used for provide binary data for request programatically.
@@ -38,13 +41,14 @@ const ScheduleLine = "line"
 // RunConfig represents the request Configs
 type RunConfig struct {
 	// call settings
-	call              string
-	host              string
-	proto             string
-	importPaths       []string
-	protoset          string
-	protosetBinary    []byte
-	enableCompression bool
+	call               string
+	host               string
+	proto              string
+	importPaths        []string
+	protoset           string
+	protosetBinary     []byte
+	enableCompression  bool
+	defaultCallOptions []grpc.CallOption
 
 	// security settings
 	creds      credentials.TransportCredentials
@@ -1044,6 +1048,15 @@ func WithStreamMessageProvider(fn StreamMessageProviderFunc) Option {
 	}
 }
 
+// WithDefaultCallOptions sets the default CallOptions for calls over the connection.
+func WithDefaultCallOptions(opts []grpc.CallOption) Option {
+	return func(o *RunConfig) error {
+		o.defaultCallOptions = opts
+
+		return nil
+	}
+}
+
 func createClientTransportCredentials(skipVerify bool, cacertFile, clientCertFile, clientKeyFile, cname string) (credentials.TransportCredentials, error) {
 	var tlsConf tls.Config
 
@@ -1146,6 +1159,29 @@ func fromConfig(cfg *Config) []Option {
 		},
 	)
 
+	var defaultCallOptions []grpc.CallOption
+	if cfg.MaxCallRecvMsgSize != "" {
+		v, err := humanize.ParseBytes(cfg.MaxCallRecvMsgSize)
+		if err != nil {
+			return nil
+		}
+
+		defaultCallOptions = append(defaultCallOptions, grpc.MaxCallRecvMsgSize(int(v)))
+	}
+
+	if cfg.MaxCallSendMsgSize != "" {
+		v, err := humanize.ParseBytes(cfg.MaxCallSendMsgSize)
+		if err != nil {
+			return nil
+		}
+
+		defaultCallOptions = append(defaultCallOptions, grpc.MaxCallSendMsgSize(int(v)))
+	}
+
+	if len(defaultCallOptions) > 0 {
+		options = append(options, WithDefaultCallOptions(defaultCallOptions))
+	}
+
 	if strings.TrimSpace(cfg.MetadataPath) != "" {
 		options = append(options, WithMetadataFromFile(strings.TrimSpace(cfg.MetadataPath)))
 	}
diff --git a/runner/requester.go b/runner/requester.go
index 8175d95..5d820d4 100644
--- a/runner/requester.go
+++ b/runner/requester.go
@@ -298,6 +298,18 @@ func (b *Requester) newClientConn(withStatsHandler bool) (*grpc.ClientConn, erro
 		opts = append(opts, grpc.WithAuthority(b.config.authority))
 	}
 
+	if len(b.config.defaultCallOptions) > 0 {
+		opts = append(opts, grpc.WithDefaultCallOptions(b.config.defaultCallOptions...))
+	} else {
+		// increase max receive and send message sizes
+		opts = append(opts,
+			grpc.WithDefaultCallOptions(
+				grpc.MaxCallRecvMsgSize(math.MaxInt32),
+				grpc.MaxCallSendMsgSize(math.MaxInt32),
+			))
+
+	}
+
 	ctx := context.Background()
 	ctx, _ = context.WithTimeout(ctx, b.config.dialTimeout)
 	// cancel is ignored here as connection.Close() is used.
@@ -327,13 +339,6 @@ func (b *Requester) newClientConn(withStatsHandler bool) (*grpc.ClientConn, erro
 		b.config.log.Debugw("Creating client connection", "options", opts)
 	}
 
-	// increase max receive and send message sizes
-	opts = append(opts,
-		grpc.WithDefaultCallOptions(
-			grpc.MaxCallRecvMsgSize(math.MaxInt32),
-			grpc.MaxCallSendMsgSize(math.MaxInt32),
-		))
-
 	if b.config.lbStrategy != "" {
 		opts = append(opts, grpc.WithBalancerName(b.config.lbStrategy))
 	}
diff --git a/www/docs/options.md b/www/docs/options.md
index 011ad6e..3a847a4 100644
--- a/www/docs/options.md
+++ b/www/docs/options.md
@@ -309,6 +309,14 @@ Results in the following data sent:
 
 Reflect metadata as stringified JSON used only for reflection request.
 
+### `--max-recv-message-size`
+
+Maximum message size the client can receive. Can be specified as bytes, or using [human readable value](https://pkg.go.dev/github.com/dustin/go-humanize#ParseBytes) such as `42 MB`.
+
+### `--max-send-message-size`
+
+Maximum message size the client can send. Can be specified as bytes, or using [human readable value](https://pkg.go.dev/github.com/dustin/go-humanize#ParseBytes) such as `42 MB`.
+
 ### `-o`, `--output`
 
 Output path. If none is provided by default we print to standard output (stdout).


Test patch:
diff --git a/runner/config_test.go b/runner/config_test.go
index 5a76c91..6743f39 100644
--- a/runner/config_test.go
+++ b/runner/config_test.go
@@ -59,14 +59,21 @@ func TestConfig_Load(t *testing.T) {
 				Data: map[string]interface{}{
 					"f_strings": []interface{}{"123", "456"},
 				},
-				Format:       "summary",
-				DialTimeout:  Duration(10 * time.Second),
-				LoadSchedule: "const",
-				CSchedule:    "const",
-				CStart:       1,
+				Format:             "summary",
+				DialTimeout:        Duration(10 * time.Second),
+				LoadSchedule:       "const",
+				CSchedule:          "const",
+				CStart:             1,
+				MaxCallRecvMsgSize: "1024mb",
+				MaxCallSendMsgSize: "2000mib",
 			},
 			true,
 		},
+		{
+			"invalid message size",
+			&Config{},
+			false,
+		},
 	}
 
 	for i, tt := range tests {
diff --git a/runner/options_test.go b/runner/options_test.go
index a9b21b8..fb5a3aa 100644
--- a/runner/options_test.go
+++ b/runner/options_test.go
@@ -10,6 +10,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
 )
 
 func TestRunConfig_newRunConfig(t *testing.T) {
@@ -496,6 +497,25 @@ func TestRunConfig_newRunConfig(t *testing.T) {
 		assert.Error(t, err)
 	})
 
+	t.Run("with max size", func(t *testing.T) {
+		c, err := NewConfig("  call  ", "  localhost:50050  ",
+			WithProtoFile("testdata/data.proto", []string{}),
+			WithDefaultCallOptions(
+				[]grpc.CallOption{
+					grpc.MaxCallSendMsgSize(1024000),
+					grpc.MaxCallRecvMsgSize(2048000),
+				},
+			),
+		)
+
+		assert.NoError(t, err)
+
+		assert.Equal(t, []grpc.CallOption{
+			grpc.MaxCallSendMsgSize(1024000),
+			grpc.MaxCallRecvMsgSize(2048000),
+		}, c.defaultCallOptions)
+	})
+
 	t.Run("with load step", func(t *testing.T) {
 		t.Run("no step", func(t *testing.T) {
 			_, err := NewConfig("  call  ", "  localhost:50050  ",
diff --git a/testdata/config/config5.json b/testdata/config/config5.json
index 960c6c0..33f87ef 100644
--- a/testdata/config/config5.json
+++ b/testdata/config/config5.json
@@ -6,10 +6,12 @@
     "proto": "grpcbin.proto",
     "call": "grpcbin.GRPCBin.DummyUnary",
     "host": "127.0.0.1:9000",
-    "duration":"20s",
-    "max-duration":"60s",
-    "stream-interval":"25s",
-    "timeout":"30s",
+    "duration": "20s",
+    "max-duration": "60s",
+    "stream-interval": "25s",
+    "timeout": "30s",
+    "max-recv-message-size": "1024mb",
+    "max-send-message-size": "2000mib",
     "data": {
         "f_strings": [
             "123",
diff --git a/testdata/config/config5.toml b/testdata/config/config5.toml
index 8d5c474..fb103af 100644
--- a/testdata/config/config5.toml
+++ b/testdata/config/config5.toml
@@ -9,6 +9,8 @@ duration = "20s"
 max-duration = "60s"
 stream-interval = "25s"
 timeout = "30s"
+max-recv-message-size = "1024mb"
+max-send-message-size = "2000mib"
 
 [data]
 f_strings = [
diff --git a/testdata/config/config5.yaml b/testdata/config/config5.yaml
index 96a2c5c..8c7a299 100644
--- a/testdata/config/config5.yaml
+++ b/testdata/config/config5.yaml
@@ -9,6 +9,8 @@ duration: 20s
 max-duration: 60s
 stream-interval: 25s
 timeout: 30s
+max-recv-message-size: "1024mb"
+max-send-message-size: "2000mib"
 data:
   f_strings:
   - '123'
diff --git a/testdata/config/config6.json b/testdata/config/config6.json
new file mode 100644
index 0000000..5629ef8
--- /dev/null
+++ b/testdata/config/config6.json
@@ -0,0 +1,21 @@
+{
+    "insecure": true,
+    "import-paths": [
+        "/home/user/pb/grpcbin"
+    ],
+    "proto": "grpcbin.proto",
+    "call": "grpcbin.GRPCBin.DummyUnary",
+    "host": "127.0.0.1:9000",
+    "duration": "20s",
+    "max-duration": "60s",
+    "stream-interval": "25s",
+    "timeout": "30s",
+    "max-recv-message-size": "1024nb",
+    "max-send-message-size": "2000nib",
+    "data": {
+        "f_strings": [
+            "123",
+            "456"
+        ]
+    }
+}
\ No newline at end of file
diff --git a/testdata/config/config6.toml b/testdata/config/config6.toml
new file mode 100644
index 0000000..2ccf8a8
--- /dev/null
+++ b/testdata/config/config6.toml
@@ -0,0 +1,19 @@
+insecure = true
+import-paths = [
+  "/home/user/pb/grpcbin"
+]
+proto = "grpcbin.proto"
+call = "grpcbin.GRPCBin.DummyUnary"
+host = "127.0.0.1:9000"
+duration = "20s"
+max-duration = "60s"
+stream-interval = "25s"
+timeout = "30s"
+max-recv-message-size = "1024nb"
+max-send-message-size = "2000nib"
+
+[data]
+f_strings = [
+  "123",
+  "456"
+]
\ No newline at end of file
diff --git a/testdata/config/config6.yaml b/testdata/config/config6.yaml
new file mode 100644
index 0000000..7075341
--- /dev/null
+++ b/testdata/config/config6.yaml
@@ -0,0 +1,17 @@
+---
+insecure: true
+import-paths:
+- "/home/user/pb/grpcbin"
+proto: grpcbin.proto
+call: grpcbin.GRPCBin.DummyUnary
+host: 127.0.0.1:9000
+duration: 20s
+max-duration: 60s
+stream-interval: 25s
+timeout: 30s
+max-recv-message-size: "1024nb"
+max-send-message-size: "2000nib"
+data:
+  f_strings:
+  - '123'
+  - '456'