Skip to content

omerfarukz/WebBen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

WebBen[chmark]

nuget license Lines of Code

Security Rating Maintainability Rating Code Smells Technical Debt Reliability Rating Vulnerabilities Bugs

Cross platform HTTP Server benchmark tool written in .NET 6.0. Declarative and easy to use. Execute test cases and compare the results. Parallelize the execution of test cases.

Runs on MacOS, Linux and Windows. For additional information see all supported platforms.

Installation

dotnet tool install --global webben

Usage samples

webben [command] [options]

Commands:
  config <fileInfo>
  uri <uri>
  analyse, analyze <uri>

Options:
  -v, --verbose                       Enable verbose output
  -e, --export-format <Default|Json>  Export format [default: Default]
  -?, -h, --help                      Show help and usage information

Example:
  webben config <filePath>

Output:
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚Name         โ”‚Elapsedโ”‚NoRโ”‚Pllโ”‚Errโ”‚Avg(ms) โ”‚StdDev(ms)โ”‚Median(ms)โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚get_simple_1 โ”‚2.13   โ”‚100โ”‚100โ”‚0  โ”‚2,083.83โ”‚11.66     โ”‚2,080.86  โ”‚
โ”‚get_simple_2 โ”‚2.03   โ”‚100โ”‚100โ”‚0  โ”‚2,017.24โ”‚7.21      โ”‚2,017.62  โ”‚
โ”‚post_simple_1โ”‚2.09   โ”‚100โ”‚500โ”‚0  โ”‚2,022.46โ”‚5.07      โ”‚2,020.69  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
webben uri <uri> [options]

Arguments:
  <uri>  The URI to use.

Options:
  -f, --fetch-content       Whether to fetch the content of the URI.
  -l, --name                Name or label
  -m, --http-method         The HTTP method to use.
  -n, --request-count       The number of requests to make.
  -p, --parallelism         The number of parallelism to use.
  -r, --allow-redirect      Whether to allow redirects.
  -t, --timeout-in-ms       The timeout in milliseconds.
  
Examples:
  webben uri http://localhost:3000
  webben uri http://localhost:3000 -n 10000
  webben uri http://localhost:3000 -p 100 -b 50 -t 5000 -m GET -f false -r false -n 10000

Output:
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚Name          โ”‚Elapsedโ”‚NoRโ”‚Pllโ”‚Errโ”‚Avg(ms)โ”‚StdDev(ms)โ”‚Median(ms)โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚initial_test_1โ”‚0.67   โ”‚10 โ”‚100โ”‚0  โ”‚456.69 โ”‚82.85     โ”‚423.60    โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
Usage:
  webben analyze <uri> [options]
  webben analyse <uri> [options]

Arguments:
  <uri>  The URI to use.

Options:
  -f, --fetch-content                                      Whether to fetch the content of the URI.
  -r, --allow-redirect                                     Whether to allow redirects.
  -t, --timeout-in-ms <timeout-in-ms>                      The bounded capacity to use.
  -m, --max-trial-count <max-trial-count>                  Iteration count for calculation. See -c
  -c, --calculation-function <Average|Median|P70|P80|P90>  Function for RPS calculation

Examples:
  analyze "https://contoso.com/?q=test"
  analyze "https://contoso.com/?q=test" -c Median  
  analyze "https://contoso.com/?q=test" -m 5 -c P80

