Repository: bojand/ghz (go)

Issue:
Template to create randomNumber within some range
**Is your feature request related to a problem? Please describe.**
Service currently accepts request where a field is a number and in a range(1 to N). While Sending million request the field is exceeding the given range.

**Describe the solution you'd like**
Create a randomNumber template which accepts range or at least and end number. 

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


Pull request:
Add random int template function to call data
Fixes #260. 

Patch:
diff --git a/runner/calldata.go b/runner/calldata.go
index bda1050..097079a 100644
--- a/runner/calldata.go
+++ b/runner/calldata.go
@@ -41,6 +41,7 @@ type CallData struct {
 var tmplFuncMap = template.FuncMap{
 	"newUUID":      newUUID,
 	"randomString": randomString,
+	"randomInt":    randomInt,
 }
 
 // newCallData returns new CallData
@@ -208,3 +209,15 @@ func randomString(length int) string {
 
 	return stringWithCharset(length, charset)
 }
+
+func randomInt(min, max int) int {
+	if min < 0 {
+		min = 0
+	}
+
+	if max <= 0 {
+		max = 1
+	}
+
+	return seededRand.Intn(max-min) + min
+}
diff --git a/www/docs/calldata.md b/www/docs/calldata.md
index 9c1e324..351c3d1 100644
--- a/www/docs/calldata.md
+++ b/www/docs/calldata.md
@@ -55,11 +55,17 @@ type CallData struct {
 
 **Template Functions**
 
-There are also two template functions available:
+There are also template functions available:
 
-`newUUID` - Generates a new UUID for each invocation.
+`func newUUID() string`  
+Generates a new UUID for each invocation.
+
+`func randomString(length int) string`  
+Generates a new random string for each incovation. Accepts a length parameter. If the argument is `<= 0` then a ranom string is generated with a random length between length of `2` and `16`.
+
+`func randomInt(min, max int) int`  
+Generates a new non-negative pseudo-random number in range `[min, max)`.
 
-`randomString` - Generates a new random string for each incovation. Accepts a length parameter. If the argument is `<= 0` then a ranom string is generated with a random length between length of `2` and `16`.
 
 **Examples**
 


Test patch:
diff --git a/runner/calldata_test.go b/runner/calldata_test.go
index f104883..4740879 100644
--- a/runner/calldata_test.go
+++ b/runner/calldata_test.go
@@ -1,6 +1,7 @@
 package runner
 
 import (
+	"strconv"
 	"strings"
 	"testing"
 	"text/template"
@@ -249,6 +250,44 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) {
 		assert.NotEqual(t, rm["trace_id"], rm["span_id"])
 	})
 
+	t.Run("randomInt", func(t *testing.T) {
+		ctd := newCallData(md, nil, "worker_id_123", 200)
+		assert.NotNil(t, ctd)
+
+		// no template
+		r, err := ctd.ExecuteData(`{"trace_id":"asdf"}`)
+		assert.NoError(t, err)
+		assert.Equal(t, `{"trace_id":"asdf"}`, string(r))
+
+		rm, err := ctd.executeMetadata(`{"trace_id":"asdf"}`)
+		assert.NoError(t, err)
+		assert.Equal(t, map[string]string{"trace_id": "asdf"}, rm)
+
+		// 0 when 0
+		r, err = ctd.ExecuteData(`{"trace_id":"{{randomInt 0 0}}"}`)
+		assert.NoError(t, err)
+		assert.Equal(t, `{"trace_id":"0"}`, string(r))
+
+		// 0 when min -1
+		r, err = ctd.ExecuteData(`{"trace_id":"{{randomInt -1 1}}"}`)
+		assert.NoError(t, err)
+		assert.Equal(t, `{"trace_id":"0"}`, string(r))
+
+		// 0 when max -1
+		r, err = ctd.ExecuteData(`{"trace_id":"{{randomInt 0 -1}}"}`)
+		assert.NoError(t, err)
+		assert.Equal(t, `{"trace_id":"0"}`, string(r))
+
+		// specific range
+		r, err = ctd.ExecuteData(`{"trace_id":"{{randomInt 4 10}}"}`)
+		assert.NoError(t, err)
+		rs := strings.Replace(string(r), `{"trace_id":"`, "", -1)
+		rs = strings.Replace(rs, `"}`, "", -1)
+		n, err := strconv.Atoi(rs)
+		assert.NoError(t, err)
+		assert.True(t, 4 <= n && n < 10)
+	})
+
 	t.Run("custom functions", func(t *testing.T) {
 
 		ctd := newCallData(md, nil, "worker_id_123", 200)