To run the repository:
-
Obtain the string
SID:PASSWORD
from Exotel DAP console, and obtain base64 encoded value by the following commands:> echo 'SID:PASSWORD' | base64 U0lEOlBBU1NXT1JECg==
-
Navigate to
plays
and replace the above obtained token and SID in the field-value ofauthorization_token
andSID
respectively in the given placeholder block of all the steps in all the plays:"endpoint": { "authorization_type": "Basic", "authorization_token": "PLACE_YOUR_BASE64_ENCODED_<SID:PASSWORD>_TOKEN_HERE", "sid": "SID" },
making it look like this
"endpoint": { "authorization_type": "Basic", "authorization_token": "U0lEOlBBU1NXT1JECg==", "sid": "SID"
-
Increase
ulimit
.ulimit -n 120000
-
Now run the
main.go
file.go run cmd/baremetrix/main.go
The following are the terminology used in the project.
play
- Refers to a test scenario.act
/flow
- Refers to a step in the testing scenario.summary
- Refers to a consolidated results.bare
- Refers to logs generated by the logger in the project.result
- Refers to bin file generated by the project which is required for plotting.
-
Navigate to plays folders and duplicate the file, renaming it with sequential Id appended to the filename. For example,
plays ├── play_a01.json └── play_a02.json
We can make a play file called
play_a02.json
. -
Follow the schema of the file and make necessary changes.
-
Navigate to
config/config.json
and add this file name as another entry inplay
section underfilename
list. An example could be similar to this:... "play": { "containerDirectory": "play", "filename": [ "play_a01", "play_a02" // new play file written here ], "fileextension": "json" }, ...
-
Run the
main.go
file.go run cmd/baremetrix/main.go
The project
currently generates four types of logs:
Type | Description | Location (default) | Remarks |
---|---|---|---|
bare | This is raw levelled log file being generated by baremetrix . |
logs/bare |
Look for the most recent timestamped .log file. |
summary | This contains consolidated summary of various stats for all iterations of all plays. | logs/summary |
Look for the most recent timestamped .csv file. |
result | This is .bin file required by vegeta lib for plotting purposes. |
logs/result |
Look for the most recent timestamped .bin file. |
plots | This is generated for all iterations for all the acts. | logs/plots |
Looks for most recent timestamped directory. Inside that look for the specific play-# /iteration-# / act-# directory, there you would find the exact plot.PS: Currently this is a WIP task. |
A play is a scenario which gets ingested by the baremetrix
framework, often running in stages (or acts) as mentioned in the playfile itself.
The mean idea behind the creation of playfiles was to provide the project the ability to handle multiple variations of testing scenarios, meanwhile providing enough configurability for fine-tuning individual testing parameters for each stage and verbose recording of metrics. Also another goal was easier codebase maintenance.
An example of a playfile is given below,
{
"id": "A01",
"name": "play-A01",
"iterations": 2,
"acts": [
{
"name": "act-1",
"type": "none",
"allocate_url": {
"use_case": "LA_GREENPIN_CREATE_PIN_ALLOCATION",
"url": "http://leadassist-staging.exotel.in/v1/tenants/SID/greenpin"
},
"api": "LA_GREENVN_CREATE_ALLOCATION",
"method": "POST",
"headers": [
{
"key": "Content-type",
"value": "application/json"
}
],
"endpoint": {
"authorization_type": "Basic",
"authorization_token": "U0lEOlBBU1NXT1JECg==",
"sid": "sid"
},
"pre_op_sequence": [],
"default_parameters": {
"seed": {
"apin": {
"min": 1000000000,
"max": 7000000000
},
"bpin": {
"min": 1000000000,
"max": 9000000000
},
"connection_id": {
"min": 0,
"max": 9000000000
}
},
"country_code": "+91",
"usage": "twoway",
"deallocation_policy": {
"duration": "1s"
}
},
"vegeta": {
"rate_of_requests": 30,
"duration_in_seconds": 20,
"duplicacy_percentage": 10,
"timeout_in_milliseconds": 120000,
"keep_alive": true
}
}
]
}
The following are the top level contents in a playfile:
Field | Purpose | Remarks |
---|---|---|
id |
Identification of the playfile. | Used in plots and summaries for easier access. |
name |
Identification of the playfile. | Used in plots and summaries for easier access. |
iterations |
Specifies the number of times a play has to be run. | To avoid writing multiple playfiles or running same plays to get an idea of mean results. |
acts |
Stages of the play/test scenario. | Details below. |
An act is a stage in a playfile. It has all details required to essential create and run the scenario in the load testing framework.
The following are the top level contents in an act:
Field | Purpose | Remarks |
---|---|---|
name |
Identification of the playfile. | Used in plots and summaries for easier access. |
type |
Can be sequence or individual . |
Used to indicate whether a particular act is just hitting a single API or if it has some network-call dependencies. |
allocate_url |
Full URL to be testing. | A placeholder is used for any credential-related information. |
api |
API Name | A list of APIs supported by the current system. Can be found in internal/constants/constants.go . |
method |
Method Name | |
header |
A list of headers in the form of key-value pairs, required. | |
endpoint |
API Authorization credentials. | Currently, houses actual credentails. Note: A task to replace it with a placeholder is identified. The plan is to use an additional step at the pipeline-level to retrieve the credentials from a secret and replacement the fields here, but this is for a later date. |
pre_op_sequence |
Calls a sequence of dependent APIs before execution. | Used for individual DELETE or GET API.Note: This is temporary solution. A task has been identified to run a sidecar which would prepopulate APIs and provides a list of responses to dependent APIs to run. |
default_parameters |
Contains parameters required for varying payload for each API call during execution of an act. | |
vegeta |
Contains parameters required by vegeta lib to run the act. |
Can be altered at act-level, not play-level. |
A flow is another type of stage in a playfile. It is in many ways quite similar to acts, with only one difference. For an act of random type, there is no inherent order maintained, whereas for a flow a definite order is maintained. For more details, please refer to the Design Document in Confluence.