strobengine 0.4.0__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. {strobengine-0.4.0 → strobengine-0.5.0}/.gitignore +3 -0
  2. {strobengine-0.4.0 → strobengine-0.5.0}/CHANGELOG.md +87 -0
  3. {strobengine-0.4.0 → strobengine-0.5.0}/Cargo.lock +19 -1
  4. {strobengine-0.4.0 → strobengine-0.5.0}/Cargo.toml +3 -2
  5. strobengine-0.5.0/PKG-INFO +86 -0
  6. strobengine-0.5.0/README.md +68 -0
  7. strobengine-0.5.0/docs/cli.md +153 -0
  8. strobengine-0.5.0/docs/dependencies.md +39 -0
  9. strobengine-0.5.0/docs/install.md +52 -0
  10. strobengine-0.5.0/docs/quickstart.md +132 -0
  11. strobengine-0.5.0/docs/reports.md +149 -0
  12. strobengine-0.5.0/docs/roadmap.md +168 -0
  13. strobengine-0.5.0/docs/sse.md +197 -0
  14. {strobengine-0.4.0 → strobengine-0.5.0}/docs/table_of_contents.md +8 -1
  15. strobengine-0.5.0/examples/sse.py +113 -0
  16. {strobengine-0.4.0 → strobengine-0.5.0}/pyproject.toml +3 -2
  17. {strobengine-0.4.0 → strobengine-0.5.0}/scripts/release.py +4 -0
  18. {strobengine-0.4.0 → strobengine-0.5.0}/src/config.rs +32 -0
  19. {strobengine-0.4.0 → strobengine-0.5.0}/src/lib.rs +57 -38
  20. {strobengine-0.4.0 → strobengine-0.5.0}/src/metrics.rs +6 -0
  21. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/grpc.rs +3 -0
  22. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/http.rs +3 -0
  23. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/http3.rs +6 -0
  24. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/mod.rs +16 -0
  25. strobengine-0.5.0/src/protocols/sse.rs +577 -0
  26. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/websocket.rs +28 -15
  27. strobengine-0.5.0/src/report/mod.rs +2 -0
  28. strobengine-0.5.0/src/report/schema.rs +392 -0
  29. strobengine-0.5.0/src/report/writer.rs +245 -0
  30. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/_strobengine.pyi +8 -0
  31. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/cli.py +250 -12
  32. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/engine.py +26 -3
  33. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/reporter.py +145 -5
  34. strobengine-0.5.0/src/strobengine/reporting/assets/chart.min.js +7 -0
  35. strobengine-0.5.0/src/strobengine/reporting/baseline.py +144 -0
  36. strobengine-0.5.0/src/strobengine/reporting/csv_report.py +56 -0
  37. strobengine-0.5.0/src/strobengine/reporting/html_report.py +238 -0
  38. strobengine-0.5.0/src/strobengine/reporting/junit_report.py +130 -0
  39. strobengine-0.5.0/src/strobengine/reporting/markdown_report.py +144 -0
  40. strobengine-0.5.0/tests/e2e/__init__.py +0 -0
  41. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/mock_server.py +23 -0
  42. strobengine-0.5.0/tests/e2e/test_persistence_e2e.py +83 -0
  43. strobengine-0.5.0/tests/e2e/test_sse_e2e.py +81 -0
  44. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_websocket_e2e.py +0 -2
  45. strobengine-0.5.0/tests/test_reporting.py +252 -0
  46. {strobengine-0.4.0 → strobengine-0.5.0}/uv.lock +89 -1
  47. strobengine-0.4.0/PKG-INFO +0 -375
  48. strobengine-0.4.0/README.md +0 -358
  49. strobengine-0.4.0/docs/roadmap.md +0 -95
  50. {strobengine-0.4.0 → strobengine-0.5.0}/.dockerignore +0 -0
  51. {strobengine-0.4.0 → strobengine-0.5.0}/.github/workflows/ci.yml +0 -0
  52. {strobengine-0.4.0 → strobengine-0.5.0}/.github/workflows/docker-release.yml +0 -0
  53. {strobengine-0.4.0 → strobengine-0.5.0}/.github/workflows/publish-test.yml +0 -0
  54. {strobengine-0.4.0 → strobengine-0.5.0}/.github/workflows/publish.yml +0 -0
  55. {strobengine-0.4.0 → strobengine-0.5.0}/.pre-commit-config.yaml +0 -0
  56. {strobengine-0.4.0 → strobengine-0.5.0}/.python-version +0 -0
  57. {strobengine-0.4.0 → strobengine-0.5.0}/Dockerfile +0 -0
  58. {strobengine-0.4.0 → strobengine-0.5.0}/LICENSE +0 -0
  59. {strobengine-0.4.0 → strobengine-0.5.0}/Makefile +0 -0
  60. {strobengine-0.4.0 → strobengine-0.5.0}/cliff.toml +0 -0
  61. {strobengine-0.4.0 → strobengine-0.5.0}/docs/benchmarks.md +0 -0
  62. {strobengine-0.4.0 → strobengine-0.5.0}/docs/docker.md +0 -0
  63. {strobengine-0.4.0 → strobengine-0.5.0}/docs/grpc.md +0 -0
  64. {strobengine-0.4.0 → strobengine-0.5.0}/docs/http3.md +0 -0
  65. {strobengine-0.4.0 → strobengine-0.5.0}/docs/http_methods.md +0 -0
  66. {strobengine-0.4.0 → strobengine-0.5.0}/docs/infrastructure.md +0 -0
  67. {strobengine-0.4.0 → strobengine-0.5.0}/docs/release.md +0 -0
  68. {strobengine-0.4.0 → strobengine-0.5.0}/docs/testing.md +0 -0
  69. {strobengine-0.4.0 → strobengine-0.5.0}/docs/websockets.md +0 -0
  70. {strobengine-0.4.0 → strobengine-0.5.0}/examples/grpc.py +0 -0
  71. {strobengine-0.4.0 → strobengine-0.5.0}/examples/http3.py +0 -0
  72. {strobengine-0.4.0 → strobengine-0.5.0}/examples/http_methods.py +0 -0
  73. {strobengine-0.4.0 → strobengine-0.5.0}/examples/load_test.py +0 -0
  74. {strobengine-0.4.0 → strobengine-0.5.0}/examples/spike_test.py +0 -0
  75. {strobengine-0.4.0 → strobengine-0.5.0}/examples/stress_test.py +0 -0
  76. {strobengine-0.4.0 → strobengine-0.5.0}/examples/websocket.py +0 -0
  77. {strobengine-0.4.0 → strobengine-0.5.0}/rust-toolchain.toml +0 -0
  78. {strobengine-0.4.0 → strobengine-0.5.0}/src/chaos.rs +0 -0
  79. {strobengine-0.4.0 → strobengine-0.5.0}/src/logging.rs +0 -0
  80. {strobengine-0.4.0 → strobengine-0.5.0}/src/progress.rs +0 -0
  81. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/grpc_parser.rs +0 -0
  82. {strobengine-0.4.0 → strobengine-0.5.0}/src/protocols/grpc_reflection.rs +0 -0
  83. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/__init__.py +0 -0
  84. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/constants.py +0 -0
  85. {strobengine-0.4.0 → strobengine-0.5.0}/src/strobengine/py.typed +0 -0
  86. {strobengine-0.4.0/tests → strobengine-0.5.0/src/strobengine/reporting}/__init__.py +0 -0
  87. {strobengine-0.4.0/tests/e2e → strobengine-0.5.0/tests}/__init__.py +0 -0
  88. {strobengine-0.4.0 → strobengine-0.5.0}/tests/conftest.py +0 -0
  89. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/conftest.py +0 -0
  90. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_cli_interface.py +0 -0
  91. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_grpc_e2e.py +0 -0
  92. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_http3_e2e.py +0 -0
  93. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_http_scenarios.py +0 -0
  94. {strobengine-0.4.0 → strobengine-0.5.0}/tests/e2e/test_performance_sanity.py +0 -0
  95. {strobengine-0.4.0 → strobengine-0.5.0}/tests/fixtures/service.proto +0 -0
  96. {strobengine-0.4.0 → strobengine-0.5.0}/tests/test_cli.py +0 -0
  97. {strobengine-0.4.0 → strobengine-0.5.0}/tests/test_engine.py +0 -0
  98. {strobengine-0.4.0 → strobengine-0.5.0}/tests/test_logging.py +0 -0
  99. {strobengine-0.4.0 → strobengine-0.5.0}/tests/test_reporter.py +0 -0
