{"id":13414978,"url":"https://github.com/omerfarukz/WebBen","last_synced_at":"2025-03-14T22:32:38.314Z","repository":{"id":37582029,"uuid":"501378934","full_name":"omerfarukz/WebBen","owner":"omerfarukz","description":"Cross platform HTTP server benchmark tool","archived":false,"fork":false,"pushed_at":"2024-01-28T11:52:54.000Z","size":465,"stargazers_count":11,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-11T05:05:07.767Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/omerfarukz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-06-08T19:08:57.000Z","updated_at":"2024-06-26T08:36:37.000Z","dependencies_parsed_at":"2024-01-28T13:17:41.848Z","dependency_job_id":"4f649766-2aa4-4a4e-933f-3649bd18aaa6","html_url":"https://github.com/omerfarukz/WebBen","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omerfarukz%2FWebBen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omerfarukz%2FWebBen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omerfarukz%2FWebBen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omerfarukz%2FWebBen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omerfarukz","download_url":"https://codeload.github.com/omerfarukz/WebBen/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221513939,"owners_count":16835746,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T21:00:40.715Z","updated_at":"2024-10-26T08:30:52.324Z","avatar_url":"https://github.com/omerfarukz.png","language":"C#","readme":"# WebBen[chmark]\n\n[![nuget](https://img.shields.io/nuget/dt/webben)](https://www.nuget.org/packages/webben) \n[![license](https://img.shields.io/github/license/omerfarukz/WebBen)](https://github.com/omerfarukz/WebBen/blob/master/LICENSE.txt)\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=ncloc)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=security_rating)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=code_smells)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=omerfarukz_WebBen\u0026metric=bugs)](https://sonarcloud.io/summary/new_code?id=omerfarukz_WebBen)\n\nCross platform HTTP Server benchmark tool written in .NET 6.0. Declarative and easy to use. Execute test cases and\ncompare the\nresults. Parallelize the execution of test cases.\n\nRuns on MacOS, Linux and Windows. For additional\ninformation see [all supported platforms](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md).\n\n## Installation\n\n```shell\ndotnet tool install --global webben\n```\n\n## Usage samples\n\n```shell\nwebben [command] [options]\n\nCommands:\n  config \u003cfileInfo\u003e\n  uri \u003curi\u003e\n  analyse, analyze \u003curi\u003e\n\nOptions:\n  -v, --verbose                       Enable verbose output\n  -e, --export-format \u003cDefault|Json\u003e  Export format [default: Default]\n  -?, -h, --help                      Show help and usage information\n\nExample:\n  webben config \u003cfilePath\u003e\n\nOutput:\n╭─────────────┬───────┬───┬───┬───┬────────┬──────────┬──────────╮\n│Name         │Elapsed│NoR│Pll│Err│Avg(ms) │StdDev(ms)│Median(ms)│\n├─────────────┼───────┼───┼───┼───┼────────┼──────────┼──────────┤\n│get_simple_1 │2.13   │100│100│0  │2,083.83│11.66     │2,080.86  │\n│get_simple_2 │2.03   │100│100│0  │2,017.24│7.21      │2,017.62  │\n│post_simple_1│2.09   │100│500│0  │2,022.46│5.07      │2,020.69  │\n╰─────────────┴───────┴───┴───┴───┴────────┴──────────┴──────────╯\n```\n\n```shell\nwebben uri \u003curi\u003e [options]\n\nArguments:\n  \u003curi\u003e  The URI to use.\n\nOptions:\n  -f, --fetch-content       Whether to fetch the content of the URI.\n  -l, --name                Name or label\n  -m, --http-method         The HTTP method to use.\n  -n, --request-count       The number of requests to make.\n  -p, --parallelism         The number of parallelism to use.\n  -r, --allow-redirect      Whether to allow redirects.\n  -t, --timeout-in-ms       The timeout in milliseconds.\n  \nExamples:\n  webben uri http://localhost:3000\n  webben uri http://localhost:3000 -n 10000\n  webben uri http://localhost:3000 -p 100 -b 50 -t 5000 -m GET -f false -r false -n 10000\n\nOutput:\n╭──────────────┬───────┬───┬───┬───┬───────┬──────────┬──────────╮\n│Name          │Elapsed│NoR│Pll│Err│Avg(ms)│StdDev(ms)│Median(ms)│\n├──────────────┼───────┼───┼───┼───┼───────┼──────────┼──────────┤\n│initial_test_1│0.67   │10 │100│0  │456.69 │82.85     │423.60    │\n╰──────────────┴───────┴───┴───┴───┴───────┴──────────┴──────────╯\n\n```\n\n```shell\nUsage:\n  webben analyze \u003curi\u003e [options]\n  webben analyse \u003curi\u003e [options]\n\nArguments:\n  \u003curi\u003e  The URI to use.\n\nOptions:\n  -f, --fetch-content                                      Whether to fetch the content of the URI.\n  -r, --allow-redirect                                     Whether to allow redirects.\n  -t, --timeout-in-ms \u003ctimeout-in-ms\u003e                      The bounded capacity to use.\n  -m, --max-trial-count \u003cmax-trial-count\u003e                  Iteration count for calculation. See -c\n  -c, --calculation-function \u003cAverage|Median|P70|P80|P90\u003e  Function for RPS calculation\n\nExamples:\n  analyze \"https://contoso.com/?q=test\"\n  analyze \"https://contoso.com/?q=test\" -c Median  \n  analyze \"https://contoso.com/?q=test\" -m 5 -c P80\n\nOutput:\n# Analyze result including max requests count per second\n╭────────────────┬────────────┬───┬───┬───┬───────┬──────────┬──────────╮\n│Name            │Elapsed(sec)│NoR│Pll│Err│Avg(ms)│StdDev(ms)│Median(ms)│\n├────────────────┼────────────┼───┼───┼───┼───────┼──────────┼──────────┤\n│2206260057093580│0.52        │1  │1  │0  │503.35 │0.00      │503.35    │\n│2206260057093580│0.29        │2  │2  │0  │283.28 │1.34      │283.28    │\n│2206260057093580│0.29        │4  │4  │0  │282.62 │11.45     │286.21    │\n│2206260057093580│0.29        │8  │8  │0  │280.83 │8.95      │284.91    │\n│2206260057093580│0.36        │16 │16 │0  │316.97 │19.17     │317.60    │\n│2206260057093580│0.71        │32 │32 │0  │658.79 │30.66     │661.04    │\n│2206260057093580│0.60        │64 │64 │0  │503.19 │59.68     │492.96    │\n│2206260057093580│0.86        │128│128│0  │707.93 │87.33     │723.58    │\n│2206260057093580│1.63        │256│256│0  │997.16 │161.11    │997.03    │\n│2206260057093580│1.14        │129│129│0  │728.80 │72.92     │724.38    │\n╰────────────────┴────────────┴───┴───┴───┴───────┴──────────┴──────────╯\n╭──────╮\n│MaxRPS│\n├──────┤\n│ 128  │\n╰──────╯\n\n```\n\n### Analyzing session\n\n![analyze2](https://raw.githubusercontent.com/omerfarukz/WebBen/master/Assets/analyze2.gif)\n\n## Configuration Sample\n\n```json\n{\n  \"TestCaseConfigurations\": [\n    {\n      \"Name\": \"get_simple_1\",\n      \"Uri\": \"http://localhost:3000/api/v1/posts/foo\"\n    },\n    {\n      \"Name\": \"get_simple_2\",\n      \"Uri\": \"http://localhost:3000/api/v1/posts/bar\"\n    },\n    {\n      \"Name\": \"post_simple_1\",\n      \"Uri\": \"http://localhost:3000/api/v1/posts\",\n      \"HttpMethod\": \"POST\",\n      \"NumberOfRequests\": 500,\n      \"FetchContent\": false,\n      \"Parallelism\": 500,\n      \"BoundedCapacity\": 500,\n      \"Headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\"\n      },\n      \"Cookies\": {\n        \"X-Session-Id\": \"44c00ac0-eae8-11ec-8fea-0242ac120002\"\n      },\n      \"Body\": {\n        \"Content\": \"{\\\"name\\\":\\\"test\\\"}\",\n        \"ContentType\": \"application/json\",\n        \"Encoding\": \"utf-8\"\n      }\n    }\n  ]\n}\n```\n\n### Usage\n\n```shell\n./webben config samples/Multiple.json\n```\n\n### Output ( Default Formatter )\n\n```shell\n╭─────────────┬───────┬───┬───┬───┬────────┬────────┬────────╮\n│Name         │Elapsed│NoR│Pll│Err│Avg     │P90     │Median  │\n├─────────────┼───────┼───┼───┼───┼────────┼────────┼────────┤\n│get_simple_1 │2.13   │100│100│0  │2,081.37│2,078.92│2,078.47│\n│get_simple_2 │2.03   │100│100│0  │2,015.18│2,025.14│2,013.66│\n│post_simple_1│2.08   │100│500│0  │2,019.53│2,023.18│2,019.60│\n╰─────────────┴───────┴───┴───┴───┴────────┴────────┴────────╯\n```\n\n### Usage\n\n```shell\n./webben config samples/Multiple.json -e Json\n```\n\n### Output ( JSON Formatter )\n\n```json\n[{\n  \"Configuration\": {\n    \"HttpMethod\": \"GET\",\n    \"RequestCount\": 100,\n    \"Parallelism\": 100,\n    \"UseDefaultCredentials\": false,\n    \"UseCookieContainer\": false,\n    \"MaxBufferSize\": 2147483647,\n    \"Name\": \"get_simple_1\",\n    \"Uri\": \"http://localhost:3000/api/v1/posts/foo\",\n    \"FetchContent\": false,\n    \"AllowRedirect\": false,\n    \"TimeoutInMs\": 2147483647\n  },\n  \"Timings\": [\n    \"00:00:02.0780162\",\n    \"...\",\n    \"00:00:02.0726471\"\n  ],\n  \"Errors\": [],\n  \"Elapsed\": \"00:00:02.1292561\"\n},\n{\n  \"Configuration\": {\n    \"HttpMethod\": \"GET\",\n    \"RequestCount\": 100,\n    \"Parallelism\": 100,\n    \"UseDefaultCredentials\": false,\n    \"UseCookieContainer\": false,\n    \"MaxBufferSize\": 2147483647,\n    \"Name\": \"get_simple_2\",\n    \"Uri\": \"http://localhost:3000/api/v1/posts/bar\",\n    \"FetchContent\": false,\n    \"AllowRedirect\": false,\n    \"TimeoutInMs\": 2147483647\n  },\n  \"Timings\": [\n    \"00:00:02.0278468\",\n    \"...\",\n    \"00:00:02.0277827\"\n  ],\n  \"Errors\": [],\n  \"Elapsed\": \"00:00:02.0749580\"\n}]\n```\n\n## Other features\n\nSupport for authentication, cookie containers, and default credentials. It is possible to use the same credential\nconfiguration for multiple test cases. The credential configuration is specified by the `CredentialConfigurationKey`\nproperty.\n\n```json\n{\n  \"CredentialConfigurations\": [\n    {\n      \"Key\": \"cred_1\",\n      \"Provider\": \"NetworkCredentialProvider\",\n      \"Data\": {\n        \"username\": \"foo\",\n        \"password\": \"bar\"\n      }\n    }\n  ]\n}\n```\n\nHttp request headers can be specified.\n\n```json\n{\n  \"TestCaseConfigurations\": [\n    {\n      \"Name\": \"post_simple_1\",\n      \"Uri\": \"http://localhost:3000\",\n      \"HttpMethod\": \"POST\",\n      \"NumberOfRequests\": 10000,\n      \"FetchContent\": false,\n      \"Parallelism\": 500,\n      \"BoundedCapacity\": 500,\n      \"Headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64)\"\n      },\n      \"Body\": {\n        \"Content\": \"{\\\"name\\\":\\\"test\\\"}\",\n        \"ContentType\": \"application/json\",\n        \"Encoding\": \"utf-8\"\n      }\n    }\n  ]\n}\n```\n    \n## Http request\nHttp 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.\n\n```http request\nPOST / HTTP/1.1\nHost: localhost:3000\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) WebBen/1.2206\nContent-Type: application/json; charset=utf-8\nContent-Length: 15\n\n{\"name\":\"test\"}\n```\n\nWebBen 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.\n\n### Example\n```shell\nwebben uri https://url-to-benchmark.local/pages/1 -e json | \\\ncurl -H \"Content-Type: application/json\" \\\n    -X POST \\\n    --data-binary @- \\\n    https://your-awesome-backend.local/api/v1/posts\n    \n\nPOST / HTTP/1.1\nHost: your-awesome-backend.local\nUser-Agent: curl/7.79.1\nAccept: */*\nContent-Type: application/json\nContent-Length: 1042\n\n{\n  \"Items\": [\n    {\n      \"Timings\": [\n        \"00:00:00.5772976\",\n        \"00:00:00.5528780\",\n        \"00:00:00.5148466\",\n        \"00:00:00.5118757\",\n        \"00:00:00.5118554\",\n        \"00:00:00.4524819\",\n        \"00:00:00.5113236\",\n        \"00:00:00.5117843\",\n        \"00:00:00.5148185\",\n        \"00:00:00.4524458\"\n      ],\n      \"Errors\": [],\n      \"Elapsed\": \"00:00:00.5938226\",\n      \"Configuration\": {\n        \"HttpMethod\": \"GET\",\n        \"RequestCount\": 10,\n        \"Parallelism\": 10,\n        \"UseDefaultCredentials\": false,\n        \"UseCookieContainer\": false,\n        \"MaxBufferSize\": 2147483647,\n        \"Name\": \"iteration1\",\n        \"Uri\": \"https://url-to-benchmark.local/pages/1\",\n        \"FetchContent\": false,\n        \"AllowRedirect\": true,\n        \"TimeoutInMs\": 2147483647\n      },\n      \"Calculations\": {\n        \"Average\": \"00:00:00.5111607\",\n        \"StdDev\": \"00:00:00.0361018\",\n        \"P90\": \"00:00:00.5772976\",\n        \"P80\": \"00:00:00.5528780\",\n        \"P70\": \"00:00:00.5148466\",\n        \"Median\": \"00:00:00.5118655\"\n      }\n    }\n  ]\n}\n```\n\n## :yum: How to contribute\nHave an idea? Found a bug? Contributions are always welcome. \n- Open an issue or create a pull request.\n- Share with your friends.\n- Give a Star.\n\nThanks! :heart:\n","funding_links":[],"categories":["Code Analysis and Metrics"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomerfarukz%2FWebBen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomerfarukz%2FWebBen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomerfarukz%2FWebBen/lists"}