Output:
# Analyze result including max requests count per second
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚Name            โ”‚Elapsed(sec)โ”‚NoRโ”‚Pllโ”‚Errโ”‚Avg(ms)โ”‚StdDev(ms)โ”‚Median(ms)โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚2206260057093580โ”‚0.52        โ”‚1  โ”‚1  โ”‚0  โ”‚503.35 โ”‚0.00      โ”‚503.35    โ”‚
โ”‚2206260057093580โ”‚0.29        โ”‚2  โ”‚2  โ”‚0  โ”‚283.28 โ”‚1.34      โ”‚283.28    โ”‚
โ”‚2206260057093580โ”‚0.29        โ”‚4  โ”‚4  โ”‚0  โ”‚282.62 โ”‚11.45     โ”‚286.21    โ”‚
โ”‚2206260057093580โ”‚0.29        โ”‚8  โ”‚8  โ”‚0  โ”‚280.83 โ”‚8.95      โ”‚284.91    โ”‚
โ”‚2206260057093580โ”‚0.36        โ”‚16 โ”‚16 โ”‚0  โ”‚316.97 โ”‚19.17     โ”‚317.60    โ”‚
โ”‚2206260057093580โ”‚0.71        โ”‚32 โ”‚32 โ”‚0  โ”‚658.79 โ”‚30.66     โ”‚661.04    โ”‚
โ”‚2206260057093580โ”‚0.60        โ”‚64 โ”‚64 โ”‚0  โ”‚503.19 โ”‚59.68     โ”‚492.96    โ”‚
โ”‚2206260057093580โ”‚0.86        โ”‚128โ”‚128โ”‚0  โ”‚707.93 โ”‚87.33     โ”‚723.58    โ”‚
โ”‚2206260057093580โ”‚1.63        โ”‚256โ”‚256โ”‚0  โ”‚997.16 โ”‚161.11    โ”‚997.03    โ”‚
โ”‚2206260057093580โ”‚1.14        โ”‚129โ”‚129โ”‚0  โ”‚728.80 โ”‚72.92     โ”‚724.38    โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚MaxRPSโ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 128  โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Analyzing session

analyze2

Configuration Sample

{
  "TestCaseConfigurations": [
    {
      "Name": "get_simple_1",
      "Uri": "http://localhost:3000/api/v1/posts/foo"
    },
    {
      "Name": "get_simple_2",
      "Uri": "http://localhost:3000/api/v1/posts/bar"
    },
    {
      "Name": "post_simple_1",
      "Uri": "http://localhost:3000/api/v1/posts",
      "HttpMethod": "POST",
      "NumberOfRequests": 500,
      "FetchContent": false,
      "Parallelism": 500,
      "BoundedCapacity": 500,
      "Headers": {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
      },
      "Cookies": {
        "X-Session-Id": "44c00ac0-eae8-11ec-8fea-0242ac120002"
      },
      "Body": {
        "Content": "{\"name\":\"test\"}",
        "ContentType": "application/json",
        "Encoding": "utf-8"
      }
    }
  ]
}

Usage

./webben config samples/Multiple.json

Output ( Default Formatter )

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚Name         โ”‚Elapsedโ”‚NoRโ”‚Pllโ”‚Errโ”‚Avg     โ”‚P90     โ”‚Median  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚get_simple_1 โ”‚2.13   โ”‚100โ”‚100โ”‚0  โ”‚2,081.37โ”‚2,078.92โ”‚2,078.47โ”‚
โ”‚get_simple_2 โ”‚2.03   โ”‚100โ”‚100โ”‚0  โ”‚2,015.18โ”‚2,025.14โ”‚2,013.66โ”‚
โ”‚post_simple_1โ”‚2.08   โ”‚100โ”‚500โ”‚0  โ”‚2,019.53โ”‚2,023.18โ”‚2,019.60โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

Usage

./webben config samples/Multiple.json -e Json

Output ( JSON Formatter )

