A load scenario is defined in a JSON file with a number of sections.
connectionSettings
This section of the JSON file contains connection information.
JSON Web Token (JWT), an open standard for creation of access tokens, or WebSocket can be used for authentication. When using JWT, the private key must be available in the path defined by jwtsettings.keypath
.
mode
: Authentication modejwt
: JSON Web Tokenws
: WebSocket
jwtsettings
: (JWT only) Settings for the JWT connection.keypath
: Local path to the JWT key file.jwtheader
: JWT headers as an escaped JSON string. Custom headers to be added to the JWT header.claims
: JWT claims as an escaped JSON string.alg
: The signing method used for the JWT. Defaults toRS512
, if omitted.- For keyfiles in RSA format, supports
RS256
,RS384
orRS512
. - For keyfiles in EC format, supports
ES256
,ES384
orES512
.
- For keyfiles in RSA format, supports
wssettings
: (WebSocket only) Settings for the WebSocket connection.server
: Qlik Sense host.virtualproxy
: Prefix for the virtual proxy that handles the virtual users.rawurl
: Define the connect URL manually instead letting theopenapp
action do it. Note: The protocol must bewss://
orws://
.port
: Set another port than default (80
for http and443
for https).security
: Use TLS (SSL) (true
/false
).allowuntrusted
: Allow untrusted (for example, self-signed) certificates (true
/false
). Defaults tofalse
, if omitted.appext
: Replaceapp
in the connect URL for theopenapp
action. Defaults toapp
, if omitted.headers
: Headers to use in requests.maxframesize
: (Default 0 - No limit). Max size in bytes allowed to be read on sense websocket.
"connectionSettings": {
"server": "myserver.com",
"mode": "jwt",
"virtualproxy": "jwt",
"security": true,
"allowuntrusted": false,
"jwtsettings": {
"keypath": "mock.pem",
"claims": "{\"user\":\"{{.UserName}}\",\"directory\":\"{{.Directory}}\"}"
}
}
jwtsettings
:
The strings for reqheader
, jwtheader
and claims
are processed as a GO template where the User
struct can be used as data:
struct {
UserName string
Password string
Directory string
}
There is also support for the time.Now
method using the function now
.
jwtheader
:
The entries for message authentication code algorithm, alg
, and token type, typ
, are added automatically to the header and should not be included.
Example: To add a key ID header, kid
, add the following string:
{
"jwtheader": "{\"kid\":\"myKeyId\"}"
}
claims
:
Example: For on-premise JWT authentication (with the user and directory set as keys in the QMC), add the following string:
{
"claims": "{\"user\": \"{{.UserName}}\",\"directory\": \"{{.Directory}}\"}"
}
Example: To add the time at which the JWT was issued, iat
("issued at"), add the following string:
{
"claims": "{\"iat\":{{now.Unix}}"
}
Example: To add the expiration time, exp
, with 5 hours expiration (time.Now uses nanoseconds), add the following string:
{
"claims": "{\"exp\":{{(now.Add 18000000000000).Unix}}}"
}
connectionSettings": {
"server": "myserver.com",
"mode": "ws",
"security": true,
"virtualproxy" : "header",
"headers" : {
"X-Sense-User" : "{{.UserName}}"
}
hooks
This section contains the possibility to define hooks, which will send requests to a defined endpoint before and after a test execution.
preexecute
: Pre execution hook. Can be used to send a request to an endpoint before a test starts.url
: Url to send a request towards.method
: Method of request, defaults to none.payload
: (optional) Content of request.respcodes
: Accepted response codes, defaults to 200.contenttype
: Request content-type header. Defaults to application/json.extractors
: Extractors, can be used to extract a value from the response to be used on subsequent hook, or to validate that a that part of a response has a specific value.Name
: Name of extractor, this name is what is later used to when accessing the extracted data in a template such as {{ .Vars.MyExtractorName }}.path
: Path to data to extract, e.g. /id to extract the data my-id from from a parameter id in JSON root.faillevel
: Defines how to report data extraction or validation failure.none
: Do nothing.info
: Log an info log row.warning
: Log a warning log row.error
: Log a error row and abort script.
validator
: Validate that part of the response has a specific valuetype
: Value should be of this type.none
: Default type, no validation of value will be done.bool
: Value should be a boolean.number
: Value should be a number.string
: Value should be a string.
value
: Validate the value is exactly equal to this.
headers
: Custom headers to add to the request.name
: Name of header.value
: Value of header.
postexecute
: Post execution hook. Can be used to send a request to an endpoint after a test is done.url
: Url to send a request towards.method
: Method of request, defaults to none.payload
: (optional) Content of request.respcodes
: Accepted response codes, defaults to 200.contenttype
: Request content-type header. Defaults to application/json.extractors
: Extractors, can be used to extract a value from the response to be used on subsequent hook, or to validate that a that part of a response has a specific value.Name
: Name of extractor, this name is what is later used to when accessing the extracted data in a template such as {{ .Vars.MyExtractorName }}.path
: Path to data to extract, e.g. /id to extract the data my-id from from a parameter id in JSON root.faillevel
: Defines how to report data extraction or validation failure.none
: Do nothing.info
: Log an info log row.warning
: Log a warning log row.error
: Log a error row and abort script.
validator
: Validate that part of the response has a specific valuetype
: Value should be of this type.none
: Default type, no validation of value will be done.bool
: Value should be a boolean.number
: Value should be a number.string
: Value should be a string.
value
: Validate the value is exactly equal to this.
headers
: Custom headers to add to the request.name
: Name of header.value
: Value of header.
"hooks": {
"preexecute": {
"url": "https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ",
"method": "POST",
"payload": "{ \"text\": \"Running test with {{ .Scheduler.ConcurrentUsers }} concurrent users and {{ .Scheduler.Iterations }} iterations towards {{ .ConnectionSettings.Server }}.\"}",
"contenttype": "application/json"
},
"postexecute": {
"url": "https://hooks.slack.com/services/XXXXXXXXX/YYYYYYYYYYY/ZZZZZZZZZZZZZZZZZZZZZZZZ",
"method": "POST",
"payload": "{ \"text\": \"Test finished with {{ .Counters.Errors }} errors and {{ .Counters.Warnings }} warnings. Total Sessions: {{ .Counters.Sessions }}\"}"
}
}
This will send a message on test startup such as:
Running test with 10 concurrent users and 2 iterations towards MyServer.com.
And a message on test finished such as:
Test finished with 4 errors and 12 warnings. Total Sessions: 20.
"hooks": {
"preexecute": {
"url": "http://myserver:8080/oktoexecute",
"method": "POST",
"headers": [
{
"name" : "someheader",
"value": "headervalue"
}
],
"payload": "{\"testID\": \"12345\",\"startAt\": \"{{now.Format \"2006-01-02T15:04:05Z07:00\"}}\"}",
"extractors": [
{
"name": "oktorun",
"path" : "/oktorun",
"faillevel": "error",
"validator" : {
"type": "bool",
"value": "true"
}
}
]
}
}
This will POST a request to http://myserver:8080/oktoexecute
with the body:
{
"testID": "12345",
"startAt": "2021-05-06T08:00:00Z01:00"
}
For a test started at 2021-05-06T08:00:00
in timezone UTC+1.
Let's assume the response from this endpoint is:
{
"oktorun": false
}
The validator with path /oktorun
will extract the value false
and compare to the value defined in the validator, in this case true
. Since the they are not equal the test will stop with error before starting exection.
loginSettings
This section of the JSON file contains information on the login settings.
type
: Type of login requestprefix
: Add a prefix (specified by theprefix
setting below) to the username, so that it will beprefix_{session}
.userlist
: List of users as specified by theuserList
setting below.fromfile
: List of users from a file with 1 user per row and the formatusername;directory;password
none
: Do not add a prefix to the username, so that it will be{session}
.
settings
:userList
: List of users for theuserlist
login request type. Directory and password can be specified per user or outside the list of usernames, which means that they are inherited by all users.filename
: Path to file with users.prefix
: Prefix to add to the username, so that it will beprefix_{session}
.directory
: Directory to set for the users.
"loginSettings": {
"type": "prefix",
"settings": {
"directory": "anydir",
"prefix": "Nunit"
}
}
"loginSettings": {
"type": "userlist",
"settings": {
"userList": [
{
"username": "[email protected]",
"directory": "anydir1",
"password": "MyPassword1"
},
{
"username": "[email protected]"
}
],
"directory": "anydir2",
"password": "MyPassword2"
}
}
Reads a user list from file. 1 User per row of the and with the format username;directory;password
. directory
and password
are optional, if none are defined for a user it will use the default values on settings (i.e. defaultdir
and defaultpassword
). If the used authentication type doesn't use directory
or password
these can be omitted.
Definition with default values:
"loginSettings": {
"type": "fromfile",
"settings": {
"filename": "./myusers.txt",
"directory": "defaultdir",
"password": "defaultpassword"
}
}
Definition without default values:
"loginSettings": {
"type": "fromfile",
"settings": {
"filename": "./myusers.txt"
}
}
This is a valid format of a file.
testuser1
testuser2;myspecialdirectory
testuser3;;somepassword
testuser4;specialdir;anotherpassword
testuser5;;A;d;v;a;n;c;e;d;;P;a;s;s;w;o;r;d;
testuser1 will get default directory
and password
, testuser3 and testuser5 will get default directory
.
scenario
This section of the JSON file contains the actions that are performed in the load scenario.
All actions follow the same basic structure:
action
: Name of the action to execute.label
: (optional) Custom string set by the user. This can be used to distinguish the action from other actions of the same type when analyzing the test results.disabled
: (optional) Disable action (true
/false
). If set totrue
, the action is not executed.settings
: Most, but not all, actions have a settings section with action-specific settings.
{
"action": "actioname",
"label": "custom label for analysis purposes",
"disabled": false,
"settings": {
}
}
Common actions
These actions are applicable for most types of Qlik Sense deployments.
Note: It is recommended to prepend the actions listed here with an openapp
action as most of them perform operations in an app context (such as making selections or changing sheets).
applybookmark
Apply a bookmark in the current app.
Note: Specify either title
or id
, not both.
title
: Name of the bookmark (supports the use of variables).id
: ID of the bookmark.selectionsonly
: Apply selections only.
{
"action": "applybookmark",
"settings": {
"title": "My bookmark"
}
}
askhubadvisor
Perform a query in the Qlik Sense hub insight advisor.
querysource
: The source from which queries will be randomly picked.file
: Read queries from file defined byfile
.querylist
: Read queries from list defined byquerylist
.
querylist
: A list of queries. Plain strings are supported and will get a weight of1
.weight
: A weight to set probablility of query being peformed.query
: A query sentence.
lang
: Query language.maxfollowup
: The maximum depth of followup queries asked. A value of0
means that a query from querysource is performed without followup queries.file
: Path to query file.app
: Optional name of app to pick in followup queries. If not set, a random app is picked.saveimages
: Save images of charts to file.saveimagefile
: File name of saved images. Defaults to server side file name. Supports Session Variables.thinktime
: Settings for thethinktime
action, which is automatically inserted before each followup. Defaults to a uniform distribution with mean=8 and deviation=4.type
: Type of think timestatic
: Static think time, defined bydelay
.uniform
: Random think time with uniform distribution, defined bymean
anddev
.
delay
: Delay (seconds), used with typestatic
.mean
: Mean (seconds), used with typeuniform
.dev
: Deviation (seconds) frommean
value, used with typeuniform
.
followuptypes
: A list of followup types enabled for followup queries. If omitted, all types are enabled.app
: Enable followup queries which change app.measure
: Enable followups based on measures.dimension
: Enable followups based on dimensions.recommendation
: Enable followups based on recommendations.sentence
: Enable followup queries based on bare sentences.
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "file",
"file": "queries.txt"
}
}
The file queries.txt
contains one query and an optional weight per line. The line format is [WEIGHT;]QUERY
.
show sales per country
5; what is the lowest price of shoes
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": ["show sales per country", "what is the lowest price of shoes"]
}
}
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": ["show sales per country", "what is the lowest price of shoes"],
"maxfollowup": 3
}
}
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": ["show sales per country", "what is the lowest price of shoes"],
"lang": "fr"
}
}
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": [
{
"query": "show sales per country",
"weight": 5,
},
"what is the lowest price of shoes"
]
}
}
See detailed examples of settings in the documentation for thinktime action.
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": [
"what is the lowest price of shoes"
],
"maxfollowup": 5,
"thinktime": {
"type": "static",
"delay": 5
}
}
}
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": [
"what is the lowest price of shoes"
],
"maxfollowup": 5,
"followuptypes": ["app"]
}
}
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": [
"show price per shoe type"
],
"maxfollowup": 5,
"saveimages": true
}
}
The saveimagefile
file name template setting supports
Session Variables.
You can apart from session variables include the following action local variables in the saveimagefile
file name template:
- .Local.ImageCount - the number of images written to file
- .Local.ServerFileName - the server side name of image file
- .Local.Query - the query sentence
- .Local.AppName - the name of app, if any app, where query is asked
- .Local.AppID - the id of app, if any app, where query is asked
{
"action": "AskHubAdvisor",
"settings": {
"querysource": "querylist",
"querylist": [
"show price per shoe type"
],
"maxfollowup": 5,
"saveimages": true,
"saveimagefile": "{{.Local.Query}}--app-{{.Local.AppName}}--user-{{.UserName}}--thread-{{.Thread}}--session-{{.Session}}"
}
}
changesheet
Change to a new sheet, unsubscribe to the currently subscribed objects, and subscribe to all objects on the new sheet.
The action supports getting data from the following objects:
-
Listbox
-
Filter pane
-
Bar chart
-
Scatter plot
-
Map (only the first layer)
-
Combo chart
-
Table
-
Pivot table
-
Line chart
-
Pie chart
-
Tree map
-
Text-Image
-
KPI
-
Gauge
-
Box plot
-
Distribution plot
-
Histogram
-
Auto chart (including any support generated visualization from this list)
-
Waterfall chart
-
id
: GUID of the sheet to change to.
{
"label": "Change Sheet Dashboard",
"action": "ChangeSheet",
"settings": {
"id": "TFJhh"
}
}
clearall
Clear all selections in an app.
{
"action": "clearall",
"label": "Clear all selections (1)"
}
clearfield
Clear selections in a field.
name
: Name of field to clear.
{
"action": "clearfield",
"label": "Clear selections in Alpha",
"settings" : {
"name": "Alpha"
}
}
clickactionbutton
A ClickActionButton
-action simulates clicking an action-button. An action-button is a sheet item which, when clicked, executes a series of actions. The series of actions contained by an action-button begins with any number generic button-actions and ends with an optional navigation button-action.
- Apply bookmark
- Move backward in all selections
- Move forward in all selections
- Lock all selections
- Clear all selections
- Lock field
- Unlock field
- Select all in field
- Select alternatives in field
- Select excluded in field
- Select possible in field
- Select values matching search criteria in field
- Clear selection in field
- Toggle selection in field
- Set value of variable
- Change to first sheet
- Change to last sheet
- Change to previous sheet
- Change sheet by name
- Change sheet by ID
id
: ID of the action-button to click.
{
"label": "ClickActionButton",
"action": "ClickActionButton",
"settings": {
"id": "951e2eee-ad49-4f6a-bdfe-e9e3dddeb2cd"
}
}
containertab
A Containertab
action simulates switching the active object in a container
object.
mode
: Mode for container tab switching, one of:objectid
,random
orindex
.objectid
: Switch to tab with object defined byobjectid
.random
: Switch to a random visible tab within the container.index
: Switch to tab with zero based index defined butindex
.
containerid
: ID of the container object.objectid
: ID of the object to set as active, used with modeobjectid
.index
: Zero based index of tab to switch to, used with modeindex
.
{
"label": "Switch to object qwerty in container object XYZ",
"action": "containertab",
"settings": {
"containerid": "xyz",
"mode": "id",
"objectid" : "qwerty"
}
}
{
"label": "Switch to random object in container object XYZ",
"action": "containertab",
"settings": {
"containerid": "xyz",
"mode": "random"
}
}
{
"label": "Switch to object in first tab in container object XYZ",
"action": "containertab",
"settings": {
"containerid": "xyz",
"mode": "index",
"index": 0
}
}
createbookmark
Create a bookmark from the current selection and selected sheet.
Note: Both title
and id
can be used to identify the bookmark in subsequent actions.
title
: Name of the bookmark (supports the use of variables).id
: ID of the bookmark.description
: (optional) Description of the bookmark to create.nosheet
: Do not include the sheet location in the bookmark.savelayout
: Include the layout in the bookmark.
{
"action": "createbookmark",
"settings": {
"title": "my bookmark",
"description": "This bookmark contains some interesting selections"
}
}
createsheet
Create a new sheet in the current app.
id
: (optional) ID to be used to identify the sheet in any subsequentchangesheet
,duplicatesheet
,publishsheet
orunpublishsheet
action.title
: Name of the sheet to create.description
: (optional) Description of the sheet to create.
{
"action": "createsheet",
"settings": {
"title" : "Generated sheet"
}
}
deletebookmark
Delete one or more bookmarks in the current app.
Note: Specify either title
or id
, not both.
title
: Name of the bookmark (supports the use of variables).id
: ID of the bookmark.mode
:single
: Delete one bookmark that matches the specifiedtitle
orid
in the current app.matching
: Delete all bookmarks with the specifiedtitle
in the current app.all
: Delete all bookmarks in the current app.
{
"action": "deletebookmark",
"settings": {
"mode": "single",
"title": "My bookmark"
}
}
deletesheet
Delete one or more sheets in the current app.
Note: Specify either title
or id
, not both.
mode
:single
: Delete one sheet that matches the specifiedtitle
orid
in the current app.matching
: Delete all sheets with the specifiedtitle
in the current app.allunpublished
: Delete all unpublished sheets in the current app.
title
: (optional) Name of the sheet to delete.id
: (optional) GUID of the sheet to delete.
{
"action": "deletesheet",
"settings": {
"mode": "matching",
"title": "Test sheet"
}
}
disconnectapp
Disconnect from an already connected app.
{
"label": "Disconnect from server",
"action" : "disconnectapp"
}
disconnectenvironment
Disconnect from an environment. This action will disconnect open websockets towards sense and events. The action is not needed for most scenarios, however if a scenario mixes different types of environmentsor uses custom actions towards external environment, it should be used directly after the last action towards the environment.
Since the action also disconnects any open websocket to Sense apps, it does not need to be preceeded with a disconnectapp
action.
{
"label": "Disconnect from environment",
"action" : "disconnectenvironment"
}
dosave
DoSave
issues a command to engine to save the currently open app. If the simulated user does not have permission to save the app it will result in an error.
{
"label": "Save MyApp",
"action" : "dosave"
}
duplicatesheet
Duplicate a sheet, including all objects.
id
: ID of the sheet to clone.changesheet
: Clear the objects currently subscribed to and then subribe to all objects on the cloned sheet (which essentially corresponds to using thechangesheet
action to go to the cloned sheet) (true
/false
). Defaults tofalse
, if omitted.save
: Executesaveobjects
after the cloning operation to save all modified objects (true
/false
). Defaults tofalse
, if omitted.cloneid
: (optional) ID to be used to identify the sheet in any subsequentchangesheet
,duplicatesheet
,publishsheet
orunpublishsheet
action.
{
"action": "duplicatesheet",
"label": "Duplicate sheet1",
"settings":{
"id" : "mBshXB",
"save": true,
"changesheet": true
}
}
getscript
Get the load script for the app.
savelog
: Save load script to log file under the INFO log labelled LoadScript
Get the load script for the app
{
"action": "getscript"
}
Get the load script for the app and save to log file
{
"action": "getscript",
"settings": {
"savelog" : true
}
}
iterated
Loop one or more actions.
Note: This action does not require an app context (that is, it does not have to be prepended with an openapp
action).
iterations
: Number of loops.actions
: Actions to iterateaction
: Name of the action to execute.label
: (optional) Custom string set by the user. This can be used to distinguish the action from other actions of the same type when analyzing the test results.disabled
: (optional) Disable action (true
/false
). If set totrue
, the action is not executed.settings
: Most, but not all, actions have a settings section with action-specific settings.
//Visit all sheets twice
{
"action": "iterated",
"label": "",
"settings": {
"iterations" : 2,
"actions" : [
{
"action": "sheetchanger"
},
{
"action": "thinktime",
"settings": {
"type": "static",
"delay": 5
}
}
]
}
}
listboxselect
Perform list object specific selectiontypes in listbox.
id
: ID of the listbox in which to select values.type
: Selection type.all
: Select all values.alternative
: Select alternative values.excluded
: Select excluded values.possible
: Select possible values.
accept
: Accept or abort selection after selection (only used withwrap
) (true
/false
).wrap
: Wrap selection with Begin / End selection requests (true
/false
).
{
"label": "ListBoxSelect",
"action": "ListBoxSelect",
"settings": {
"id": "951e2eee-ad49-4f6a-bdfe-e9e3dddeb2cd",
"type": "all",
"wrap": true,
"accept": true
}
}
objectsearch
Perform a search select in a listbox, field or master dimension.
id
: Identifier for the object, this would differ depending ontype
.listbox
: Use the ID of listbox objectfield
: Use the name of the fielddimension
: Use the title of the dimension masterobject.
searchterms
: List of search terms to search for.type
: Type of object to searchlistbox
: (Default)id
is the ID of a listbox.field
:id
is the name of a field.dimension
:id
is the title of a master object dimension.
source
: Source of search termsfromlist
: (Default) Use search terms fromsearchterms
array.fromfile
: Use search term from file defined bysearchtermsfile
erroronempty
: If set to true and the object search yields an empty result, the action will result in an error. Defaults to false.searchtermsfile
: Path to search terms file when usingsource
of typefromfile
. File should contain one term per row.
Search a listbox object, all users searches for same thing and gets an error if no result found
{
"label": "Search and select Sweden in listbox",
"action": "objectsearch",
"settings": {
"id": "maesVjgte",
"searchterms": ["Sweden"],
"type": "listbox",
"erroronempty": true
}
}
Search a field. Users use one random search term from the searchterms
list.
{
"label": "Search field",
"action": "objectsearch",
"disabled": false,
"settings": {
"id": "Countries",
"searchterms": [
"Sweden",
"Germany",
"Liechtenstein"
],
"type": "field"
}
}
Search a master object dimension using search terms from a file.
{
"label": "Search dimension",
"action": "objectsearch",
"disabled": false,
"settings": {
"id": "Dim1M",
"type": "dimension",
"erroronempty": true,
"source": "fromfile",
"searchtermsfile": "./resources/objectsearchterms.txt"
}
}
openapp
Open an app.
Note: If the app name is used to specify which app to open, this action cannot be the first action in the scenario. It must be preceded by an action that can populate the artifact map, such as openhub
.
appmode
: App selection modecurrent
: (default) Use the current app, selected by an app selection in a previous actionguid
: Use the app GUID specified by theapp
parameter.name
: Use the app name specified by theapp
parameter.random
: Select a random app from the artifact map, which is filled by e.g.openhub
randomnamefromlist
: Select a random app from a list of app names. Thelist
parameter should contain a list of app names.randomguidfromlist
: Select a random app from a list of app GUIDs. Thelist
parameter should contain a list of app GUIDs.randomnamefromfile
: Select a random app from a file with app names. Thefilename
parameter should contain the path to a file in which each line represents an app name.randomguidfromfile
: Select a random app from a file with app GUIDs. Thefilename
parameter should contain the path to a file in which each line represents an app GUID.round
: Select an app from the artifact map according to the round-robin principle.roundnamefromlist
: Select an app from a list of app names according to the round-robin principle. Thelist
parameter should contain a list of app names.roundguidfromlist
: Select an app from a list of app GUIDs according to the round-robin principle. Thelist
parameter should contain a list of app GUIDs.roundnamefromfile
: Select an app from a file with app names according to the round-robin principle. Thefilename
parameter should contain the path to a file in which each line represents an app name.roundguidfromfile
: Select an app from a file with app GUIDs according to the round-robin principle. Thefilename
parameter should contain the path to a file in which each line represents an app GUID.
app
: App name or app GUID (supports the use of session variables). Used withappmode
set toguid
orname
.list
: List of apps. Used withappmode
set torandomnamefromlist
,randomguidfromlist
,roundnamefromlist
orroundguidfromlist
.filename
: Path to a file in which each line represents an app. Used withappmode
set torandomnamefromfile
,randomguidfromfile
,roundnamefromfile
orroundguidfromfile
.externalhost
: (optional) Sets an external host to be used instead ofserver
configured in connection settings.unique
: Create unqiue engine session not re-using session from previous connection with same user. Defaults to false.
{
"label": "OpenApp",
"action": "OpenApp",
"settings": {
"appmode": "guid",
"app": "7967af99-68b6-464a-86de-81de8937dd56"
}
}
{
"label": "OpenApp",
"action": "OpenApp",
"settings": {
"appmode": "randomguidfromlist",
"list": ["7967af99-68b6-464a-86de-81de8937dd56", "ca1a9720-0f42-48e5-baa5-597dd11b6cad"]
}
}
productversion
Request the product version from the server and, optionally, save it to the log. This is a lightweight request that can be used as a keep-alive message in a loop.
log
: Save the product version to the log (true
/false
). Defaults tofalse
, if omitted.
//Keep-alive loop
{
"action": "iterated",
"settings" : {
"iterations" : 10,
"actions" : [
{
"action" : "productversion"
},
{
"action": "thinktime",
"settings": {
"type": "static",
"delay": 30
}
}
]
}
}
publishbookmark
Publish a bookmark.
Note: Specify either title
or id
, not both.
title
: Name of the bookmark (supports the use of variables).id
: ID of the bookmark.
Publish the bookmark with id
"bookmark1" that was created earlier on in the script.
{
"label" : "Publish bookmark 1",
"action": "publishbookmark",
"disabled" : false,
"settings" : {
"id" : "bookmark1"
}
}
Publish the bookmark with the title
"bookmark of testuser", where "testuser" is the username of the simulated user.
{
"label" : "Publish bookmark 2",
"action": "publishbookmark",
"disabled" : false,
"settings" : {
"title" : "bookmark of {{.UserName}}"
}
}
publishsheet
Publish sheets in the current app.
mode
:allsheets
: Publish all sheets in the app.sheetids
: Only publish the sheets specified by thesheetIds
array.
sheetIds
: (optional) Array of sheet IDs for thesheetids
mode.includePublished
: Try to publish already published sheets.
{
"label": "PublishSheets",
"action": "publishsheet",
"settings": {
"mode": "sheetids",
"sheetIds": ["qmGcYS", "bKbmgT"]
}
}
randomaction
Randomly select other actions to perform. This meta-action can be used as a starting point for your testing efforts, to simplify script authoring or to add background load.
randomaction
accepts a list of action types between which to randomize. An execution of randomaction
executes one or more of the listed actions (as determined by the iterations
parameter), randomly chosen by a weighted probability. If nothing else is specified, each action has a default random mode that is used. An override is done by specifying one or more parameters of the original action.
Each action executed by randomaction
is followed by a customizable thinktime
.
Note: The recommended way to use this action is to prepend it with an openapp
and a changesheet
action as this ensures that a sheet is always in context.
actions
: List of actions from which to randomly pick an action to execute. Each item has a number of possible parameters.type
: Type of actionthinktime
: See thethinktime
action.sheetobjectselection
: Make random selections within objects visible on the current sheet. See theselect
action.changesheet
: See thechangesheet
action.clearall
: See theclearall
action.
weight
: The probabilistic weight of the action, specified as an integer. This number is proportional to the likelihood of the specified action, and is used as a weight in a uniform random selection.overrides
: (optional) Static overrides to the action. The overrides can include any or all of the settings from the original action, as determined by thetype
field. If nothing is specified, the default values are used.
thinktimesettings
: Settings for thethinktime
action, which is automatically inserted after every randomized action.type
: Type of think timestatic
: Static think time, defined bydelay
.uniform
: Random think time with uniform distribution, defined bymean
anddev
.
delay
: Delay (seconds), used with typestatic
.mean
: Mean (seconds), used with typeuniform
.dev
: Deviation (seconds) frommean
value, used with typeuniform
.
iterations
: Number of random actions to perform.
The following default values are used for the different actions:
thinktime
: Mirrors the configuration ofthinktimesettings
sheetobjectselection
:
{
"settings":
{
"id": <UNIFORMLY RANDOMIZED>,
"type": "RandomFromAll",
"min": 1,
"max": 2,
"accept": true
}
}
changesheet
:
{
"settings":
{
"id": <UNIFORMLY RANDOMIZED>
}
}
clearall
:
{
"settings":
{
}
}
{
"action": "RandomAction",
"settings": {
"iterations": 5,
"actions": [
{
"type": "thinktime",
"weight": 1
},
{
"type": "sheetobjectselection",
"weight": 3
},
{
"type": "changesheet",
"weight": 5
},
{
"type": "clearall",
"weight": 1
}
],
"thinktimesettings": {
"type": "uniform",
"mean": 10,
"dev": 5
}
}
}
{
"action": "RandomAction",
"settings": {
"iterations": 1,
"actions": [
{
"type": "sheetobjectselection",
"weight": 1,
"overrides": {
"type": "RandomFromExcluded",
"min": 1,
"max": 5
}
}
],
"thinktimesettings": {
"type": "static",
"delay": 1
}
}
}
reload
Reload the current app by simulating selecting Load data in the Data load editor. To select an app, preceed this action with an openapp
action.
mode
: Error handling during the reload operationdefault
: Use the default error handling.abend
: Stop reloading the script, if an error occurs.ignore
: Continue reloading the script even if an error is detected in the script.
partial
: Enable partial reload (true
/false
). This allows you to add data to an app without reloading all data. Defaults tofalse
, if omitted.log
: Save the reload log as a field in the output (true
/false
). Defaults tofalse
, if omitted. Note: This should only be used when needed as the reload log can become very large.nosave
: Do not send a save request for the app after the reload is done. Defaults to saving the app.
{
"action": "reload",
"settings": {
"mode" : "default",
"partial": false
}
}
select
Select random values in an object.
See the Limitations section in the README.md file for limitations related to this action.
id
: ID of the object in which to select values.type
: Selection typerandomfromall
: Randomly select within all values of the symbol table.randomfromenabled
: Randomly select within the white and light grey values on the first data page.randomfromexcluded
: Randomly select within the dark grey values on the first data page.randomdeselect
: Randomly deselect values on the first data page.values
: Select specific element values, defined byvalues
array.
accept
: Accept or abort selection after selection (only used withwrap
) (true
/false
).wrap
: Wrap selection with Begin / End selection requests (true
/false
).min
: Minimum number of selections to make.max
: Maximum number of selections to make.dim
: Dimension / column in which to select.values
: Array of element values to select when using selection typevalues
. These are the element values for a selection, not the values seen by the user.
Randomly select among all the values in object RZmvzbF
.
{
"label": "ListBox Year",
"action": "Select",
"settings": {
"id": "RZmvzbF",
"type": "RandomFromAll",
"accept": true,
"wrap": false,
"min": 1,
"max": 3,
"dim": 0
}
}
Randomly select among all the enabled values (a.k.a "white" values) in object RZmvzbF
.
{
"label": "ListBox Year",
"action": "Select",
"settings": {
"id": "RZmvzbF",
"type": "RandomFromEnabled",
"accept": true,
"wrap": false,
"min": 1,
"max": 3,
"dim": 0
}
}
This example selects specific element values in object RZmvzbF
. These are the values which can be seen in a selection when e.g. inspecting traffic, it is not the data values presented to the user. E.g. when loading a table in the following order by a Sense loadscript:
Beta
Alpha
Gamma
which might be presented to the user sorted as
Alpha
Beta
Gamma
The element values will be Beta=0, Alpha=1 and Gamma=2.
To statically select "Gamma" in this case:
{
"label": "Select Gammma",
"action": "Select",
"settings": {
"id": "RZmvzbF",
"type": "values",
"accept": true,
"wrap": false,
"values" : [2],
"dim": 0
}
}
setscript
Set the load script for the current app. To load the data from the script, use the reload
action after the setscript
action.
script
: Load script for the app (written as a string).
{
"action": "setscript",
"settings": {
"script" : "Characters:\nLoad Chr(RecNo()+Ord('A')-1) as Alpha, RecNo() as Num autogenerate 26;"
}
}
setscriptvar
Sets a variable which can be used within the same session. Cannot be accessed across different simulated users.
name
: Name of variable to set. Will overwrite any existing variable with same name.type
: Type of the variable.string
: Variable of type string e.g.my var value
.int
: Variable of type integer e.g.6
.array
: Variable of type array e.g.1,2,3
.
value
: Value to set to variable (supports the use of session variables).sep
: Separator to use when separating string into array. Defaults to,
.
Create a variable containing a string and use it in openapp.
{
"action": "setscriptvar",
"settings": {
"name": "mylocalvar",
"type": "string",
"value": "My app Name with number for session {{ .Session }}"
}
},
{
"action": "openapp",
"settings": {
"appmode": "name",
"app": "{{ .ScriptVars.mylocalvar }}"
}
}
Create a variable containing an integer and use it in a loop creating bookmarks numbered 1 to 5. Then in a different loop reset variable and delete the bookmarks.
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "0"
}
},
{
"action": "iterated",
"settings": {
"iterations": 5,
"actions": [
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "{{ add .ScriptVars.BookmarkCounter 1 }}"
}
},
{
"action": "createbookmark",
"settings": {
"title": "Bookmark {{ .ScriptVars.BookmarkCounter }}",
"description": "This bookmark contains some interesting selections"
}
}
]
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "0"
}
},
{
"action": "iterated",
"disabled": false,
"settings": {
"iterations": 3,
"actions": [
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "{{ .ScriptVars.BookmarkCounter | add 1}}"
}
},
{
"action": "deletebookmark",
"settings": {
"mode": "single",
"title": "Bookmark {{ $element:=range.ScriptVars.BookmarkCounter }} {{ $element }}{{ end }}"
}
}
]
}
}
Combine two variables MyArrayVar
and BookmarkCounter
to create 3 bookmarks with the names Bookmark one
, Bookmark two
and Bookmark three
.
{
"action": "setscriptvar",
"settings": {
"name": "MyArrayVar",
"type": "array",
"value": "one,two,three,four,five",
"sep": ","
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "0"
}
},
{
"action": "iterated",
"disabled": false,
"settings": {
"iterations": 3,
"actions": [
{
"action": "createbookmark",
"settings": {
"title": "Bookmark {{ index .ScriptVars.MyArrayVar .ScriptVars.BookmarkCounter }}",
"description": "This bookmark contains some interesting selections"
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "{{ .ScriptVars.BookmarkCounter | add 1}}"
}
}
]
}
}
A more advanced example.
Create a bookmark "BookmarkX" for each iteration in a loop, and add this to an array "MyArrayVar". After the first iterated
action this will look like "Bookmark1,Bookmark2,Bookmark3". The second iterated
action then deletes these bookmarks using the created array.
Dissecting the first array construction action. The join
command takes the elements .ScriptVars.MyArrayVar
and joins them together into a string separated by the separtor ,
. So with an array of [ elem1 elem2 ] this becomes a string as elem1,elem2
. The if
statement checks if the value of .ScriptVars.BookmarkCounter
is 0, if it is 0 (i.e. the first iteration) it sets the string to Bookmark1
. If it is not 0, it executes the join command on .ScriptVars.MyArrayVar, on iteration 3, the result of this would be Bookmark1,Bookmark2
then it appends the fixed string ,Bookmark
, so far the string is Bookmark1,Bookmark2,Bookmark
. Lastly it takes the value of .ScriptVars.BookmarkCounter
, which is now 2, and adds 1 too it and appends, making the entire string Bookmark1,Bookmark2,Bookmark3
.
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "0"
}
},
{
"action": "iterated",
"disabled": false,
"settings": {
"iterations": 3,
"actions": [
{
"action": "setscriptvar",
"settings": {
"name": "MyArrayVar",
"type": "array",
"value": "{{ if eq 0 .ScriptVars.BookmarkCounter }}Bookmark1{{ else }}{{ join .ScriptVars.MyArrayVar \",\" }},Bookmark{{ .ScriptVars.BookmarkCounter | add 1 }}{{ end }}",
"sep": ","
}
},
{
"action": "createbookmark",
"settings": {
"title": "{{ index .ScriptVars.MyArrayVar .ScriptVars.BookmarkCounter }}",
"description": "This bookmark contains some interesting selections"
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "{{ .ScriptVars.BookmarkCounter | add 1}}"
}
}
]
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "0"
}
},
{
"action": "iterated",
"disabled": false,
"settings": {
"iterations": 3,
"actions": [
{
"action": "deletebookmark",
"settings": {
"mode": "single",
"title": "{{ index .ScriptVars.MyArrayVar .ScriptVars.BookmarkCounter }}"
}
},
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "{{ .ScriptVars.BookmarkCounter | add 1}}"
}
}
]
}
}
setsensevariable
Sets a Qlik Sense variable on a sheet in the open app.
name
: Name of the Qlik Sense variable to set.value
: Value to set the Qlik Sense variable to. (supports the use of session variables)
Set a variable to 2000
{
"name": "vSampling",
"value": "2000"
}
sheetchanger
Create and execute a changesheet
action for each sheet in an app. This can be used to cache the inital state for all objects or, by chaining two subsequent sheetchanger
actions, to measure how well the calculations in an app utilize the cache.
{
"label" : "Sheetchanger uncached",
"action": "sheetchanger"
},
{
"label" : "Sheetchanger cached",
"action": "sheetchanger"
}
smartsearch
Perform a Smart Search in Sense app to find suggested selections.
searchtextsource
: Source for list of strings used for searching.searchtextlist
(default)searchtextfile
searchtextlist
: List of of strings used for searching.searchtextfile
: File path to file with one search string per line.pastesearchtext
:true
: Simulate pasting search text.false
: Simulate typing at normal speed (default).
makeselection
: Select a random search result.true
false
selectionthinktime
: Think time before selection ifmakeselection
istrue
, defaults to a 1 second delay.type
: Type of think timestatic
: Static think time, defined bydelay
.uniform
: Random think time with uniform distribution, defined bymean
anddev
.
delay
: Delay (seconds), used with typestatic
.mean
: Mean (seconds), used with typeuniform
.dev
: Deviation (seconds) frommean
value, used with typeuniform
.
{
"action": "smartsearch",
"label": "one term search",
"settings": {
"searchtextlist": [
"term1"
]
}
}
{
"action": "smartsearch",
"label": "two term search",
"settings": {
"searchtextlist": [
"term1 term2"
]
}
}
{
"action": "smartsearch",
"settings": {
"searchtextlist": [
"text1",
"text2",
"text3"
]
}
}
{
"action": "smartsearch",
"settings": {
"searchtextsource": "searchtextfile",
"searchtextfile": "data/searchtexts.txt"
}
}
search text
"quoted search text"
another search text
The default behavior is to simulate typing at normal speed.
{
"action": "smartsearch",
"settings": {
"pastesearchtext": true,
"searchtextlist": [
"text1"
]
}
}
{
"action": "smartsearch",
"settings": {
"searchtextlist": [
"term1"
],
"makeselection": true,
"selectionthinktime": {
"type": "static",
"delay": 2
}
}
}
{
"action": "smartsearch",
"settings": {
"searchtextlist": [
"\"word1 word2\""
]
}
}
{
"action": "smartsearch",
"label": "two term search, one including spaces",
"settings": {
"searchtextlist": [
"\"word1 word2\" term2"
]
}
}
{
"action": "smartsearch",
"label": "one term search including spaces",
"settings": {
"searchtext":
"searchtextlist": [
"\\\"hello"
]
}
}
subscribeobjects
Subscribe to any object in the currently active app.
clear
: Remove any previously subscribed objects from the subscription list.ids
: List of object IDs to subscribe to.
Subscribe to two objects in the currently active app and remove any previous subscriptions.
{
"action" : "subscribeobjects",
"label" : "clear subscriptions and subscribe to mBshXB and f2a50cb3-a7e1-40ac-a015-bc4378773312",
"disabled": false,
"settings" : {
"clear" : true,
"ids" : ["mBshXB", "f2a50cb3-a7e1-40ac-a015-bc4378773312"]
}
}
Subscribe to an additional single object (or a list of objects) in the currently active app, adding the new subscription to any previous subscriptions.
{
"action" : "subscribeobjects",
"label" : "add c430d8e2-0f05-49f1-aa6f-7234e325dc35 to currently subscribed objects",
"disabled": false,
"settings" : {
"clear" : false,
"ids" : ["c430d8e2-0f05-49f1-aa6f-7234e325dc35"]
}
}
thinktime
Simulate user think time.
Note: This action does not require an app context (that is, it does not have to be prepended with an openapp
action).
type
: Type of think timestatic
: Static think time, defined bydelay
.uniform
: Random think time with uniform distribution, defined bymean
anddev
.
delay
: Delay (seconds), used with typestatic
.mean
: Mean (seconds), used with typeuniform
.dev
: Deviation (seconds) frommean
value, used with typeuniform
.
This simulates a think time of 10 to 15 seconds.
{
"label": "TimerDelay",
"action": "thinktime",
"settings": {
"type": "uniform",
"mean": 12.5,
"dev": 2.5
}
}
This simulates a think time of 5 seconds.
{
"label": "TimerDelay",
"action": "thinktime",
"settings": {
"type": "static",
"delay": 5
}
}
unpublishbookmark
Unpublish a bookmark.
Note: Specify either title
or id
, not both.
title
: Name of the bookmark (supports the use of variables).id
: ID of the bookmark.
Unpublish the bookmark with id
"bookmark1" that was created earlier on in the script.
{
"label" : "Unpublish bookmark 1",
"action": "unpublishbookmark",
"disabled" : false,
"settings" : {
"id" : "bookmark1"
}
}
Unpublish the bookmark with the title
"bookmark of testuser", where "testuser" is the username of the simulated user.
{
"label" : "Unpublish bookmark 2",
"action": "unpublishbookmark",
"disabled" : false,
"settings" : {
"title" : "bookmark of {{.UserName}}"
}
}
unpublishsheet
Unpublish sheets in the current app.
mode
:allsheets
: Unpublish all sheets in the app.sheetids
: Only unpublish the sheets specified by thesheetIds
array.
sheetIds
: (optional) Array of sheet IDs for thesheetids
mode.
{
"label": "UnpublishSheets",
"action": "unpublishsheet",
"settings": {
"mode": "allsheets"
}
}
unsubscribeobjects
Unsubscribe to any currently subscribed object.
ids
: List of object IDs to unsubscribe from.clear
: Remove any previously subscribed objects from the subscription list.
Unsubscribe from a single object (or a list of objects).
{
"action" : "unsubscribeobjects",
"label" : "unsubscribe from object maVjt and its children",
"disabled": false,
"settings" : {
"ids" : ["maVjt"]
}
}
Unsubscribe from all currently subscribed objects.
{
"action" : "unsubscribeobjects",
"label" : "unsubscribe from all objects",
"disabled": false,
"settings" : {
"clear": true
}
}
stepdimension
Cycle a step in a cyclic dimension
id
: library ID of the cyclic dimension
Cycle one step in the dimension with library ID aBc123
.
{
"action": "stepdimension",
"settings":{
"id": "aBc123"
}
}
Qlik Sense Enterprise on Windows (QSEoW) actions
These actions are only applicable to Qlik Sense Enterprise on Windows (QSEoW) deployments.
deleteodag
Delete all user-generated on-demand apps for the current user and the specified On-Demand App Generation (ODAG) link.
linkname
: Name of the ODAG link from which to delete generated apps. The name is displayed in the ODAG navigation bar at the bottom of the selection app.
{
"action": "DeleteOdag",
"settings": {
"linkname": "Drill to Template App"
}
}
generateodag
Generate an on-demand app from an existing On-Demand App Generation (ODAG) link.
linkname
: Name of the ODAG link from which to generate an app. The name is displayed in the ODAG navigation bar at the bottom of the selection app.
{
"action": "GenerateOdag",
"settings": {
"linkname": "Drill to Template App"
}
}
openhub
Open the hub in a QSEoW environment. This also makes the apps included in the response for the users myspace
available for use by subsequent actions. The action changestream
can be used to only select from apps in a specific stream.
{
"action": "OpenHub",
"label": "Open the hub"
}
changestream
Change to specified stream. This makes the apps in the specified stream selectable by actions such as openapp
.
mode
: Decides what kind of value thestream
field contains. Defaults toname
.name
:stream
is the name of the stream.id
:stream
is the ID if the stream.
stream
:
Make apps in stream Everyone
selectable by subsequent actions.
{
"label": "ChangeStream Everyone",
"action": "changestream",
"settings": {
"mode": "name",
"stream" : "Everyone"
}
}
Make apps in stream with id ABSCDFSDFSDFO1231234
selectable subsequent actions.
{
"label": "ChangeStream Test1",
"action": "changestream",
"settings": {
"mode": "id",
"stream" : "ABSCDFSDFSDFO1231234"
}
}
This section describes the session variables that can be used with some of the actions.
Session variables
Some 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}}
.
The following session variables are supported in actions:
UserName
: The simulated username. This is not the same as the authenticated user, but rather how the username was defined by Login settings.Session
: The enumeration of the currently simulated session.Thread
: The enumeration of the currently simulated "thread" or "concurrent user".ScriptVars
: A map containing script variables added by the actionsetscriptvar
.Artifacts
:GetIDByTypeAndName
: A function that accepts the two string arguments,artifactType
andartifactName
, and returns the resource id of the artifact.GetNameByTypeAndID
: A function that accepts the two string arguments,artifactType
andartifactID
, and returns the name of the artifact.
The following variable is supported in the filename of the log file:
ConfigFile
: The filename of the config file, without file extension.
The following functions are supported:
now
: Evaluates Golang time.Now().hostname
: Hostname of the local machine.timestamp
: Timestamp inyyyyMMddhhmmss
format.uuid
: Generate an uuid.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)
{
"label" : "Create bookmark",
"action": "createbookmark",
"settings": {
"title": "my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})",
"description": "This bookmark contains some interesting selections"
}
},
{
"label" : "Publish created bookmark",
"action": "publishbookmark",
"disabled" : false,
"settings" : {
"title": "my bookmark {{.Thread}}-{{.Session}} ({{.UserName}})",
}
}
{
"action": "createbookmark",
"settings": {
"title": "{{env \"TITLE\"}}",
"description": "This bookmark contains some interesting selections"
}
}
{
"action": "setscriptvar",
"settings": {
"name": "BookmarkCounter",
"type": "int",
"value": "1"
}
},
{
"action": "createbookmark",
"settings": {
"title": "Bookmark no {{ add .ScriptVars.BookmarkCounter 1 }}",
"description": "This bookmark will have the title Bookmark no 2"
}
}
{
"action": "setscriptvar",
"settings": {
"name": "MyAppId",
"type": "string",
"value": "{{.Artifacts.GetIDByTypeAndName \"app\" (print \"an-app-\" .Session)}}"
}
}
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.
{
"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.
{
"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",
}
}
scheduler
This section of the JSON file contains scheduler settings for the users in the load scenario.
simple
Settings specific to the simple
scheduler.
type
: Type of schedulersimple
: Standard scheduler
iterationtimebuffer
:mode
: Time buffer mode. Defaults tonowait
, if omitted.nowait
: No time buffer in between the iterations.constant
: Add a constant time buffer after each iteration. Defined byduration
.onerror
: Add a time buffer in case of an error. Defined byduration
.minduration
: Add a time buffer if the iteration duration is less thanduration
.
duration
: Duration of the time buffer (for example,500ms
,30s
or1m10s
). Valid time units arens
,us
(orµs
),ms
,s
,m
, andh
.
instance
: Instance number for this instance. Use different instance numbers when running the same script in multiple instances to make sure the randomization is different in each instance. Defaults to 1.reconnectsettings
: Settings for enabling re-connection attempts in case of unexpected disconnects.reconnect
: Enable re-connection attempts if the WebSocket is disconnected. Defaults tofalse
.backoff
: Re-connection backoff scheme. Defaults to[0.0, 2.0, 2.0, 2.0, 2.0, 2.0, 4.0, 4.0, 8.0, 12.0, 16.0]
, if left empty. An example backoff scheme could be[0.0, 1.0, 10.0, 20.0]
:0.0
: If the WebSocket is disconnected, wait 0.0s before attempting to re-connect1.0
: If the previous attempt to re-connect failed, wait 1.0s before attempting again10.0
: If the previous attempt to re-connect failed, wait 10.0s before attempting again20.0
: If the previous attempt to re-connect failed, wait 20.0s before attempting again
settings
:executionTime
: Test execution time (seconds). The sessions are disconnected when the specified time has elapsed. Allowed values are positive integers.-1
means an infinite execution time.iterations
: Number of iterations for each 'concurrent' user to repeat. Allowed values are positive integers.-1
means an infinite number of iterations.rampupDelay
: Time delay (seconds) scheduled in between each concurrent user during the startup period.concurrentUsers
: Number of concurrent users to simulate. Allowed values are positive integers.reuseUsers
:true
: Every iteration for each concurrent user uses the same user and session.false
: Every iteration for each concurrent user uses a new user and session. The total number of users is the product ofconcurrentusers
anditerations
.
onlyinstanceseed
: Disable session part of randomization seed. Defaults tofalse
, if omitted.true
: All users and sessions have the same randomization sequence, which only changes if theinstance
flag is changed.false
: Normal randomization sequence, dependent on both theinstance
parameter and the current user session.
If reconnectsettings.reconnect
is enabled, the following is attempted:
- Re-connect the WebSocket.
- Get the currently opened app in the re-attached engine session.
- Re-subscribe to the same object as before the disconnection.
- If successful, the action during which the re-connect happened is logged as a successful action with
action
andlabel
changed toReconnect(action)
andReconnect(label)
. - Restart the action that was executed when the disconnection occurred (unless it is a
thinktime
action, which will not be restarted). - Log an info row with info type
WebsocketReconnect
and with a semicolon-separateddetails
section as follows: "success=X
;attempts=Y
;TimeSpent=Z
"X
: True/falseY
: An integer representing the number of re-connection attemptsZ
: The time spent re-connecting (ms)
Simple scheduler settings:
"scheduler": {
"type": "simple",
"settings": {
"executiontime": 120,
"iterations": -1,
"rampupdelay": 7.0,
"concurrentusers": 10
},
"iterationtimebuffer" : {
"mode": "onerror",
"duration" : "5s"
},
"instance" : 2
}
Simple scheduler set to attempt re-connection in case of an unexpected WebSocket disconnection:
"scheduler": {
"type": "simple",
"settings": {
"executiontime": 120,
"iterations": -1,
"rampupdelay": 7.0,
"concurrentusers": 10
},
"iterationtimebuffer" : {
"mode": "onerror",
"duration" : "5s"
},
"reconnectsettings" : {
"reconnect" : true
}
}
settings
This section of the JSON file contains timeout and logging settings for the load scenario.
timeout
: Timeout setting (seconds) for requests.logs
: Log settingstraffic
: Log traffic information (true
/false
). Defaults tofalse
, if omitted. Note: This should only be used for debugging purposes as traffic logging is resource-demanding.debug
: Log debug information (true
/false
). Defaults tofalse
, if omitted.metrics
: Log traffic metrics (true
/false
). Defaults tofalse
, if omitted. Note: This should only be used for debugging purposes as traffic logging is resource-demanding.regression
: Log regression data (true
/false
). Defaults tofalse
, if omitted. Note: Do not log regression data when testing performance. Note With regression logging enabled, the the scheduler is implicitly set to execute the scenario as one user for one iteration.filename
: Name of the log file (supports the use of variables).format
: Log format. Defaults totsvfile
, if omitted.tsvfile
: Log to file in TSV format and output status to console.tsvconsole
: Log to console in TSV format without any status output.jsonfile
: Log to file in JSON format and output status to console.jsonconsole
: Log to console in JSON format without any status output.console
: Log to console in color format without any status output.combined
: Log to file in TSV format and to console in JSON format.no
: Default logs and status output turned off.onlystatus
: Default logs turned off, but status output turned on.
summary
: Type of summary to display after the test run. Defaults to simple for minimal performance impact.0
orundefined
: Simple, single-row summary1
ornone
: No summary2
orsimple
: Simple, single-row summary3
orextended
: Extended summary that includes statistics on each unique combination of action, label and app GUID4
orfull
: Same as extended, but with statistics on each unique combination of method and endpoint added
summaryFilename
: Name of summary file, only used when using summary typefile
. Defaults tosummary.json
outputs
: Used by some actions to save results to a file.dir
: Directory in which to save artifacts generated by the script (except log file).
maxerrors
: Break execution if max errors exceeded. 0 - Do not break. Defaults to 0.
"settings": {
"timeout": 300,
"logs": {
"traffic": false,
"debug": false,
"filename": "logs/{{.ConfigFile}}-{{timestamp}}.log"
}
}
"settings": {
"timeout": 300,
"logs": {
"filename": "logs/scenario.log"
},
"outputs" : {
"dir" : "./outputs"
}
}