@@ -248,3 +248,6 @@ __marimo__/
248
248
 
249
249
  # Streamlit
250
250
  .streamlit/secrets.toml
251
+
252
+ # strobengine reports
253
+ .strobengine/
@@ -4,6 +4,91 @@ All notable changes to `strobengine` will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.5.0] - 2026-08-30
8
+
9
+ ### Documentation
10
+
11
+ - Convert README links to absolute GitHub URLs
12
+ - *(cli)* Add --sse/--no-sse and --sse-max-events to option tables
13
+ - *(examples)* Add SSE streaming load test examples
14
+ - Add SSE load testing reference guide
15
+ - Add SSE to README, quickstart, and table of contents
16
+ - Mark HTML report generator as complete in roadmap
17
+ - Mark baseline comparison as complete in roadmap
18
+ - Add reporting and visualizations reference guide
19
+ - Add Reporting & Visualizations to documentation indexes
20
+ - Add Advanced Metrics & Observability epic to roadmap
21
+ - Mark Export Formats as complete in roadmap
22
+
23
+ ### Features
24
+
25
+ - *(config)* Add sse_enabled, sse_max_events to TestConfig
26
+ - *(metrics)* Add sse_events_received, sse_first_event_us, sse_event_interval_us to RequestMetric
27
+ - *(sse)* Implement SSE frame parser and SseEngine
28
+ - *(sse)* Wire SSE engine into protocol detection and config routing
29
+ - *(sse)* Centralize protocol routing and add URL normalization
30
+ - *(deps)* Add serde with derive feature for report serialization
31
+ - *(report)* Add ReportArtifact schema with serde serialization
32
+ - *(config)* Add output_dir and no_save to TestConfig
33
+ - *(python)* Wire report persistence through CLI and engine
34
+ - *(report)* Add ReportArtifact::from_summary_and_config converter
35
+ - *(report)* Add save_report_json with atomic writes and latest.json
36
+ - *(report)* Invoke save_report_json on benchmark completion
37
+ - *(reporting)* Add standalone HTML report generator with Chart.js
38
+ - *(cli)* Add --html flag for standalone HTML report generation
39
+ - *(reporting)* Add baseline artifact loading and delta comparison
40
+ - *(reporting)* Add Historical Comparison section to HTML report
41
+ - *(cli)* Add --compare-to flag for baseline comparison
42
+ - *(reporting)* Inline Chart.js from local asset for 100% offline reports
43
+ - *(reporting)* Add CLI terminal comparison and extend compute_comparison
44
+ - *(engine)* Add get_config() convenience method to StrobEngine
45
+ - *(reporting)* Add Markdown, JUnit XML, and CSV export generators
46
+ - *(cli)* Add --markdown, --junit, --csv export flags
47
+ - *(reporting)* Add generate_markdown_summary for GitHub Actions / PR comments
48
+ - *(reporting)* Add generate_junit_report and generate_csv_report
49
+
50
+ ### Miscellaneous Tasks
51
+
52
+ - *(pyproject)* Simplify readme config and update documentation URL
53
+ - *(scripts)* Run uv lock during release version bump
54
+
55
+ ### Styling
56
+
57
+ - *(tests)* Reorder imports in test_reporting.py for ruff isort compliance
58
+
59
+ ### Testing
60
+
61
+ - *(config)* Update TestConfig::new calls with SSE parameters
62
+ - *(e2e)* Add SSE streaming endpoint to mock server
63
+ - *(e2e)* Add SSE integration tests for error paths and streaming
64
+ - *(e2e)* Add persistence E2E tests for report artifact disk writing
65
+ - *(reporting)* Add unit tests for Markdown summary generator
66
+ - *(reporting)* Add JUnit XML and CSV export unit tests
67
+ ## [0.4.1] - 2026-08-26
68
+
69
+ ### Bug Fixes
70
+
71
+ - *(pypi)* Configure readme base-url for relative link resolution
72
+ - *(cli)* Validate ws_mode with StrEnum to reject invalid strings
73
+ - *(cli)* URL-decode form values before passing to Rust
74
+ - *(websocket)* Count actual Pong payload size and fix PingPong status code
75
+ - *(reporter)* Handle GB and TB in _format_bytes
76
+
77
+ ### Documentation
78
+
79
+ - Add dependencies and installation guides
80
+ - Add quick start guide and CLI reference
81
+ - Update table of contents with new pages
82
+ - Slim README and link to documentation pages
83
+ - Add multi-target, reporting, SSE, messaging, and caching epics to roadmap
84
+
85
+ ### Miscellaneous Tasks
86
+
87
+ - *(release)* Bump version to 0.4.1
88
+
89
+ ### Testing
90
+
91
+ - *(e2e)* Remove bytes_received assertion from PingPong mode test
7
92
  ## [0.4.0] - 2026-08-23
