Skip to content

Commit

Permalink
Enhancement add modulo func to sync template (#488)
Browse files Browse the repository at this point in the history
* enhancement add modulo function to sync template
  • Loading branch information
pawel-fobka authored Aug 5, 2024
1 parent a3c3c9e commit 19c83de
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 3 deletions.
30 changes: 30 additions & 0 deletions docs/settingup.md
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,7 @@ The following functions are supported:
* `env`: Retrieve a specific environment variable. Takes one argument - the name of the environment variable to expand.
* `add`: Adds two integer values together and outputs the sum. E.g. `{{ add 1 2 }}`.
* `join`: Joins array elements together to a string separated by defined separator. E.g. `{{ join .ScriptVars.MyArray \",\" }}`.
* `modulo`: Returns modulo of two integer values and output the result. E.g. `{{ modulo 10 4 }}` (will return 2)

### Example

Expand Down Expand Up @@ -2499,6 +2500,35 @@ The following functions are supported:
}
```

Let's assume the case there are 4 apps to be used in the test, all ending with number 0 to 3. The use of modulo in the example will cycle through the app suffix number in following order: 1, 2, 3, 0.

```json
{
"action": "elastictriggersubscription",
"label": "trigger reporting task",
"settings": {
"subscriptiontype": "template-sharing",
"limitperpage": 100,
"appname": "PS-18566_Test_Levels_Pages- {{ modulo .Session 4}}",
"subscriptionmode": "random",
}
}
```

Very similar case as above but apps have number suffix from 1 to 4. This can be handled combining `modulo` and `add` functions. The cycle through the suffix number will be done in following order: 2, 3, 4, 1.
```json
{
"action": "elastictriggersubscription",
"label": "trigger reporting task",
"settings": {
"subscriptiontype": "template-sharing",
"limitperpage": 100,
"appname": "PS-18566_Test_Levels_Pages- {{ modulo .Session 4 | add 1 }}",
"subscriptionmode": "random",
}
}
```

</details>


Expand Down
30 changes: 30 additions & 0 deletions generatedocs/data/extra/sessionvariables/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The following functions are supported:
* `env`: Retrieve a specific environment variable. Takes one argument - the name of the environment variable to expand.
* `add`: Adds two integer values together and outputs the sum. E.g. `{{ add 1 2 }}`.
* `join`: Joins array elements together to a string separated by defined separator. E.g. `{{ join .ScriptVars.MyArray \",\" }}`.
* `modulo`: Returns modulo of two integer values and output the result. E.g. `{{ modulo 10 4 }}` (will return 2)

### Example

Expand Down Expand Up @@ -96,4 +97,33 @@ The following functions are supported:
}
```

Let's assume the case there are 4 apps to be used in the test, all ending with number 0 to 3. The use of modulo in the example will cycle through the app suffix number in following order: 1, 2, 3, 0.

```json
{
"action": "elastictriggersubscription",
"label": "trigger reporting task",
"settings": {
"subscriptiontype": "template-sharing",
"limitperpage": 100,
"appname": "PS-18566_Test_Levels_Pages- {{ modulo .Session 4}}",
"subscriptionmode": "random",
}
}
```

Very similar case as above but apps have number suffix from 1 to 4. This can be handled combining `modulo` and `add` functions. The cycle through the suffix number will be done in following order: 2, 3, 4, 1.
```json
{
"action": "elastictriggersubscription",
"label": "trigger reporting task",
"settings": {
"subscriptiontype": "template-sharing",
"limitperpage": 100,
"appname": "PS-18566_Test_Levels_Pages- {{ modulo .Session 4 | add 1 }}",
"subscriptionmode": "random",
}
}
```

</details>
2 changes: 1 addition & 1 deletion generatedocs/generated/documentation.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ var (

Extra = map[string]common.DocEntry{
"sessionvariables": {
Description: "\n## Session variables\n\nThis section describes the session variables that can be used with some of the actions.\n\n<details>\n<summary><a name=\"session_variables\"></a>Session variables</summary>\n\nSome action parameters support session variables. A session variable is defined by putting the variable, prefixed by a dot, within double curly brackets, such as `{{.UserName}}`.\n\nThe following session variables are supported in actions:\n\n* `UserName`: The simulated username. This is not the same as the authenticated user, but rather how the username was defined by [Login settings](#login_settings). \n* `Session`: The enumeration of the currently simulated session.\n* `Thread`: The enumeration of the currently simulated \"thread\" or \"concurrent user\".\n* `ScriptVars`: A map containing script variables added by the action `setscriptvar`.\n* `Artifacts`:\n * `GetIDByTypeAndName`: A function that accepts the two string arguments,\n `artifactType` and `artifactName`, and returns the resource id of the artifact.\n * `GetNameByTypeAndID`: A function that accepts the two string arguments,\n `artifactType` and `artifactID`, and returns the name of the artifact.\n\n\nThe following variable is supported in the filename of the log file:\n\n* `ConfigFile`: The filename of the config file, without file extension.\n\nThe following functions are supported:\n\n* `now`: Evaluates Golang [time.Now()](https://golang.org/pkg/time/). \n* `hostname`: Hostname of the local machine.\n* `timestamp`: Timestamp in `yyyyMMddhhmmss` format.\n* `uuid`: Generate an uuid.\n* `env`: Retrieve a specific environment variable. Takes one argument - the name of the environment variable to expand.\n* `add`: Adds two integer values together and outputs the sum. E.g. `{{ add 1 2 }}`.\n* `join`: Joins array elements together to a string separated by defined separator. E.g. `{{ join .ScriptVars.MyArray \\\",\\\" }}`.\n\n### Example\n\n```json\n{\n \"label\" : \"Create bookmark\",\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})\",\n \"description\": \"This bookmark contains some interesting selections\"\n }\n},\n{\n \"label\" : \"Publish created bookmark\",\n \"action\": \"publishbookmark\",\n \"disabled\" : false,\n \"settings\" : {\n \"title\": \"my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})\",\n }\n}\n\n```\n\n```json\n{\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"{{env \\\"TITLE\\\"}}\",\n \"description\": \"This bookmark contains some interesting selections\"\n }\n}\n```\n\n```json\n{\n \"action\": \"setscriptvar\",\n \"settings\": {\n \"name\": \"BookmarkCounter\",\n \"type\": \"int\",\n \"value\": \"1\"\n }\n},\n{\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"Bookmark no {{ add .ScriptVars.BookmarkCounter 1 }}\",\n \"description\": \"This bookmark will have the title Bookmark no 2\"\n }\n}\n```\n\n```json\n{\n \"action\": \"setscriptvar\",\n \"settings\": {\n \"name\": \"MyAppId\",\n \"type\": \"string\",\n \"value\": \"{{.Artifacts.GetIDByTypeAndName \\\"app\\\" (print \\\"an-app-\\\" .Session)}}\"\n }\n}\n```\n\n</details>\n",
Description: "\n## Session variables\n\nThis section describes the session variables that can be used with some of the actions.\n\n<details>\n<summary><a name=\"session_variables\"></a>Session variables</summary>\n\nSome action parameters support session variables. A session variable is defined by putting the variable, prefixed by a dot, within double curly brackets, such as `{{.UserName}}`.\n\nThe following session variables are supported in actions:\n\n* `UserName`: The simulated username. This is not the same as the authenticated user, but rather how the username was defined by [Login settings](#login_settings). \n* `Session`: The enumeration of the currently simulated session.\n* `Thread`: The enumeration of the currently simulated \"thread\" or \"concurrent user\".\n* `ScriptVars`: A map containing script variables added by the action `setscriptvar`.\n* `Artifacts`:\n * `GetIDByTypeAndName`: A function that accepts the two string arguments,\n `artifactType` and `artifactName`, and returns the resource id of the artifact.\n * `GetNameByTypeAndID`: A function that accepts the two string arguments,\n `artifactType` and `artifactID`, and returns the name of the artifact.\n\n\nThe following variable is supported in the filename of the log file:\n\n* `ConfigFile`: The filename of the config file, without file extension.\n\nThe following functions are supported:\n\n* `now`: Evaluates Golang [time.Now()](https://golang.org/pkg/time/). \n* `hostname`: Hostname of the local machine.\n* `timestamp`: Timestamp in `yyyyMMddhhmmss` format.\n* `uuid`: Generate an uuid.\n* `env`: Retrieve a specific environment variable. Takes one argument - the name of the environment variable to expand.\n* `add`: Adds two integer values together and outputs the sum. E.g. `{{ add 1 2 }}`.\n* `join`: Joins array elements together to a string separated by defined separator. E.g. `{{ join .ScriptVars.MyArray \\\",\\\" }}`.\n* `modulo`: Returns modulo of two integer values and output the result. E.g. `{{ modulo 10 4 }}` (will return 2)\n\n### Example\n\n```json\n{\n \"label\" : \"Create bookmark\",\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})\",\n \"description\": \"This bookmark contains some interesting selections\"\n }\n},\n{\n \"label\" : \"Publish created bookmark\",\n \"action\": \"publishbookmark\",\n \"disabled\" : false,\n \"settings\" : {\n \"title\": \"my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})\",\n }\n}\n\n```\n\n```json\n{\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"{{env \\\"TITLE\\\"}}\",\n \"description\": \"This bookmark contains some interesting selections\"\n }\n}\n```\n\n```json\n{\n \"action\": \"setscriptvar\",\n \"settings\": {\n \"name\": \"BookmarkCounter\",\n \"type\": \"int\",\n \"value\": \"1\"\n }\n},\n{\n \"action\": \"createbookmark\",\n \"settings\": {\n \"title\": \"Bookmark no {{ add .ScriptVars.BookmarkCounter 1 }}\",\n \"description\": \"This bookmark will have the title Bookmark no 2\"\n }\n}\n```\n\n```json\n{\n \"action\": \"setscriptvar\",\n \"settings\": {\n \"name\": \"MyAppId\",\n \"type\": \"string\",\n \"value\": \"{{.Artifacts.GetIDByTypeAndName \\\"app\\\" (print \\\"an-app-\\\" .Session)}}\"\n }\n}\n```\n\nLet's assume the case there are 4 apps to be used in the test, all ending with number 0 to 3. The use of modulo in the example will cycle through the app suffix number in following order: 1, 2, 3, 0.\n\n```json\n{\n \"action\": \"elastictriggersubscription\",\n \"label\": \"trigger reporting task\",\n \"settings\": {\n \"subscriptiontype\": \"template-sharing\",\n \"limitperpage\": 100,\n \"appname\": \"PS-18566_Test_Levels_Pages- {{ modulo .Session 4}}\",\n \"subscriptionmode\": \"random\",\n }\n}\n```\n\nVery similar case as above but apps have number suffix from 1 to 4. This can be handled combining `modulo` and `add` functions. The cycle through the suffix number will be done in following order: 2, 3, 4, 1.\n```json\n{\n \"action\": \"elastictriggersubscription\",\n \"label\": \"trigger reporting task\",\n \"settings\": {\n \"subscriptiontype\": \"template-sharing\",\n \"limitperpage\": 100,\n \"appname\": \"PS-18566_Test_Levels_Pages- {{ modulo .Session 4 | add 1 }}\",\n \"subscriptionmode\": \"random\",\n }\n}\n```\n\n</details>\n",
Examples: "",
},
}
Expand Down
14 changes: 14 additions & 0 deletions synced/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var (
"env": os.Getenv,
"add": add,
"join": strings.Join,
"modulo": modulo,
}
)

Expand Down Expand Up @@ -142,6 +143,19 @@ func add(iVal1 interface{}, iVal2 interface{}) (int64, error) {
return val1 + val2, nil
}

func modulo(iVal1 interface{}, iVal2 interface{}) (int64, error) {
val1, err := parseToInt64(iVal1)
if err != nil {
return 0, err
}
val2, err := parseToInt64(iVal2)
if err != nil {
return 0, err
}

return val1 % val2, nil
}

func parseToInt64(val interface{}) (int64, error) {
switch val := val.(type) {
case string:
Expand Down
5 changes: 4 additions & 1 deletion synced/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func TestTemplate(t *testing.T) {
Param2 Template `json:"param2"`
Param3 Template `json:"param3"`
Param4 Template `json:"param4"`
Param5 Template `json:"param5"`
}

_ = os.Setenv("test-env", "val2")
Expand All @@ -64,7 +65,8 @@ func TestTemplate(t *testing.T) {
"param1" : "val1 is {{.Val1}} and val2 is {{env \"test-env\"}}",
"param2" : "{{ add 1 \"3\" }}",
"param3" : "{{ join .Val2 \",\" }},elem4",
"param4" : "{{ join (slice .Val2 0 (add (len .Val2) -1)) \",\" }}"
"param4" : "{{ join (slice .Val2 0 (add (len .Val2) -1)) \",\" }}",
"param5" : "{{ modulo 10 \"4\" }}"
}`

if err := json.Unmarshal([]byte(jsn), &myStruct); err != nil {
Expand All @@ -75,6 +77,7 @@ func TestTemplate(t *testing.T) {
testParam(t, &myStruct.Param2, "4")
testParam(t, &myStruct.Param3, "elem1,elem2,elem3,elem4")
testParam(t, &myStruct.Param4, "elem1,elem2")
testParam(t, &myStruct.Param5, "2")
}

func testParam(t *testing.T, tmpl *Template, expected string) {
Expand Down
4 changes: 3 additions & 1 deletion synced/templatemap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ func TestMap(t *testing.T) {
"param1" : "val1 is {{.Val1}} and val2 is {{env \"test-env\"}}",
"param2" : "{{ add 1 \"3\" }}",
"param3" : "{{ join .Val2 \",\" }},elem4",
"param4" : "{{ join (slice .Val2 0 (add (len .Val2) -1)) \",\" }}"
"param4" : "{{ join (slice .Val2 0 (add (len .Val2) -1)) \",\" }}",
"param5" : "{{ modulo 10 \"4\" }}"
}`

var tmplMap TemplateMap
Expand All @@ -31,6 +32,7 @@ func TestMap(t *testing.T) {
"param2": "4",
"param3": "elem1,elem2,elem3,elem4",
"param4": "elem1,elem2",
"param5": "2",
}

for k, v := range cmpMap {
Expand Down

0 comments on commit 19c83de

Please sign in to comment.