[{
  "Configuration": {
    "HttpMethod": "GET",
    "RequestCount": 100,
    "Parallelism": 100,
    "UseDefaultCredentials": false,
    "UseCookieContainer": false,
    "MaxBufferSize": 2147483647,
    "Name": "get_simple_1",
    "Uri": "http://localhost:3000/api/v1/posts/foo",
    "FetchContent": false,
    "AllowRedirect": false,
    "TimeoutInMs": 2147483647
  },
  "Timings": [
    "00:00:02.0780162",
    "...",
    "00:00:02.0726471"
  ],
  "Errors": [],
  "Elapsed": "00:00:02.1292561"
},
{
  "Configuration": {
    "HttpMethod": "GET",
    "RequestCount": 100,
    "Parallelism": 100,
    "UseDefaultCredentials": false,
    "UseCookieContainer": false,
    "MaxBufferSize": 2147483647,
    "Name": "get_simple_2",
    "Uri": "http://localhost:3000/api/v1/posts/bar",
    "FetchContent": false,
    "AllowRedirect": false,
    "TimeoutInMs": 2147483647
  },
  "Timings": [
    "00:00:02.0278468",
    "...",
    "00:00:02.0277827"
  ],
  "Errors": [],
  "Elapsed": "00:00:02.0749580"
}]

Other features

Support for authentication, cookie containers, and default credentials. It is possible to use the same credential configuration for multiple test cases. The credential configuration is specified by the CredentialConfigurationKey property.

{
  "CredentialConfigurations": [
    {
      "Key": "cred_1",
      "Provider": "NetworkCredentialProvider",
      "Data": {
        "username": "foo",
        "password": "bar"
      }
    }
  ]
}

Http request headers can be specified.

{
  "TestCaseConfigurations": [
    {
      "Name": "post_simple_1",
      "Uri": "http://localhost:3000",
      "HttpMethod": "POST",
      "NumberOfRequests": 10000,
      "FetchContent": false,
      "Parallelism": 500,
      "BoundedCapacity": 500,
      "Headers": {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
      },
      "Body": {
        "Content": "{\"name\":\"test\"}",
        "ContentType": "application/json",
        "Encoding": "utf-8"
      }
    }
  ]
}

Http request

Http requests created by WebBen are not actually sent to the server. Instead, they are stored in a queue. The queue is processed by multiple threads depending on the parallelism.

POST / HTTP/1.1
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) WebBen/1.2206
Content-Type: application/json; charset=utf-8
Content-Length: 15

{"name":"test"}

WebBen is just a simple tool to generate http requests. You can combine it with other tools to make more complex tasks. For example, you can use WebBen to generate requests and then use another tool to send them to the your backend.

Example

webben uri https://url-to-benchmark.local/pages/1 -e json | \
curl -H "Content-Type: application/json" \
    -X POST \
    --data-binary @- \
    https://your-awesome-backend.local/api/v1/posts
    

POST / HTTP/1.1
Host: your-awesome-backend.local
User-Agent: curl/7.79.1
Accept: */*
Content-Type: application/json
Content-Length: 1042

{
  "Items": [
    {
      "Timings": [
        "00:00:00.5772976",
        "00:00:00.5528780",
        "00:00:00.5148466",
        "00:00:00.5118757",
        "00:00:00.5118554",
        "00:00:00.4524819",
        "00:00:00.5113236",
        "00:00:00.5117843",
        "00:00:00.5148185",
        "00:00:00.4524458"
      ],
      "Errors": [],
      "Elapsed": "00:00:00.5938226",
      "Configuration": {
        "HttpMethod": "GET",
        "RequestCount": 10,
        "Parallelism": 10,
        "UseDefaultCredentials": false,
        "UseCookieContainer": false,
        "MaxBufferSize": 2147483647,
        "Name": "iteration1",
        "Uri": "https://url-to-benchmark.local/pages/1",
        "FetchContent": false,
        "AllowRedirect": true,
        "TimeoutInMs": 2147483647
      },
      "Calculations": {
        "Average": "00:00:00.5111607",
        "StdDev": "00:00:00.0361018",
        "P90": "00:00:00.5772976",
        "P80": "00:00:00.5528780",
        "P70": "00:00:00.5148466",
        "Median": "00:00:00.5118655"
      }
    }
  ]
}

๐Ÿ˜‹ How to contribute

Have an idea? Found a bug? Contributions are always welcome.

  • Open an issue or create a pull request.
  • Share with your friends.
  • Give a Star.

Thanks! โค๏ธ