File: README.md
eBPF-powered Kubernetes Monitoring and Performance Testing
*Anteon automatically generates Service Map of your K8s cluster without code instrumentation or sidecars. So you can easily find the bottlenecks in your system. Red lines indicate the high latency between services.*[Live Demo](https://demo.getanteon.com/) β’ [Documentation](https://getanteon.com/docs) β’ [Discord](https://discord.com/invite/9KdnrSUZQg)
π What is Anteon?
Anteon (formerly Ddosify) is an open-source, eBPF-based Kubernetes Monitoring and Performance Testing platform.
π Kubernetes Monitoring
- Automatic Service Map Creation: Anteon automatically creates a service map of your cluster without code instrumentation or sidecars. So you can easily find the bottlenecks in your system.
- Performance Insights: It helps you spot issues like services taking too long to respond or slow SQL queries.
- Real-Time Metrics: The platform tracks and displays live data on your cluster instances CPU, memory, disk, and network usage.
- Ease of Use: You don't need to change any code, restart services, or add extra components (like sidecars) to get these insights, thanks to the eBPF based agent (Alaz).
- Alerts for Anomalies: If something unusual, like a sudden increase in CPU usage, happens in your Kubernetes (K8s) cluster, Anteon immediately sends alerts to your Slack.
- Seamless Integration with Performance Testing: Performance testing is natively integrated with Kubernetes monitoring for a unified experience.
π¨ Performance Testing
- Multi-Location Based: Generate load/performance tests from over 25 countries worldwide.
- Easy Scenario Builder: Create test scenarios easily without writing any code.
- Seamless Integration with Kubernetes Monitoring: Performance testing is natively integrated with Kubernetes monitoring for a unified experience.
- Postman Integration: Import tests directly from Postman, making it convenient for those already using Postman for API development and testing.
π Documentation
β¨ Ask Anteon Guru
If you donβt want to get lost in the documentation, you can ask Anteon Guru directly. It's an Anteon-focused AI that uses information from the Anteon Website and Anteon GitHub Repository to answer your questions.
βΉοΈ About This Repository
This repository includes the source code for the Anteon Load Engine (Ddosify). You can access Docker Images for the Anteon Engine and Self Hosted on Docker Hub. Since Anteon is a Verified Publisher on Docker Hub, there isn't any pull limits.
- Ddosify documentation provides information on the installation, usage, and features of the Anteon Load Engine.
- The Self-Hosted folder contains installation instructions for the Self-Hosted version.
- Anteon eBPF agent (Alaz) has its own repository.
See the Anteon website for more information.
π οΈ Contributing
See our Contribution Guide and please follow the Code of Conduct in all your interactions with the project.
Thanks goes to these wonderful people!
Made with contrib.rocks.
π¨ Communication
You can join our Discord Server for issues, feature requests, feedbacks or anything else.
β οΈ Disclaimer
Anteon is created for testing the performance of web applications. Users must be the owner of the target system. Using it for harmful purposes is extremely forbidden. Anteon team & company is not responsible for itsβ usages and consequences.
π License
Licensed under the AGPLv3
File: ddosify_engine/completions/README.md
Shell completions
Zsh
completions/_ddosify provides a basic auto-completions. You can apply one of the steps to get an auto-completion successfully.
You can locate the file in any directory referenced by $fpath. You can use the following command to list directories in $fpath.
echo $fpath | tr ' ' '\n'For example, if you are using oh-my-zsh you can add it as a plugin after locating file under plugin related directory appeared in $fpath. You can create a directory named ddosify under ~/.oh-my-zsh/plugins and copy _ddosify file to it.
mkdir -p ~/.oh-my-zsh/plugins/ddosify
cp completions/_ddosify ~/.oh-my-zsh/plugins/ddosifyThen, you can add ddosify to your plugins list in ~/.zshrc file.
# ~/.zshrc
plugins=(
...
ddosify
)If you don't have an appropriate directory, you can create one and add it to $fpath.
mkdir -p ${ZDOTDIR:-~}/.zsh_functions
echo 'fpath+=${ZDOTDIR:-~}/.zsh_functions' >> ${ZDOTDIR:-~}/.zshrcThen, you can copy _ddosify file to the directory you created.
cp completions/_ddosify ${ZDOTDIR:-~}/.zsh_functions/_ddosifyFile: ddosify_engine/README.md
Ddosify: A high-performance load testing tool
Table of Contents
β Scenario-Based - Create your flow in a JSON file. Without a line of code!
β Different Load Types - Test your system's limits across different load types.
β Parameterization - Use dynamic variables just like on Postman.
β Correlation - Extract variables from earlier phases and pass them on to the following ones.
β Test Data - Import test data from CSV and use it in the scenario.
β Assertion - Verify that the response matches your expectations.
β Success Criteria - Set the success criteria for your test.
β Cookies - Pass cookies through steps and set initial cookies if you want.
β Widely Used Protocols - Currently supporting HTTP, HTTPS, HTTP/2. Other protocols are on the way.
Tutorials / Blog Posts
- Testing the Performance of User Authentication Flow
- Load Testing a Fintech API with CSV Test Data Import
Installation
ddosify is available via Docker, Docker Extension, Homebrew Tap, and downloadable as pre-compiled binaries from the releases page for macOS, Linux and Windows.
For shell auto completions, see Ddosify Completions.
Docker
docker run -it --rm ddosify/ddosifyDocker Extension
Run Ddosify on Docker Desktop with Ddosify Docker extension. More details here.
Homebrew Tap (macOS and Linux)
brew install ddosify/tap/ddosifyLinux
- For ARM architectures change
ddosify_amd64toddosify_arm64orddosify_armv6. - Superuser privilege is required.
Redhat (Fedora, CentOS, RHEL, etc.)
rpm -i https://github.com/ddosify/ddosify/releases/download/v1.0.6/ddosify_amd64.rpmDebian (Ubuntu, Linux Mint, etc.)
wget https://github.com/ddosify/ddosify/releases/download/v1.0.6/ddosify_amd64.deb
dpkg -i ddosify_amd64.debAlpine
wget https://github.com/ddosify/ddosify/releases/download/v1.0.6/ddosify_amd64.apk
apk add --allow-untrusted ddosify_amd64.apkFreeBSD
pkg install ddosifyWindows Executable
- Download zip file for your architecture from the releases page.
- For example, download ddosify version
vx.x.xwith amd64 architecture:ddosify_x.x.x.zip_windows_amd64
- For example, download ddosify version
- Unzip
ddosify_x.x.x_windows_amd64.zip - Open Powershell or CMD (Command Prompt) and change directory to unzipped folder:
ddosify_x.x.x_windows_amd64 - Run ddosify:
.\ddosify.exe -t https://getanteon.comUsing the convenience script (macOS and Linux)
- The script requires root or sudo privileges to move ddosify binary to
/usr/local/bin. - The script attempts to detect your operating system (macOS or Linux) and architecture (arm64, x86, amd64) to download the appropriate binary from the releases page.
- By default, the script installs the latest version of
ddosify. - If you have problems, check common issues.
- Required packages:
curlandsudo
curl -sSfL https://raw.githubusercontent.com/getanteon/anteon/master/scripts/install.sh | shGo install from source (macOS, FreeBSD, Linux, Windows)
Minimum supported Go version is 1.18
go install -v go.ddosify.com/ddosify@latestQuick Start
This section aims to show you how to use Ddosify easily without deep dive into its details.
Simple load test
ddosify -t https://getanteon.comThe above command runs a load test with the default value that is 100 requests in 10 seconds.
Using some of the features
ddosify -t https://getanteon.com -n 1000 -d 20 -m PUT -T 7 -P http://proxy_server.com:80Ddosify sends a total of 1000 PUT requests to https://getanteon.com over proxy http://proxy_server.com:80 in 20 seconds with a timeout of 7 seconds per request.
Usage for CI/CD pipelines (JSON output)
ddosify -t https://getanteon.com -o stdout-json | jq .avg_durationDdosify outputs the result in JSON format. Then
jq(or any other command-line JSON processor) fetches theavg_duration. The rest depends on your CI/CD flow logic.Scenario based load test
ddosify -config config_examples/config.jsonDdosify first sends HTTP/2 POST request to https://getanteon.com/endpoint_1 using basic auth credentials test_user:12345 over proxy http://proxy_host.com:proxy_port and with a timeout of 3 seconds. Once the response is received, HTTPS GET request will be sent to https://getanteon.com/endpoint_2 along with the payload included in config_examples/payload.txt file with a timeout of 2 seconds. This flow will be repeated 20 times in 5 seconds and response will be written to stdout.
Load test with Dynamic Variables (Parameterization)
ddosify -t https://getanteon.com/{{_randomInt}} -d 10 -n 100 -h 'User-Agent: {{_randomUserAgent}}' -b '{"city": "{{_randomCity}}"}'Ddosify sends a total of 100 GET requests to https://getanteon.com/{{_randomInt}} in 10 seconds.
{{_randomInt}}path generates random integers between 1 and 1000 in every request. Dynamic variables can be used in URL, headers, payload (body) and basic authentication. In this example, Ddosify generates a random user agent in the header and a random city in the body. The full list of the dynamic variables can be found in the docs.Correlation (Captured Variables)
ddosify -config ddosify_config_correlation.jsonDdosify allows you to specify variables at the global level and use them throughout the scenario, as well as extract variables from previous steps and inject them to the next steps in each iteration individually. You can inject those variables in requests url, headers and payload(body). The example config can be found in correlation-config-example.
Test Data
ddosify -config ddosify_data_csv.jsonDdosify allows you to load test data from a file, tag specific columns for later use. You can inject those variables in requests url, headers and payload (body). The example config can be found in test-data-example.
Advanced Usage
You can configure your load test by the CLI options or a config file. Config file supports more features than the CLI. For example, you can't create a scenario-based load test with CLI options.
CLI Flags
ddosify [FLAG]| Flag | Description | Type | Default | Required |
|---|---|---|---|---|
-t |
Target website URL. Example: https://getanteon.com | string |
- | Yes |
-n |
Total iteration count | int |
100 |
No |
-d |
Test duration in seconds. | int |
10 |
No |
-m |
Request method. Available methods for HTTP(s) are GET, POST, PUT, DELETE, HEAD, PATCH, OPTIONS | string |
GET |
No |
-b |
The payload of the network packet. AKA body for the HTTP. | string |
- | No |
-a |
Basic authentication. Usage: -a username:password |
string |
- | No |
-h |
Headers of the request. You can provide multiple headers with multiple -h flag. Usage: -h 'Accept: text/html' |
string |
- | No |
-T |
Timeout of the request in seconds. | int |
5 |
No |
-P |
Proxy address as host:port. -P 'http://user:pass@proxy_host.com:port' |
string |
- | No |
-o |
Test result output destination. Supported outputs are [stdout, stdout-json] Other output types will be added. | string |
stdout |
No |
-l |
Type of the load test. Ddosify supports 3 load types. | string |
linear |
No |
--config |
Config File of the load test. | string |
- | No |
--version |
Prints version, git commit, built date (utc), go information and quit | - | - | No |
--cert_path |
A path to a certificate file (usually called 'cert.pem') | - | - | No |
--cert_key_path |
A path to a certificate key file (usually called 'key.pem') | - | - | No |
--debug |
Iterates the scenario once and prints curl-like verbose result. Note that this flag overrides json config. | bool |
false |
No |
Load Types
Linear
ddosify -t https://getanteon.com -l linearResult:
Note: If the iteration count is too low for the given duration, the test might be finished earlier than you expect.
Incremental
ddosify -t https://getanteon.com -l incrementalResult:
Waved
ddosify -t https://getanteon.com -l wavedResult:
Configuration
Configuration file lets you use all the capabilities of Ddosify.
The features you can use by config file:
- Scenario creation
- Environment variables
- Correlation
- Assertions
- Cookies
- Custom load type creation
- Payload from a file
- Multipart/form-data payload
- Extra connection configuration
- HTTP2 support
Usage:
ddosify -config <json_config_path>There is an example config file at config_examples/config.json. This file contains all of the parameters you can use. Details of each parameter;
iteration_count(optional)This is the equivalent of the
-nflag. The difference is that if you have multiple steps in your scenario, this value represents the iteration count of the steps.load_type(optional)This is the equivalent of the
-lflag.duration(optional)This is the equivalent of the
-dflag.manual_load(optional)If you are looking for creating your own custom load type, you can use this feature. The example below says that Ddosify will run the scenario 5 times, 10 times, and 20 times, respectively along with the provided durations.
iteration_countanddurationwill be auto-filled by Ddosify according tomanual_loadconfiguration. In this example,iteration_countwill be 35 and thedurationwill be 18 seconds.
Alsomanual_loadoverridesload_typeif you provide both of them. As a result, you don't need to provide these 3 parameters when usingmanual_load.json"manual_load": [ {"duration": 5, "count": 5}, {"duration": 6, "count": 10}, {"duration": 7, "count": 20} ]proxy(optional)This is the equivalent of the
-Pflag.output(optional)This is the equivalent of the
-oflag.engine_mode(optional)Can be one of
distinct-user,repeated-user, or default modeddosify.distinct-usermode simulates a new user for every iteration.repeated-usermode can use pre-used user in subsequent iterations.ddosifymode is default mode of the engine. In this mode engine runs in its max capacity, and does not show user simulation behaviour.
env(optional)Scenario-scoped global variables. Note that dynamic variables changes every iteration.
json"env": { "COMPANY_NAME" :"Ddosify", "randomCountry" : "{{_randomCountry}}" }data(optional)Config for loading test data from a CSV file.
CSV data used in below config.json"data":{ "info": { "path" : "config/config_testdata/test.csv", "delimiter": ";", "vars": { "0":{"tag":"name"}, "1":{"tag":"city"}, "2":{"tag":"team"}, "3":{"tag":"payload", "type":"json"}, "4":{"tag":"age", "type":"int"} }, "allow_quota" : true, "order": "sequential", "skip_first_line" : true, "skip_empty_line" : true } }Field Description Type Default Required? pathLocal path or remote url for your CSV file string- Yes delimiterDelimiter for reading CSV string,No varsTag columns using column index as key, use typefield if you want to cast a column to a specific type, default isstring, can be one of the following:json,int,float,bool.map- Yes allow_quotaIf set to true, a quote may appear in an unquoted field and a non-doubled quote may appear in a quoted field boolfalseNo orderOrder of reading records from CSV. Can be randomorsequentialstringrandomNo skip_first_lineSkips first line while reading records from CSV. boolfalseNo skip_empty_lineSkips empty lines while reading records from CSV. booltrueNo success_criterias(optional)Config for pass fail logic for the test. abort and delay fields can be used to adjust the abort behaviour in case of failure. If abort is true for a rule and rules fails at certain point, engine will decide to abort test immediately if delay is 0 or not given. If delay is given, it will wait for delay seconds and reassert the rule.
Example: Check 90th percentile and fail_count;
json{ "duration": 10, <other_global_configurations>, "success_criterias": [ { "rule" : "p90(iteration_duration) < 220", "abort" : false }, { "rule" : "fail_count_perc < 0.1", "abort" : true, "delay" : 1 }, { "rule" : "fail_count < 100", "abort" : true, "delay" : 0 } ], "steps": [....] }steps(required)This parameter lets you create your scenario. Ddosify runs the provided steps, respectively. For the given example file step id: 2 will be executed immediately after the response of step id: 1 is received. The order of the execution is the same as the order of the steps in the config file.
Details of each parameter for a step;
id(required)Each step must have a unique integer id.
url(required)This is the equivalent of the
-tflag.-
Name of the step.
method(optional)This is the equivalent of the
-mflag.headers(optional)List of headers with key:value format.
payload(optional)Body or payload. This is the equivalent of the
-bflag.Note: If you want to use
x-www-form-urlencoded, set Content-Type header toapplication/x-www-form-urlencoded.Example: send
x-www-form-urlencodeddata;json{ "headers": { "Content-Type": "application/x-www-form-urlencoded" }, "payload": "key1=value1&key2=value2" }payload_file(optional)If you need a long payload, we suggest using this parameter instead of
payload.-
Use this for
multipart/form-dataContent-Type.Accepts list of
form-fieldobjects, structured as below;json{ "name": [field-name], "value": [field-value|file-path|url], "type": <text|file>, // Default "text" "src": <local|remote> // Default "local" }Example: Sending form name-value pairs;
json"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]" } ]Example: Sending form name-value pairs and a local file;
json"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]", }, { "name": "[field-name]", "value": "./test.png", "type": "file" } ]Example: Sending form name-value pairs and a local file and a remote file;
json"payload_multipart": [ { "name": "[field-name]", "value": "[field-value]", }, { "name": "[field-name]", "value": "./test.png", "type": "file" }, { "name": "[field-name]", "value": "http://getanteon.com/test.png", "type": "file", "src": "remote" } ]Note: Ddosify adds
Content-Type: multipart/form-data; boundary=[generated-boundary-value]header to the request when usingpayload_multipart. timeout(optional)This is the equivalent of the
-Tflag.capture_env(optional)Config for extraction of variables to use them in next steps.
Example: Capture NUM variable from steps response body;json"steps": [ { "id": 1, "url": "http://getanteon.com/endpoint1", "capture_env": { "NUM" :{"from":"body","json_path":"num"}, } }, ]assertion(optional)The response from this step will be subject to the assertion rules. If one of the provided rules fails, step is considered as failure.
Example: Check status code and content-length header values;json"steps": [ { "id": 1, "url": "http://getanteon.com/endpoint1", "assertion": [ "equals(status_code,200)", "in(headers.content-length,[2000,3000])" ] }, ]-
Sleep duration(ms) before executing the next step. Can be an exact duration or a range.
Example: Sleep 1000ms after step-1;
json"steps": [ { "id": 1, "url": "http://getanteon.com/endpoint1", "sleep": "1000" }, { "id": 2, "url": "http://getanteon.com/endpoint2", } ]Example: Sleep between 300ms-500ms after step-1;
json"steps": [ { "id": 1, "url": "http://getanteon.com/endpoint1", "sleep": "300-500" }, { "id": 2, "url": "http://getanteon.com/endpoint2", } ] auth(optional)Basic authentication.
json"auth": { "username": "test_user", "password": "12345" }others(optional)This parameter accepts dynamic key: value pairs to configure connection details of the protocol in use.
json"others": { "disable-compression": false, // Default true "h2": true, // Enables HTTP/2. Default false. "disable-redirect": true // Default false }
Parameterization (Dynamic Variables)
Just like the Postman, Ddosify supports parameterization (dynamic variables) on URL, headers, payload (body) and basic authentication. Actually, we support all the random methods Postman supports. If you use {{$randomVariable}} on Postman you can use it as {{_randomVariable}} on Ddosify. Just change $ to _ and you will be fine. To simulate a realistic load test on your system, Ddosify can send every request with dynamic variables.
The full list of dynamic variables can be found in the documentation.
Parameterization on URL
Ddosify sends 100 GET requests in 10 seconds with random string key parameter. This approach can be also used in cache bypass.
ddosify -t https://getanteon.com/?key={{_randomString}} -d 10 -n 100Parameterization on Headers
Ddosify sends 100 GET requests in 10 seconds with random Transaction-Type and Country headers.
ddosify -t https://getanteon.com -d 10 -n 100 -h 'Transaction-Type: {{_randomTransactionType}}' -h 'Country: {{_randomCountry}}'Parameterization on Payload (Body)
Ddosify sends 100 GET requests in 10 seconds with random latitude and longitude values in body.
ddosify -t https://getanteon.com -d 10 -n 100 -b '{"latitude": "{{_randomLatitude}}", "longitude": "{{_randomLongitude}}"}'Parameterization on Basic Authentication
Ddosify sends 100 GET requests in 10 seconds with random username and password with basic authentication.
ddosify -t https://getanteon.com -d 10 -n 100 -a '{{_randomUserName}}:{{_randomPassword}}'Parameterization on Config File
Dynamic variables can be used on config file as well. Ddosify sends 100 GET requests in 10 seconds with random string key parameter in URL and random User-Key header.
ddosify -config ddosify_config_dynamic.json{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
"id": 1,
"url": "https://getanteon.com/?key={{_randomString}}",
"method": "POST",
"headers": {
"User-Key": "{{_randomInt}}"
}
}
]
}Environment Variables
In addition, you can also use operating system environment variables. To access these variables, simply add the $ prefix followed by the variable name wrapped in double curly braces. The syntax for this is {{$OS_ENV_VARIABLE}} within the config file.
For instance, to use the USER environment variable from your operating system, simply input {{$USER}}. You can use operating system environment variables in URL, Headers, Body (Payload), and Basic Authentication.
Here is an example of using operating system environment variables in the config file. TARGET_SITE operating system environment variable is used in URL and USER environment variable is used in Headers.
export TARGET_SITE="https://getanteon.com"
ddosify -config ddosify_config_os_env.json{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
"id": 1,
"url": "{{$TARGET_SITE}}",
"method": "POST",
"headers": {
"os-env-user": "{{$USER}}"
}
}
]
}Assertion
By default, Ddosify marks a step result as successful if it sends the request and receives the response without any network errors. Status code or body type (or content) does not affect the success/failure criteria. However, this may not provide a good test result for your use case, and you may want to create your own success/fail logic. That's where Assertions come in.
Ddosify supports assertions on status code, response body, response size, response time, headers, and variables. You can use the assertion parameter in the config file to check if the response matches the given condition per step. If the condition is not met, Ddosify will fail the step. Check the example config to see how it looks.
As shown in the related table, the first five keywords store different data related to the response. The last keyword, variables, stores the current state of environment variables for the step. You can use Functions or Operators to build conditional expressions based on these keywords.
You can write multiple assertions for a step. If any assertion fails, the step is marked as failed.
If Ddosify can't receive the response for a request, that step is marked as failed without processing the assertions. You will see a Server Error as the failure reason in the test result instead of an Assertion Error.
Keywords
| Keyword | Description | Usage |
|---|---|---|
status_code |
Status code | - |
body |
Response body | - |
response_size |
Response size in bytes | - |
response_time |
Response time in ms | - |
headers |
Response headers | headers.header-key |
variables |
Global and captured variables | variables.VarName |
Functions
| Function | Parameters | Description |
|---|---|---|
less_than |
( param int, limit int ) |
checks if param is less than limit |
greater_than |
( param int, limit int ) |
checks if param is greater than limit |
exists |
( param any ) |
checks if variable exists |
equals |
( param1 any, param2 any ) |
checks if given parameters are equal |
equals_on_file |
( param any, file_path string ) |
reads from given file path and checks if it equals to given parameter |
in |
( param any, array_param array ) |
checks if expression is in given array |
contains |
( param1 any, param2 any ) |
makes substring with param1 inside param2 |
not |
( param bool ) |
returns converse of given param |
range |
( param int, low int,high int ) |
returns param is in range of [low,high): low is included, high is not included. |
json_path |
( json_path string) |
extracts from response body using given json path |
xpath |
( xpath string ) |
extracts from response body using given xml path |
html_path |
( html string ) |
extracts from response body using given html path |
regexp |
( param any, regexp string, matchNo int ) |
extracts from given value in the first parameter using given regular expression |
Operators
| Operator | Description |
|---|---|
== |
equals |
!= |
not equals |
> |
greater than |
< |
less than |
! |
not |
&& |
and |
|| |
or |
Assertion Examples
| Expression | Description |
|---|---|
less_than(status_code,201) |
checks if status code is less than 201 |
equals(status_code,200) |
checks if status code equals to 200 |
status_code == 200 |
same as preceding one |
not(status_code == 500) |
checks if status code not equals to 500 |
status_code != 500 |
same as preceding one |
equals(json_path(\"employees.0.name\"),\"Name\") |
checks if json extracted value is equal to "Name" |
equals(xpath(\"//item/title\"),\"ABC\") |
checks if xml extracted value is equal to "ABC" |
equals(html_path(\"//body/h1\"),\"ABC\") |
checks if html extracted value is equal to "ABC" |
equals(variables.x,100) |
checks if x variable coming from global or captured variables is equal to 100 |
equals(variables.x,variables.y) |
checks if variables x and y are equal to each other |
equals_on_file(body,\"file.json\") |
reads from file.json and compares response body with read file |
exists(headers.Content-Type) |
checks if content-type header exists in response headers |
contains(body,\"xyz\") |
checks if body contains "xyz" in it |
range(headers.content-length,100,300) |
checks if content-length header is in range [100,300) |
in(status_code,[200,201]) |
checks if status code equal to 200 or 201 |
(status_code == 200) || (status_code == 201) |
same as preceding one |
regexp(body,\"[a-z]+_[0-9]+\",0) == \"messi_10\" |
checks if matched result from regex is equal to "messi_10" |
Success Criteria (Pass / Fail)
Ddosify supports success criteria, allowing users to verify the success of their load tests based on response times and failure counts of iterations. With this feature, users can assert the percentile of response times and the failure counts of all iterations in a test.
Users can specify the required percentile of response times and failure counts in the configuration file, and the engine will compare the actual response times and failure counts to these values throughout the test continuously. According to the user's configuration, the test can be aborted or continue running until the end. Check the example config to see how the success_criterias keyword looks.
Note that the functions and operators mentioned in the Step Assertion section can also be utilized for the Success Criteria keywords listed below.
You can see a success criteria example in the EXAMPLES file.
Difference Between Success Criteria and Step Assertions
Unlike assertions focused on individual steps, which determine the success or failure of a step according to its response, Success Criteria create an abort/continue logic for the entire test, which is based on the accumulated data from all iterations.
Keywords
| Keyword | Description | Usage |
|---|---|---|
fail_count |
Failure count of iterations | Used for aborting when test exceeds certain fail_count |
iteration_duration |
Response times of iterations in ms | Used for percentile functions |
fail_count_perc |
Fail count percentage, in range [0,1] | Used for aborting when test exceeds certain fail count percentage |
Functions
| Function | Parameters | Description |
|---|---|---|
p99 |
( arr int array ) |
99th percentile, use as p99(iteration_duration) |
p98 |
( arr int array ) |
98th percentile, use as p98(iteration_duration) |
p95 |
( arr int array) |
95th percentile, use as p95(iteration_duration) |
p90 |
( arr int array) |
90th percentile, use as p90(iteration_duration) |
p80 |
( arr int array) |
80th percentile, use as p80(iteration_duration) |
min |
( arr int array) |
returns minimum element |
max |
( arr int array) |
returns maximum element |
avg |
( arr int array) |
calculates and returns average |
Examples
| Expression | Description |
|---|---|
p95(iteration_duration) < 100 |
95th percentile should be less than 100 ms |
less_than(fail_count,120) |
Total fail count should be less than 120 |
less_than(fail_count_perc,0.05) |
Fail count percentage should be less than 5% |
Correlation
Ddosify enables you to capture variables from steps using json_path, xpath, xpath_html, or regular expressions. Later, in the subsequent steps, you can inject both the captured variables and the scenario-scoped global variables.
:warning: Points to keep in mind
- You must specify 'header_key' when capturing from header.
- For json_path syntax, please take a look at gjson syntax doc.
- Regular expression are expected in 'Golang' style regex. For converting your existing regular expressions, you can use regex101.
- You can extract values from headers, body, and cookies.
You can use debug parameter to validate your config.
ddosify -config ddosify_config_correlation.json -debugCapture with json_path
{
"steps": [
{
"capture_env": {
"NUM": { "from": "body", "json_path": "num" },
"NAME": { "from": "body", "json_path": "name" },
"SQUAD": { "from": "body", "json_path": "squad" },
"PLAYERS": { "from": "body", "json_path": "squad.players" },
"MESSI": { "from": "body", "json_path": "squad.players.0" }
}
}
]
}Capture with XPath on XML
{
"steps": [
{
"capture_env": {
"TITLE": { "from": "body", "xpath": "//item/title" }
}
}
]
}Capture with XPath on HTML
{
"steps": [
{
"capture_env": {
"TITLE": { "from": "body", "xpath_html": "//body/h1" }
}
}
]
}Capture with Regular Expressions
{
"steps": [
{
"capture_env": {
"CONTENT_TYPE": {
"from": "header",
"header_key": "Content-Type",
"regexp": { "exp": "application/(\\w)+", "matchNo": 0 }
},
"REGEX_MATCH_ENV": {
"from": "body",
"regexp": { "exp": "[a-z]+_[0-9]+", "matchNo": 1 }
}
}
}
]
}Capture Header Value
{
"steps": [
{
"capture_env": {
"TOKEN": { "from": "header", "header_key": "Authorization" }
}
}
]
}Scenario-Scoped Variables
{
"env": {
"TARGET_URL": "http://localhost:8084/hello",
"USER_KEY": "ABC",
"COMPANY_NAME": "Ddosify",
"RANDOM_COUNTRY": "{{_randomCountry}}",
"NUMBERS": [22, 33, 10, 52]
}
}Overall Config and Injection
On array-like captured variables or environment vars, the rand( ) function can be utilized.
// ddosify_config_correlation.json
{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
"id": 1,
"url": "{{TARGET_URL}}",
"method": "POST",
"headers": {
"User-Key": "{{USER_KEY}}",
"Rand-Selected-Num": "{{rand(NUMBERS)}}"
},
"payload": "{{COMPANY_NAME}}",
"capture_env": {
"NUM": { "from": "body", "json_path": "num" },
"NAME": { "from": "body", "json_path": "name" },
"SQUAD": { "from": "body", "json_path": "squad" },
"PLAYERS": { "from": "body", "json_path": "squad.players" },
"MESSI": { "from": "body", "json_path": "squad.players.0" },
"TOKEN": { "from": "header", "header_key": "Authorization" },
"CONTENT_TYPE": {
"from": "header",
"header_key": "Content-Type",
"regexp": { "exp": "application/(\\w)+", "matchNo": 0 }
}
}
},
{
"id": 2,
"url": "{{TARGET_URL}}",
"method": "POST",
"headers": {
"User-Key": "{{USER_KEY}}",
"Authorization": "{{TOKEN}}",
"Content-Type": "{{CONTENT_TYPE}}"
},
"payload_file": "payload.json",
"capture_env": {
"TITLE": { "from": "body", "xpath": "//item/title" },
"REGEX_MATCH_ENV": {
"from": "body",
"regexp": { "exp": "[a-z]+_[0-9]+", "matchNo": 1 }
}
}
}
],
"env": {
"TARGET_URL": "http://localhost:8084/hello",
"USER_KEY": "ABC",
"COMPANY_NAME": "Ddosify",
"RANDOM_COUNTRY": "{{_randomCountry}}",
"NUMBERS": [22, 33, 10, 52]
}
}// payload.json
{
"boolField": "{{_randomBoolean}}",
"numField": "{{NUM}}",
"strField": "{{NAME}}",
"numArrayField": ["{{NUM}}", 34],
"strArrayField": ["{{NAME}}", "hello"],
"mixedArrayField": ["{{NUM}}", 34, "{{NAME}}", "{{SQUAD}}"],
"{{NAME}}": "messi",
"obj": {
"numField": "{{NUM}}",
"objectField": "{{SQUAD}}",
"arrayField": "{{PLAYERS}}"
}
}Test Data Set
Ddosify enables you to load test data from CSV files. Later, in your scenario, you can inject variables that you tagged.
We are using this CSV data in config below.
// config_data_csv.json
"data":{
"csv_test": {
"path" : "config/config_testdata/test.csv",
"delimiter": ";",
"vars": {
"0":{"tag":"name"},
"1":{"tag":"city"},
"2":{"tag":"team"},
"3":{"tag":"payload", "type":"json"},
"4":{"tag":"age", "type":"int"}
},
"allow_quota" : true,
"order": "random",
"skip_first_line" : true
}
}You can refer to tagged variables in your request like below.
// payload.json
{
"name": "{{data.csv_test.name}}",
"team": "{{data.csv_test.team}}",
"city": "{{data.csv_test.city}}",
"payload": "{{data.csv_test.payload}}",
"age": "{{data.csv_test.age}}"
}Cookies
Ddosify supports cookies in the following engine modes: distinct-user and repeated-user. Cookies are not supported in the default ddosify mode.
In repeated-user mode, Ddosify uses the same cookie jar for all iterations executed by the same user. It sets cookies returned at the first successful iteration and does not change them afterward. This way, the same cookies are passed through steps in all iterations executed by the same user.
In distinct-user mode, Ddosify uses a different cookie jar for each iteration, so cookies are passed through steps in one iteration only.
You can see a cookie example in the EXAMPLES file.
Initial / Custom Cookies
You can set initial/custom cookies for your test scenario using cookie_jar field in the config file. You can enable/disable custom cookies with enabled key. Check the example config.
| Key | Description | Example |
|---|---|---|
name |
The name of the cookie. This field is used to identify the cookie. | platform |
value |
The value of the cookie. This field contains the data that the cookie stores. | web |
domain |
Domain or subdomain that can access the cookie. | app.getanteon.com |
path |
Path within the domain that can access the cookie. | / |
expires |
When the cookie should expire. The date format should be rfc2616. | Thu, 16 Mar 2023 09:24:02 GMT |
max_age |
Number of seconds until the cookie expires. | 5 |
http_only |
Whether the cookie should only be accessible through HTTP or HTTPS headers, and not through client-side scripts | true |
secure |
Whether the cookie should only be sent over a secure (HTTPS) connection | false |
raw |
The raw format of the cookie. If it is used, the other keys are discarded. | myCookie=myValue; Expires=Wed, 21 Oct 2026 07:28:00 GMT; Path=/ |
Cookie Capture
You can capture values from cookies from its name just like you do for headers and body and use them in your test scenario.
{
"iteration_count": 100,
"load_type": "linear",
"duration": 10,
"steps": [
{
...
"capture_env": {
"TEST" :{"from":"cookies","cookie_name":"test"}
}
}
]
}Cookie Assertion
You can refer to cookie values as cookies.cookie_name while you write assertions for your steps.
Following fields are available for cookie assertion:
name: Name of the cookiedomain: Domain of the cookiepath: Path of the cookievalue: Value of the cookieexpires: Expiration date of the cookiemaxAge: Max age of the cookiesecure: Secure flag of the cookiehttpOnly: Http only flag of the cookierawExpires: Raw expiration date of the cookie
Examples:
cookies.test.expires < time(\"Thu, 01 Jan 1990 00:00:00 GMT\")is a valid assertion expression. It checks if the cookie namedtesthas an expiration date beforeThu, 01 Jan 1990 00:00:00 GMT.cookies.test.path == \"/login\"is another valid assertion expression. It checks if the cookie namedtesthas a path value equal to/login.
Common Issues
macOS Security Issue
"ddosify" canβt be opened because Apple cannot check it for malicious software.- Open
/usr/local/bin - Right click
ddosifyand select Open - Select Open
- Close the opened terminal
OS Limit - Too Many Open Files
If you create large load tests, you may encounter the following errors:
Server Error Distribution (Count:Reason):
199 :Get "https://getanteon.com": dial tcp 188.114.96.3:443: socket: too many open files
159 :Get "https://getanteon.com": dial tcp 188.114.97.3:443: socket: too many open filesThis is because the OS limits the number of open files. You can check the current limit by running ulimit -n command. You can increase this limit to 50000 by running the following command on both Linux and macOS.
ulimit -n 50000But this will only increase the limit for the current session. To increase the limit permanently, you can change the shell configuration file. For example, if you are using bash, you can add the following lines to ~/.bashrc file. If you are using zsh, you can add the following lines to ~/.zshrc file.
# For .bashrc
echo "ulimit -n 50000" >> ~/.bashrc
# For .zshrc
echo "ulimit -n 50000" >> ~/.zshrcContributing
See our Contribution Guide and please follow the Code of Conduct in all your interactions with the project.
Communication
You can join our Discord Server for issues, feature requests, feedbacks or anything else.
Disclaimer
Ddosify is created for testing the performance of web applications. Users must be the owner of the target system. Using it for harmful purposes is extremely forbidden. Ddosify team & company is not responsible for itsβ usages and consequences.
License
Licensed under the AGPLv3
File: selfhosted/README.md
Anteon Self Hosted: Effortless Kubernetes Monitoring and Performance Testing
π Documentation
- π Installing Anteon Self-Hosted
- β Installing eBPF Agent (Alaz)
- π° Upgrading to Self-Hosted Enterprise
- π§ Slack Integration
See the documentation for other guides such as disabling telemetry.
π License
Anteon Self Hosted is licensed under the AGPLv3