diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a233ee01..70a4e2db 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -31,13 +31,13 @@ jobs: runs-on: ubuntu-latest env: GO111MODULE: on - GOLANGCI_LINT_VERSION: v1.46.2 + GOLANGCI_LINT_VERSION: v1.49.0 steps: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 id: go - name: Check out code uses: actions/checkout@v3 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index fe565b4a..2677a5f3 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -32,7 +32,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v3 with: - go-version: 1.18 + go-version: 1.19 - name: Get current time uses: gerred/actions/current-time@master diff --git a/.golangci.yml b/.golangci.yml index 0d226779..f5279a1c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -11,11 +11,11 @@ issues: # Since we purposefully do that. See comments in code. - path: runner/requester.go text: "lostcancel" - + # TODO Look into fixing time.Tick() usage SA1015 in worker.go - path: runner/worker.go text: "SA1015" - + # We intentionally assign nil to err - path: runner/worker.go text: "ineffectual assignment to `err`" @@ -30,13 +30,12 @@ issues: # TODO fix protobuf deprecated - path: runner/ - text: "SA1019: package github.com/golang/protobuf" - + text: 'SA1019: "github.com/golang/protobuf/proto"' + # TODO fix protobuf deprecated - path: protodesc/ - text: "SA1019: package github.com/golang/protobuf" + text: 'SA1019: "github.com/golang/protobuf/proto"' # TODO fix protobuf deprecated - path: runner/ - text: "SA1019: \"github.com/golang/protobuf/jsonpb\" is deprecated" - + text: 'SA1019: "github.com/golang/protobuf/jsonpb" is deprecated' diff --git a/cmd/ghz/main.go b/cmd/ghz/main.go index e1c48fdd..f6fa94b7 100644 --- a/cmd/ghz/main.go +++ b/cmd/ghz/main.go @@ -266,6 +266,14 @@ var ( maxSendMsgSize = kingpin.Flag("max-send-message-size", "Maximum message size the client can send."). PlaceHolder(" ").IsSetByUser(&isMaxSendMsgSizeSet).String() + isDisableTemplateFuncsSet = false + disableTemplateFuncs = kingpin.Flag("disable-template-functions", "Do not use and execute any template functions in call template data. Useful for better performance"). + Default("false").IsSetByUser(&isDisableTemplateFuncsSet).Bool() + + isDisableTemplateDataSet = false + disableTemplateData = kingpin.Flag("disable-template-data", "Do not use and execute any call template data. Useful for better performance."). + Default("false").IsSetByUser(&isDisableTemplateDataSet).Bool() + // host main argument isHostSet = false host = kingpin.Arg("host", "Host and port to test.").String() @@ -507,6 +515,8 @@ func createConfigFromArgs(cfg *runner.Config) error { cfg.LBStrategy = *lbStrategy cfg.MaxCallRecvMsgSize = *maxRecvMsgSize cfg.MaxCallSendMsgSize = *maxSendMsgSize + cfg.DisableTemplateFuncs = *disableTemplateFuncs + cfg.DisableTemplateData = *disableTemplateData return nil } @@ -760,6 +770,16 @@ func mergeConfig(dest *runner.Config, src *runner.Config) error { dest.MaxCallSendMsgSize = src.MaxCallSendMsgSize } + // call data template functions behavior + if isDisableTemplateFuncsSet { + dest.DisableTemplateFuncs = src.DisableTemplateFuncs + } + + // call data template behavior + if isDisableTemplateDataSet { + dest.DisableTemplateData = src.DisableTemplateData + } + return nil } diff --git a/runner/calldata.go b/runner/calldata.go index 06e69644..07b236ce 100644 --- a/runner/calldata.go +++ b/runner/calldata.go @@ -50,27 +50,32 @@ var tmplFuncMap = template.FuncMap{ "randomInt": randomInt, } -var commonTemplate *template.Template = template.New("call_template_data"). - Funcs(tmplFuncMap). - Funcs(template.FuncMap(sprigFuncMap)) - // newCallData returns new CallData func newCallData( mtd *desc.MethodDescriptor, - funcs template.FuncMap, - workerID string, reqNum int64) *CallData { + workerID string, reqNum int64, withFuncs, withTemplateData bool, funcs template.FuncMap) *CallData { + + var t *template.Template + if withTemplateData { + t = template.New("call_template_data") + + if withFuncs { + t = t. + Funcs(tmplFuncMap). + Funcs(template.FuncMap(sprigFuncMap)) - fns := make(template.FuncMap, len(funcs)) + if len(funcs) > 0 { + fns := make(template.FuncMap, len(funcs)) - if len(funcs) > 0 { - for k, v := range funcs { - fns[k] = v + for k, v := range funcs { + fns[k] = v + } + + t = t.Funcs(fns) + } } } - t, _ := commonTemplate.Clone() - t.Funcs(fns) - now := time.Now() newUUID, _ := uuid.NewRandom() @@ -119,6 +124,10 @@ func (td *CallData) Regenerate() *CallData { } func (td *CallData) execute(data string) (*bytes.Buffer, error) { + if td.t == nil { + return nil, nil + } + t, err := td.t.Parse(data) if err != nil { return nil, err @@ -134,6 +143,10 @@ func (td *CallData) execute(data string) (*bytes.Buffer, error) { // The *parse.Tree field is exported only for use by html/template // and should be treated as unexported by all other clients. func (td *CallData) hasAction(data string) (bool, error) { + if td.t == nil { + return false, nil + } + t, err := td.t.Parse(data) if err != nil { return false, err @@ -165,7 +178,7 @@ func (td *CallData) ExecuteData(data string) ([]byte, error) { if len(data) > 0 { input := []byte(data) tpl, err := td.execute(data) - if err == nil { + if err == nil && tpl != nil { input = tpl.Bytes() } @@ -181,7 +194,7 @@ func (td *CallData) executeMetadata(metadata string) (map[string]string, error) if len(metadata) > 0 { input := []byte(metadata) tpl, err := td.execute(metadata) - if err == nil { + if err == nil && tpl != nil { input = tpl.Bytes() } diff --git a/runner/calldata_test.go b/runner/calldata_test.go index d00ce9b4..b5404d8b 100644 --- a/runner/calldata_test.go +++ b/runner/calldata_test.go @@ -17,7 +17,7 @@ func TestCallData_New(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, md) - ctd := newCallData(md, nil, "worker_id_123", 100) + ctd := newCallData(md, "worker_id_123", 100, true, true, nil) assert.NotNil(t, ctd) assert.Equal(t, "worker_id_123", ctd.WorkerID) @@ -73,7 +73,7 @@ func TestCallData_ExecuteData(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) r, err := ctd.ExecuteData(tt.in) @@ -124,7 +124,7 @@ func TestCallData_ExecuteMetadata(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) r, err := ctd.executeMetadata(tt.in) @@ -146,7 +146,7 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) { t.Run("newUUID", func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) // no template @@ -194,7 +194,7 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) { }) t.Run("randomString", func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) // no template @@ -256,7 +256,7 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) { }) t.Run("randomInt", func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) // no template @@ -295,17 +295,17 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) { t.Run("custom functions", func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) - ctd = newCallData(md, template.FuncMap{ + ctd = newCallData(md, "worker_id_123", 200, true, true, template.FuncMap{ "getSKU": func() string { return "custom-sku" }, "newUUID": func() string { return "custom-uuid" }, - }, "worker_id_123", 200) + }) r, err := ctd.ExecuteData(`{"trace_id":"{{newUUID}}", "span_id":"{{getSKU}}"}`) assert.NoError(t, err) @@ -320,7 +320,7 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) { t.Run("sprig functions", func(t *testing.T) { - ctd := newCallData(md, nil, "worker_id_123", 200) + ctd := newCallData(md, "worker_id_123", 200, true, true, nil) assert.NotNil(t, ctd) r, err := ctd.ExecuteData(`{"trace_id":"{{add 1 2}}"}`) diff --git a/runner/config.go b/runner/config.go index a320233c..b2263375 100644 --- a/runner/config.go +++ b/runner/config.go @@ -116,6 +116,8 @@ type Config struct { 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"` + DisableTemplateFuncs bool `json:"disable-template-functions" toml:"disable-template-functions" yaml:"disable-template-functions"` + DisableTemplateData bool `json:"disable-template-data" toml:"disable-template-data" yaml:"disable-template-data"` } func checkData(data interface{}) error { diff --git a/runner/data.go b/runner/data.go index ece878da..68ac1337 100644 --- a/runner/data.go +++ b/runner/data.go @@ -65,7 +65,7 @@ type mdProvider struct { func newDataProvider(mtd *desc.MethodDescriptor, binary bool, dataFunc BinaryDataFunc, data []byte, - funcs template.FuncMap) (*dataProvider, error) { + withFuncs, withTemplateData bool, funcs template.FuncMap) (*dataProvider, error) { dp := dataProvider{ binary: binary, @@ -98,12 +98,15 @@ func newDataProvider(mtd *desc.MethodDescriptor, } // Test if we can preseed data - ctd := newCallData(mtd, funcs, "", 0) ha := false - if !dp.binary { - ha, err = ctd.hasAction(string(dp.data)) - if err != nil { - return nil, err + ctd := newCallData(mtd, "", 0, withFuncs, withTemplateData, funcs) + + if withTemplateData { + if !dp.binary { + ha, err = ctd.hasAction(string(dp.data)) + if err != nil { + return nil, err + } } } @@ -221,9 +224,9 @@ func (dp *dataProvider) getMessages(ctd *CallData, i int, inputData []byte) ([]* return inputs, nil } -func newMetadataProvider(mtd *desc.MethodDescriptor, mdData []byte, funcs template.FuncMap) (*mdProvider, error) { +func newMetadataProvider(mtd *desc.MethodDescriptor, mdData []byte, withFuncs, withTemplateData bool, funcs template.FuncMap) (*mdProvider, error) { // Test if we can preseed data - ctd := newCallData(mtd, funcs, "", 0) + ctd := newCallData(mtd, "", 0, withFuncs, withTemplateData, funcs) ha, err := ctd.hasAction(string(mdData)) if err != nil { return nil, err @@ -389,7 +392,7 @@ type dynamicMessageProvider struct { indexCounter uint } -func newDynamicMessageProvider(mtd *desc.MethodDescriptor, data []byte, streamCallCount uint) (*dynamicMessageProvider, error) { +func newDynamicMessageProvider(mtd *desc.MethodDescriptor, data []byte, streamCallCount uint, withFuncs, withTemplateData bool) (*dynamicMessageProvider, error) { mp := dynamicMessageProvider{ mtd: mtd, data: data, @@ -419,10 +422,14 @@ func newDynamicMessageProvider(mtd *desc.MethodDescriptor, data []byte, streamCa mp.arrayLen = uint(len(mp.arrayJSONData)) // Test if we have actions - ctd := newCallData(mtd, nil, "", 0) - ha, err := ctd.hasAction(string(mp.data)) - if err != nil { - return nil, err + ha := false + ctd := newCallData(mtd, "", 0, withFuncs, withTemplateData, nil) + + if withTemplateData { + ha, err = ctd.hasAction(string(mp.data)) + if err != nil { + return nil, err + } } if !ha { diff --git a/runner/data_test.go b/runner/data_test.go index 0995780a..463635ec 100644 --- a/runner/data_test.go +++ b/runner/data_test.go @@ -275,7 +275,7 @@ func TestMetadata_newMetadataProvider(t *testing.T) { nil) assert.NoError(t, err) - mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"asdf"}`), nil) + mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"asdf"}`), true, true, nil) assert.NoError(t, err) assert.NotNil(t, mdp) assert.NotNil(t, mdp.preseed) @@ -289,7 +289,7 @@ func TestMetadata_newMetadataProvider(t *testing.T) { nil) assert.NoError(t, err) - mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ .RequestNumber }}"}`), nil) + mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ .RequestNumber }}"}`), true, true, nil) assert.NoError(t, err) assert.NotNil(t, mdp) assert.Nil(t, mdp.preseed) @@ -304,11 +304,11 @@ func TestMetadata_getMetadataForCall(t *testing.T) { nil) assert.NoError(t, err) - mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"asdf"}`), nil) + mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"asdf"}`), true, true, nil) assert.NoError(t, err) assert.NotNil(t, mdp.preseed) - cd := newCallData(mtdUnary, nil, "123", 1) + cd := newCallData(mtdUnary, "123", 1, true, true, nil) md, err := mdp.getMetadataForCall(cd) assert.NoError(t, err) @@ -324,11 +324,11 @@ func TestMetadata_getMetadataForCall(t *testing.T) { nil) assert.NoError(t, err) - mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ .RequestNumber }}"}`), nil) + mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ .RequestNumber }}"}`), true, true, nil) assert.NoError(t, err) assert.Nil(t, mdp.preseed) - cd := newCallData(mtdUnary, nil, "123", 1) + cd := newCallData(mtdUnary, "123", 1, true, true, nil) md1, err := mdp.getMetadataForCall(cd) assert.NoError(t, err) @@ -336,7 +336,7 @@ func TestMetadata_getMetadataForCall(t *testing.T) { assert.Equal(t, []string{"1"}, md1.Get("token")) assert.NotSame(t, mdp.preseed, md1) - cd = newCallData(mtdUnary, nil, "123", 2) + cd = newCallData(mtdUnary, "123", 2, true, true, nil) md2, err := mdp.getMetadataForCall(cd) assert.NoError(t, err) assert.NotNil(t, md2) @@ -359,11 +359,11 @@ func TestMetadata_getMetadataForCall(t *testing.T) { }, } - mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ customFunc }}"}`), funcs) + mdp, err := newMetadataProvider(mtdUnary, []byte(`{"token":"{{ customFunc }}"}`), true, true, funcs) assert.NoError(t, err) assert.Nil(t, mdp.preseed) - cd := newCallData(mtdUnary, funcs, "123", 1) + cd := newCallData(mtdUnary, "123", 1, true, true, funcs) md1, err := mdp.getMetadataForCall(cd) assert.NoError(t, err) diff --git a/runner/options.go b/runner/options.go index 84271e2f..d2d39925 100644 --- a/runner/options.go +++ b/runner/options.go @@ -124,6 +124,10 @@ type RunConfig struct { hasLog bool log Logger + // template call data + disableTemplateFuncs bool + disableTemplateData bool + // misc name string cpus int @@ -1095,6 +1099,24 @@ func WithDefaultCallOptions(opts []grpc.CallOption) Option { } } +// WithDisableTemplateFuncs disables template functions in call data +func WithDisableTemplateFuncs(v bool) Option { + return func(o *RunConfig) error { + o.disableTemplateFuncs = v + + return nil + } +} + +// WithDisableTemplateData disables template data execution in call data +func WithDisableTemplateData(v bool) Option { + return func(o *RunConfig) error { + o.disableTemplateData = v + + return nil + } +} + func createClientTransportCredentials(skipVerify bool, cacertFile, clientCertFile, clientKeyFile, cname string) (credentials.TransportCredentials, error) { var tlsConf tls.Config @@ -1187,6 +1209,8 @@ func fromConfig(cfg *Config) []Option { WithConcurrencyStepDuration(time.Duration(cfg.CStepDuration)), WithConcurrencyDuration(time.Duration(cfg.CMaxDuration)), WithCountErrors(cfg.CountErrors), + WithDisableTemplateFuncs(cfg.DisableTemplateFuncs), + WithDisableTemplateData(cfg.DisableTemplateData), func(o *RunConfig) error { o.call = cfg.Call return nil diff --git a/runner/requester.go b/runner/requester.go index 54afe850..03763c5d 100644 --- a/runner/requester.go +++ b/runner/requester.go @@ -122,7 +122,7 @@ func NewRequester(c *RunConfig) (*Requester, error) { md := mtd.GetInputType() payloadMessage := dynamic.NewMessage(md) if payloadMessage == nil { - return nil, fmt.Errorf("No input type of method: %s", mtd.GetName()) + return nil, fmt.Errorf("no input type of method: %s", mtd.GetName()) } // fill in the rest @@ -131,7 +131,7 @@ func NewRequester(c *RunConfig) (*Requester, error) { if c.dataProviderFunc != nil { reqr.dataProvider = c.dataProviderFunc } else { - defaultDataProvider, err := newDataProvider(reqr.mtd, c.binary, c.dataFunc, c.data, c.funcs) + defaultDataProvider, err := newDataProvider(reqr.mtd, c.binary, c.dataFunc, c.data, !c.disableTemplateFuncs, !c.disableTemplateData, c.funcs) if err != nil { return nil, err } @@ -141,7 +141,7 @@ func NewRequester(c *RunConfig) (*Requester, error) { if c.mdProviderFunc != nil { reqr.metadataProvider = c.mdProviderFunc } else { - defaultMDProvider, err := newMetadataProvider(reqr.mtd, c.metadata, c.funcs) + defaultMDProvider, err := newMetadataProvider(reqr.mtd, c.metadata, !c.disableTemplateFuncs, !c.disableTemplateData, c.funcs) if err != nil { return nil, err } diff --git a/runner/run_test.go b/runner/run_test.go index b60f233d..33927dff 100644 --- a/runner/run_test.go +++ b/runner/run_test.go @@ -3,6 +3,7 @@ package runner import ( "fmt" "strconv" + "strings" "testing" "text/template" "time" @@ -217,6 +218,93 @@ func TestRunUnary(t *testing.T) { assert.NotEmpty(t, parsed) }) + t.Run("test disabled template functions", func(t *testing.T) { + gs.ResetCounters() + + data := make(map[string]interface{}) + data["name"] = "{{ newUUID }}" + + report, err := Run( + "helloworld.Greeter.SayHello", + internal.TestLocalhost, + WithProtoFile("../testdata/greeter.proto", []string{}), + WithTotalRequests(1), + WithConcurrency(1), + WithTimeout(time.Duration(20*time.Second)), + WithData(data), + WithInsecure(true), + WithDisableTemplateFuncs(true), + ) + + assert.Error(t, err) + assert.True(t, strings.Contains(err.Error(), `function "newUUID" not defined`)) + assert.Nil(t, report) + }) + + t.Run("test disabled template functions with data", func(t *testing.T) { + gs.ResetCounters() + + data := make(map[string]interface{}) + data["name"] = "{{ .RequestNumber }}" + + report, err := Run( + "helloworld.Greeter.SayHello", + internal.TestLocalhost, + WithProtoFile("../testdata/greeter.proto", []string{}), + WithTotalRequests(1), + WithConcurrency(1), + WithTimeout(time.Duration(20*time.Second)), + WithData(data), + WithInsecure(true), + WithDisableTemplateFuncs(true), + ) + + assert.NoError(t, err) + assert.NotNil(t, report) + + count := gs.GetCount(callType) + assert.Equal(t, 1, count) + + calls := gs.GetCalls(callType) + assert.NotNil(t, calls) + assert.Len(t, calls, 1) + + msg := calls[0][0] + assert.Equal(t, "0", msg.GetName()) + }) + + t.Run("test disabled template data", func(t *testing.T) { + gs.ResetCounters() + + data := make(map[string]interface{}) + data["name"] = "{{ .RequestNumber }}" + + report, err := Run( + "helloworld.Greeter.SayHello", + internal.TestLocalhost, + WithProtoFile("../testdata/greeter.proto", []string{}), + WithTotalRequests(1), + WithConcurrency(1), + WithTimeout(time.Duration(20*time.Second)), + WithData(data), + WithInsecure(true), + WithDisableTemplateData(true), + ) + + assert.NoError(t, err) + assert.NotNil(t, report) + + count := gs.GetCount(callType) + assert.Equal(t, 1, count) + + calls := gs.GetCalls(callType) + assert.NotNil(t, calls) + assert.Len(t, calls, 1) + + msg := calls[0][0] + assert.Equal(t, "{{ .RequestNumber }}", msg.GetName()) + }) + t.Run("test skip first N", func(t *testing.T) { gs.ResetCounters() diff --git a/runner/worker.go b/runner/worker.go index c3c7ccb1..6198b4df 100644 --- a/runner/worker.go +++ b/runner/worker.go @@ -80,7 +80,7 @@ func (w *Worker) Stop() { func (w *Worker) makeRequest(tv TickValue) error { reqNum := int64(tv.reqNumber) - ctd := newCallData(w.mtd, w.config.funcs, w.workerID, reqNum) + ctd := newCallData(w.mtd, w.workerID, reqNum, !w.config.disableTemplateFuncs, !w.config.disableTemplateData, w.config.funcs) reqMD, err := w.metadataProvider(ctd) if err != nil { @@ -116,7 +116,7 @@ func (w *Worker) makeRequest(tv TickValue) error { msgProvider = w.msgProvider } else if w.mtd.IsClientStreaming() { if w.config.streamDynamicMessages { - mp, err := newDynamicMessageProvider(w.mtd, w.config.data, w.config.streamCallCount) + mp, err := newDynamicMessageProvider(w.mtd, w.config.data, w.config.streamCallCount, !w.config.disableTemplateFuncs, !w.config.disableTemplateData) if err != nil { return err } diff --git a/www/docs/calldata.md b/www/docs/calldata.md index 3165f462..b9509776 100644 --- a/www/docs/calldata.md +++ b/www/docs/calldata.md @@ -123,3 +123,9 @@ report, err := runner.Run( runner.WithBinaryDataFunc(dataFunc), ) ``` + +### Disabling + +Execution of call template functions can be done by setting `--disable-template-functions` to `true` or by using `WithDisableTemplateFuncs(true)`. + +Execution of call data template can be disabled completely by setting `--disable-template-data` to `true` or by using `WithDisableTemplateData(true)`. diff --git a/www/docs/options.md b/www/docs/options.md index e0b6bdc5..ea5f0502 100644 --- a/www/docs/options.md +++ b/www/docs/options.md @@ -390,6 +390,14 @@ Client load balancing strategy. For example: `--lb-strategy "round_robin"` By default stats for fastest, slowest, average, histogram, and latency distributions only take into account the responses with OK status. This option enabled counting of erroneous (non-OK) responses in stats calculations as well. +### `--disable-template-functions` + +Disable execution of template functions within call data and metadata. This can be useful for some performance improvements. Note that if template functions are used within data with this option set to `true`, it will result in an error. If `--disable-template-data` is set to `true` this is automatically also set to `true`. + +### `--disable-template-data` + +Disable execution of templates within call data and metadata. This can be useful for some performance improvements. This automatically also sets `disable-template-functions` to `true`. + ### `-v`, `--version` Print the version.