8
93
 
9
94
  ### Bug Fixes
@@ -105,6 +190,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
105
190
  - Add rust-toolchain.toml for reproducible builds
106
191
  - Remove e2e test from pre commit hooks
107
192
  - *(ci)* Pin github actions to full commit SHAs
193
+ - *(release)* Bump version to 0.4.0
194
+ - Bump to 0.4.0 in uv.lock
108
195
 
109
196
  ### Other
110
197
 
@@ -1461,6 +1461,7 @@ dependencies = [
1461
1461
  "base64",
1462
1462
  "bytes",
1463
1463
  "futures-core",
1464
+ "futures-util",
1464
1465
  "h2",
1465
1466
  "http",
1466
1467
  "http-body",
@@ -1479,12 +1480,14 @@ dependencies = [
1479
1480
  "sync_wrapper",
1480
1481
  "tokio",
1481
1482
  "tokio-rustls",
1483
+ "tokio-util",
1482
1484
  "tower",
1483
1485
  "tower-http",
1484
1486
  "tower-service",
1485
1487
  "url",
1486
1488
  "wasm-bindgen",
1487
1489
  "wasm-bindgen-futures",
1490
+ "wasm-streams",
1488
1491
  "web-sys",
1489
1492
  ]
1490
1493
 
@@ -1654,6 +1657,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1654
1657
  checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
1655
1658
  dependencies = [
1656
1659
  "serde_core",
1660
+ "serde_derive",
1657
1661
  ]
1658
1662
 
1659
1663
  [[package]]
@@ -1781,7 +1785,7 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
1781
1785
 
1782
1786
  [[package]]
1783
1787
  name = "strobengine"
1784
- version = "0.4.0"
1788
+ version = "0.5.0"
1785
1789
  dependencies = [
1786
1790
  "async-trait",
1787
1791
  "base64",
@@ -1801,6 +1805,7 @@ dependencies = [
1801
1805
  "pyo3",
1802
1806
  "quinn",
1803
1807
  "reqwest",
1808
+ "serde",
1804
1809
  "serde_json",
1805
1810
  "tokio",
1806
1811
  "tokio-stream",
@@ -2355,6 +2360,19 @@ dependencies = [
2355
2360
  "unicode-ident",
2356
2361
  ]
2357
2362
 
2363
+ [[package]]
2364
+ name = "wasm-streams"
2365
+ version = "0.5.0"
2366
+ source = "registry+https://github.com/rust-lang/crates.io-index"
2367
+ checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb"
2368
+ dependencies = [
2369
+ "futures-util",
2370
+ "js-sys",
2371
+ "wasm-bindgen",
2372
+ "wasm-bindgen-futures",
2373
+ "web-sys",
2374
+ ]
2375
+
2358
2376
  [[package]]
2359
2377
  name = "web-sys"
2360
2378
  version = "0.3.103"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "strobengine"
3
- version = "0.4.0"
3
+ version = "0.5.0"
4
4
  edition = "2024"
5
5
  readme = "README.md"
6
6
 
@@ -15,7 +15,7 @@ crate-type = ["cdylib", "rlib"]
15
15
  # "abi3-py311" tells pyo3 (and maturin) to build using the stable ABI with
16
16
  # minimum Python version 3.11
17
17
  pyo3 = { version = "0.29", features = ["extension-module", "abi3-py311"] }
18
- reqwest = { version = "0.13.4", default-features = false, features = ["rustls", "http2"] }
18
+ reqwest = { version = "0.13.4", default-features = false, features = ["rustls", "http2", "stream"] }
19
19
  http = "1"
20
20
  bytes = "1"
21
21
  tokio = { version = "1.53.0", features = ["sync", "time", "rt", "rt-multi-thread", "macros", "signal"] }
@@ -37,6 +37,7 @@ base64 = "0.22"
37
37
  hex = "0.4"
38
38
  prost-reflect = { version = "0.16.5", features = ["serde"] }
39
39
  protox = "0.9.1"
40
+ serde = { version = "1", features = ["derive"] }
40
41
  serde_json = "1.0.151"
41
42
  tonic-reflection = { version = "0.14.6", default-features = false }
42
43
  quinn = { version = "0.11", default-features = false, features = ["runtime-tokio", "rustls-ring"] }
@@ -0,0 +1,86 @@
1
+ Metadata-Version: 2.4
2
+ Name: strobengine
3
+ Version: 0.5.0
4
+ Requires-Dist: rich>=13.0.0
5
+ Requires-Dist: typer>=0.27.0
6
+ Requires-Dist: jinja2>=3.1
7
+ License-File: LICENSE
8
+ Summary: A load testing framework with a Python UI and a bare-metal Rust engine core.
9
+ Author-email: riccione <28346232+riccione@users.noreply.github.com>
10
+ License-Expression: Apache-2.0
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
13
+ Project-URL: Changelog, https://github.com/strobeops/strobengine/blob/main/CHANGELOG.md
14
+ Project-URL: Documentation, https://github.com/strobeops/strobengine/blob/main/docs/table_of_contents.md
15
+ Project-URL: Homepage, https://github.com/strobeops/strobengine
16
+ Project-URL: Source, https://github.com/strobeops/strobengine
17
+
18
+ # strobengine
19
+
20
+ A high-performance HTTP, WebSocket, gRPC, and SSE load testing engine with a Python API and a bare-metal Rust core.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pip install strobengine
26
+ # or from source
27
+ git clone https://github.com/strobeops/strobengine.git && cd strobengine && uv sync
28
+ ```
29
+
30
+ > See [Installation Guide](https://github.com/strobeops/strobengine/blob/main/docs/install.md) for Docker, PyPI, and development setup.
31
+
32
+ ## Quick Start
33
+
34
+ ```python
35
+ from strobengine import StrobEngine
36
+ from strobengine.reporter import print_summary
37
+
38
+ engine = StrobEngine(url="http://localhost:8080/api/health", concurrency=50, duration=30)
39
+ summary = engine.run()
40
+ print_summary(summary)
41
+ ```
42
+
43
+ ```bash
44
+ strobengine load http://localhost:8080/api/health -c 50 -d 30
45
+ ```
46
+
47
+ > See [Quick Start Guide](https://github.com/strobeops/strobengine/blob/main/docs/quickstart.md) for Python API and CLI examples.
48
+
49
+ ## Documentation
50
+
51
+ | Section | Description |
52
+ |---------|-------------|
53
+ | [Installation](https://github.com/strobeops/strobengine/blob/main/docs/install.md) | Build from source, Docker, PyPI |
54
+ | [Dependencies](https://github.com/strobeops/strobengine/blob/main/docs/dependencies.md) | System requirements, Rust crates, Python packages |
55
+ | [Quick Start](https://github.com/strobeops/strobengine/blob/main/docs/quickstart.md) | Python API and CLI usage examples |
56
+ | [CLI Reference](https://github.com/strobeops/strobengine/blob/main/docs/cli.md) | All subcommands, flags, and options |
57
+ | [HTTP Methods](https://github.com/strobeops/strobengine/blob/main/docs/http_methods.md) | Supported methods, request bodies, headers |
58
+ | [WebSocket](https://github.com/strobeops/strobengine/blob/main/docs/websockets.md) | WS/WSS modes, pub/sub broadcasting, metrics |
59
+ | [gRPC](https://github.com/strobeops/strobengine/blob/main/docs/grpc.md) | Unary calls, protobuf, deadline, chaos |
60
+ | [HTTP/3](https://github.com/strobeops/strobengine/blob/main/docs/http3.md) | QUIC transport, 0-RTT resumption, loss recovery |
61
+ | [SSE](https://github.com/strobeops/strobengine/blob/main/docs/sse.md) | Server-Sent Events streaming, TTFB, event intervals |
62
+ | [Reporting](https://github.com/strobeops/strobengine/blob/main/docs/reports.md) | JSON persistence, HTML reports, baseline comparison |
63
+ | [Docker](https://github.com/strobeops/strobengine/blob/main/docs/docker.md) | Pulling images, running containers |
64
+ | [Testing](https://github.com/strobeops/strobengine/blob/main/docs/testing.md) | Test structure, e2e, CI/CD |
65
+ | [Roadmap](https://github.com/strobeops/strobengine/blob/main/docs/roadmap.md) | Planned features |
66
+
67
+ ## How to Contribute
68
+
69
+ 1. Fork the repository
70
+ 2. Create a feature branch (`git checkout -b feat/my-feature`)
71
+ 3. Install dependencies and set up pre-push Git hooks:
72
+ ```bash
73
+ uv sync
74
+ uv run pre-commit install --hook-type pre-push
75
+ ```
76
+ 4. Run formatting, linting, and tests manually (or let git push run them automatically):
77
+ ```bash
78
+ make check
79
+ ```
80
+ 5. Commit your changes following [Conventional Commits](https://www.conventionalcommits.org/)
81
+ 6. Push to your branch and open a Pull Request
82
+
83
+ ## License
84
+
85
+ This project is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/strobeops/strobengine/blob/main/LICENSE) for the full text.
86
+
@@ -0,0 +1,68 @@
1
+ # strobengine
2
+
3
+ A high-performance HTTP, WebSocket, gRPC, and SSE load testing engine with a Python API and a bare-metal Rust core.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install strobengine
9
+ # or from source
10
+ git clone https://github.com/strobeops/strobengine.git && cd strobengine && uv sync
11
+ ```
12
+
13
+ > See [Installation Guide](https://github.com/strobeops/strobengine/blob/main/docs/install.md) for Docker, PyPI, and development setup.
14
+
15
+ ## Quick Start
16
+
17
+ ```python
18
+ from strobengine import StrobEngine
19
+ from strobengine.reporter import print_summary
20
+
21
+ engine = StrobEngine(url="http://localhost:8080/api/health", concurrency=50, duration=30)
22
+ summary = engine.run()
23
+ print_summary(summary)
24
+ ```
25
+
26
+ ```bash
27
+ strobengine load http://localhost:8080/api/health -c 50 -d 30
28
+ ```
29
+
30
+ > See [Quick Start Guide](https://github.com/strobeops/strobengine/blob/main/docs/quickstart.md) for Python API and CLI examples.
31
+
32
+ ## Documentation
33
+
34
+ | Section | Description |
35
+ |---------|-------------|
36
+ | [Installation](https://github.com/strobeops/strobengine/blob/main/docs/install.md) | Build from source, Docker, PyPI |
37
+ | [Dependencies](https://github.com/strobeops/strobengine/blob/main/docs/dependencies.md) | System requirements, Rust crates, Python packages |
38
+ | [Quick Start](https://github.com/strobeops/strobengine/blob/main/docs/quickstart.md) | Python API and CLI usage examples |
39
+ | [CLI Reference](https://github.com/strobeops/strobengine/blob/main/docs/cli.md) | All subcommands, flags, and options |
40
+ | [HTTP Methods](https://github.com/strobeops/strobengine/blob/main/docs/http_methods.md) | Supported methods, request bodies, headers |
41
+ | [WebSocket](https://github.com/strobeops/strobengine/blob/main/docs/websockets.md) | WS/WSS modes, pub/sub broadcasting, metrics |
42
+ | [gRPC](https://github.com/strobeops/strobengine/blob/main/docs/grpc.md) | Unary calls, protobuf, deadline, chaos |
43
+ | [HTTP/3](https://github.com/strobeops/strobengine/blob/main/docs/http3.md) | QUIC transport, 0-RTT resumption, loss recovery |
44
+ | [SSE](https://github.com/strobeops/strobengine/blob/main/docs/sse.md) | Server-Sent Events streaming, TTFB, event intervals |
45
+ | [Reporting](https://github.com/strobeops/strobengine/blob/main/docs/reports.md) | JSON persistence, HTML reports, baseline comparison |
46
+ | [Docker](https://github.com/strobeops/strobengine/blob/main/docs/docker.md) | Pulling images, running containers |
47
+ | [Testing](https://github.com/strobeops/strobengine/blob/main/docs/testing.md) | Test structure, e2e, CI/CD |
48
+ | [Roadmap](https://github.com/strobeops/strobengine/blob/main/docs/roadmap.md) | Planned features |
49
+
50
+ ## How to Contribute
51
+
52
+ 1. Fork the repository
53
+ 2. Create a feature branch (`git checkout -b feat/my-feature`)
54
+ 3. Install dependencies and set up pre-push Git hooks:
55
+ ```bash
56
+ uv sync
57
+ uv run pre-commit install --hook-type pre-push
58
+ ```
59
+ 4. Run formatting, linting, and tests manually (or let git push run them automatically):
60
+ ```bash
61
+ make check
62
+ ```
63
+ 5. Commit your changes following [Conventional Commits](https://www.conventionalcommits.org/)
64
+ 6. Push to your branch and open a Pull Request
65
+
66
+ ## License
67
+
68
+ This project is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/strobeops/strobengine/blob/main/LICENSE) for the full text.
@@ -0,0 +1,153 @@
1
+ # CLI Reference
2
+
3
+ strobengine provides a CLI for running load tests from the terminal.
4
+
5
+ ## Default Behavior
6
+
7
+ By default, this spawns **10 concurrent workers** for **10 seconds** with a **10-second request timeout**. Results are displayed as a formatted table with total requests, errors, requests/sec, and latency percentiles (min, avg, p50, p90, p95, p99, max).
8
+
9
+ ## Subcommands
10
+
11
+ | Subcommand | Description |
12
+ |------------|-------------|
13
+ | `load` | Constant load test (default if no subcommand given) |
14
+ | `stress` | Ramp from starting to target concurrency, then hold |
15
+ | `spike` | Baseline -> peak -> baseline |
16
+
17
+ ## Load Subcommand Options
18
+
19
+ | Flag | Default | Description |
20
+ |------|---------|-------------|
21
+ | `-c`, `--concurrency` | `10` | Number of concurrent workers |
22
+ | `-d`, `--duration` | `10` | Duration in seconds |
23
+ | `-t`, `--timeout` | `10` | Per-request timeout in seconds |
24
+ | `--method` | `GET` | HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) |
25
+ | `--body` | none | Request body (raw string) |
26
+ | `--form` | none | Form data body (e.g. key1=val1&key2=val2) |
27
+ | `--header` | none | Custom header key:value (repeatable) |
28
+ | `--chaos` | off | Enable fault injection (~10%% of requests) |
29
+ | `--no-progress` | off | Suppress live progress bar |
30
+ | `-v`, `-vv`, `-vvv` | warn | Increase verbosity (INFO, DEBUG, TRACE) |
31
+ | `-q`, `--quiet` | off | Suppress all output |
32
+ | `--log-file <path>` | none | Write logs to file |
33
+ | `--json` | off | Output raw JSON instead of formatted table |
34
+ | `--ws-mode` | `handshake` | WebSocket mode: `handshake`, `ping_pong`, `stream` |
35
+ | `--ws-payload` | none | WebSocket text payload for stream mode |
36
+ | `--ws-role` | none | WebSocket Pub/Sub role: `publisher`, `subscriber` |
37
+ | `--ws-publish-interval` | none | Publisher send interval in milliseconds |
38
+ | `--ws-subscribers` | none | Number of subscriber workers |
39
+ | `--grpc-service` | none | gRPC service name (e.g. helloworld.Greeter) |
40
+ | `--grpc-method` | none | gRPC method name (e.g. SayHello) |
41
+ | `--grpc-payload` | none | Base64-encoded protobuf payload |
42
+ | `--grpc-deadline-ms` | none | gRPC deadline in milliseconds |
43
+ | `--http3/--no-http3` | off | Enable HTTP/3 over QUIC |
44
+ | `--quic-zero-rtt` | off | Enable QUIC 0-RTT connection testing |
45
+ | `--quic-max-idle-timeout` | none | QUIC max idle timeout in ms |
46
+ | `--sse/--no-sse` | off | Enable SSE streaming mode |
47
+ | `--sse-max-events` | none | Maximum events to receive per connection |
48
+
49
+ ## Stress Subcommand Options
50
+
51
+ | Flag | Default | Description |
52
+ |------|---------|-------------|
53
+ | `--from` | `10` | Starting concurrency |
54
+ | `--to` | `200` | Target concurrency |
55
+ | `--ramp` | `60` | Ramp duration in seconds |
56
+ | `--hold` | `30` | Hold duration at target concurrency |
57
+ | `-t`, `--timeout` | `10` | Per-request timeout in seconds |
58
+ | `--method` | `GET` | HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) |
59
+ | `--body` | none | Request body (raw string) |
60
+ | `--form` | none | Form data body (e.g. key1=val1&key2=val2) |
61
+ | `--header` | none | Custom header key:value (repeatable) |
62
+ | `--chaos` | off | Enable fault injection (~10%% of requests) |
63
+ | `--no-progress` | off | Suppress live progress bar |
64
+ | `-v`, `-vv`, `-vvv` | warn | Increase verbosity (INFO, DEBUG, TRACE) |
65
+ | `-q`, `--quiet` | off | Suppress all output |
66
+ | `--log-file <path>` | none | Write logs to file |
67
+ | `--json` | off | Output raw JSON |
68
+ | `--ws-mode` | `handshake` | WebSocket mode: `handshake`, `ping_pong`, `stream` |
69
+ | `--ws-payload` | none | WebSocket text payload for stream mode |
70
+ | `--ws-role` | none | WebSocket Pub/Sub role: `publisher`, `subscriber` |
71
+ | `--ws-publish-interval` | none | Publisher send interval in milliseconds |
72
+ | `--ws-subscribers` | none | Number of subscriber workers |
73
+ | `--grpc-service` | none | gRPC service name (e.g. helloworld.Greeter) |
74
+ | `--grpc-method` | none | gRPC method name (e.g. SayHello) |
75
+ | `--grpc-payload` | none | Base64-encoded protobuf payload |
76
+ | `--grpc-deadline-ms` | none | gRPC deadline in milliseconds |
77
+ | `--http3/--no-http3` | off | Enable HTTP/3 over QUIC |
78
+ | `--quic-zero-rtt` | off | Enable QUIC 0-RTT connection testing |
79
+ | `--quic-max-idle-timeout` | none | QUIC max idle timeout in ms |
80
+ | `--sse/--no-sse` | off | Enable SSE streaming mode |
81
+ | `--sse-max-events` | none | Maximum events to receive per connection |
82
+
83
+ ## Spike Subcommand Options
84
+
85
+ | Flag | Default | Description |
86
+ |------|---------|-------------|
87
+ | `--baseline` | `5` | Baseline concurrency |
88
+ | `--peak` | `500` | Peak concurrency |
89
+ | `--pre-spike` | `5` | Pre-spike duration in seconds |
90
+ | `--spike-duration` | `10` | Spike duration in seconds |
91
+ | `--post-spike` | `5` | Post-spike duration in seconds |
92
+ | `-t`, `--timeout` | `10` | Per-request timeout in seconds |
93
+ | `--method` | `GET` | HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) |
94
+ | `--body` | none | Request body (raw string) |
95
+ | `--form` | none | Form data body (e.g. key1=val1&key2=val2) |
96
+ | `--header` | none | Custom header key:value (repeatable) |
97
+ | `--chaos` | off | Enable fault injection (~10%% of requests) |
98
+ | `--no-progress` | off | Suppress live progress bar |
99
+ | `-v`, `-vv`, `-vvv` | warn | Increase verbosity (INFO, DEBUG, TRACE) |
100
+ | `-q`, `--quiet` | off | Suppress all output |
101
+ | `--log-file <path>` | none | Write logs to file |
102
+ | `--json` | off | Output raw JSON |
103
+ | `--ws-mode` | `handshake` | WebSocket mode: `handshake`, `ping_pong`, `stream` |
104
+ | `--ws-payload` | none | WebSocket text payload for stream mode |
105
+ | `--ws-role` | none | WebSocket Pub/Sub role: `publisher`, `subscriber` |
106
+ | `--ws-publish-interval` | none | Publisher send interval in milliseconds |
107
+ | `--ws-subscribers` | none | Number of subscriber workers |
108
+ | `--grpc-service` | none | gRPC service name (e.g. helloworld.Greeter) |
109
+ | `--grpc-method` | none | gRPC method name (e.g. SayHello) |
110
+ | `--grpc-payload` | none | Base64-encoded protobuf payload |
111
+ | `--grpc-deadline-ms` | none | gRPC deadline in milliseconds |
112
+ | `--http3/--no-http3` | off | Enable HTTP/3 over QUIC |
113
+ | `--quic-zero-rtt` | off | Enable QUIC 0-RTT connection testing |
114
+ | `--quic-max-idle-timeout` | none | QUIC max idle timeout in ms |
115
+ | `--sse/--no-sse` | off | Enable SSE streaming mode |
116
+ | `--sse-max-events` | none | Maximum events to receive per connection |
117
+
118
+ ## Global Options
119
+
120
+ | Flag | Description |
121
+ |------|-------------|
122
+ | `-V`, `--version` | Show version and exit |
123
+
124
+ ## Verbosity Levels
125
+
126
+ | Flag | Level | Shows |
127
+ |------|-------|-------|
128
+ | (default) | `warn` | Errors and warnings only |
129
+ | `-v` | `info` | Engine start/stop, test configuration |
130
+ | `-vv` | `debug` | Worker spawn, HTTP errors, connection events |
131
+ | `-vvv` | `trace` | Per-request latency, status codes, chaos injection |
132
+ | `-q` | off | Suppress all log output (progress bar remains) |
133
+
134
+ Logs stream to **stderr** by default, keeping stdout clean for JSON output piping:
135
+
136
+ ```bash
137
+ strobengine load http://localhost:8080/api/health -vv --json > results.json
138
+ ```
139
+
140
+ ## Live Progress Bar
141
+
142
+ During test execution, a live progress bar displays on stderr with real-time telemetry:
143
+
144
+ ```
145
+ ⠋ [00:00:05] [==============>-------------] 40% | 1250 req/s | 20 VUs | 12 err | avg 4.2ms
146
+ ```
147
+
148
+ - **RPS**: Instantaneous requests per second (sampled every 200ms)
149
+ - **VUs**: Active virtual users / concurrent workers
150
+ - **Errors**: Total error count
151
+ - **Avg latency**: Running average across all completed requests
152
+
153
+ The progress bar auto-detects non-TTY environments (CI/CD, piped output) and suppresses itself. Use `--no-progress` to explicitly disable it on interactive terminals.
@@ -0,0 +1,39 @@
1
+ # Dependencies
2
+
3
+ ## System Requirements
4
+
5
+ - **Python** >= 3.11
6
+ - **Rust** stable (with `cargo`)
7
+ - **uv** (Python package manager)
8
+
9
+ ## Rust Crates
10
+
11
+ | Crate | Version | Purpose |
12
+ |-------|---------|---------|
13
+ | pyo3 | 0.29 | Python FFI bindings (stable ABI, abi3-py311) |
14
+ | reqwest | 0.13 | HTTP client with connection pooling |
15
+ | tonic | 0.14 | gRPC framework with TLS support |
16
+ | quinn | 0.11 | QUIC transport for HTTP/3 |
17
+ | h3 | 0.0.8 | HTTP/3 protocol implementation |
18
+ | h3-quinn | 0.0.10 | h3-Quinn bridge |
19
+ | tokio | 1.53 | Multi-threaded async runtime |
20
+ | tokio-util | 0.7 | CancellationToken for graceful worker shutdown |
21
+ | tracing | 0.1 | Structured logging instrumentation |
22
+ | tracing-subscriber | 0.3 | Log formatting and output (stderr/file) |
23
+ | indicatif | 0.17 | Terminal progress bar rendering |
24
+ | fastrand | 2 | Fast random number generation for chaos injection |
25
+ | http | 1 | HTTP method types and header primitives |
26
+ | bytes | 1 | Zero-copy byte buffer for request payloads |
27
+ | tokio-tungstenite | 0.26 | WebSocket client with TLS support |
28
+ | prost / prost-reflect | 0.14 / 0.16 | Protobuf encoding/decoding and reflection |
29
+ | base64 | 0.22 | Base64 payload decoding for gRPC |
30
+ | hex | 0.4 | Hex payload decoding for gRPC |
31
+
32
+ ## Python Dependencies
33
+
34
+ | Package | Version | Purpose |
35
+ |---------|---------|---------|
36
+ | pytest | >= 8.0 | Test runner |
37
+ | pytest-asyncio | >= 0.24 | Async test support |
38
+ | aiohttp | >= 3.14 | Mock server for E2E tests |
39
+ | ruff | >= 0.15 | Linting and formatting |
@@ -0,0 +1,52 @@
1
+ # Installation
2
+
3
+ ## From Source (Recommended)
4
+
5
+ ```bash
6
+ # Clone the repository
7
+ git clone https://github.com/strobeops/strobengine.git
8
+ cd strobengine
9
+
10
+ # Build the native extension and install the package
11
+ uv sync
12
+ ```
13
+
14
+ `uv sync` invokes [maturin](https://github.com/PyO3/maturin) under the hood, which compiles the Rust code into a native Python extension module and installs it into your virtual environment.
15
+
16
+ ## From Docker
17
+
18
+ Pull and run strobengine directly from Docker Hub:
19
+
20
+ ```bash
21
+ # Latest release
22
+ docker pull strobeops/strobengine:latest
23
+ docker run --rm -it strobeops/strobengine load http://host.docker.internal:8080/api/health -c 50 -d 30
24
+
25
+ # Specific version
26
+ docker pull strobeops/strobengine:0.3.0
27
+ ```
28
+
29
+ > See [Docker documentation](docker.md) for version tags, host networking, and building locally.
30
+
31
+ ## Verify Installation
32
+
33
+ ```bash
34
+ # Check version
35
+ strobengine --version
36
+
37
+ # Or via Python
38
+ uv run python -c "from strobengine import StrobEngine; print('OK')"
39
+ ```
40
+
41
+ ## Development Setup
42
+
43
+ ```bash
44
+ # Install with dev dependencies
45
+ uv sync
46
+
47
+ # Install pre-commit hooks (optional)
48
+ uv run pre-commit install --hook-type pre-push
49
+
50
+ # Run the full check suite
51
+ make check
52
+ ```