-
Notifications
You must be signed in to change notification settings - Fork 2
Closed
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
The load testing tool currently has no integration tests that verify end-to-end functionality. We need tests that spin up a mock HTTP server and verify that the load tester correctly generates requests, tracks metrics, and handles various response scenarios.
Proposed Approach
Use wiremock or httpmock crate to create a mock HTTP server, then run the load tester against it and verify behavior.
Test Scenarios Required
Basic Functionality
- GET requests are made to the correct URL
- POST requests include the correct body
- Custom headers are sent correctly
- Correct number of concurrent connections established
Load Models
- Concurrent model makes unlimited requests
- RPS model rate-limits to target rate (within tolerance)
- RampRps model increases/decreases rate correctly
- DailyTraffic model follows phase patterns
Metrics Verification
-
requests_totalincrements correctly -
requests_status_codes_totaltracks by status code -
request_duration_secondshistogram populated -
concurrent_requestsgauge reflects active requests - Metrics endpoint (port 9090) returns valid Prometheus format
Error Handling
- Connection refused handled gracefully
- Timeout handled correctly
- 4xx responses counted in metrics
- 5xx responses counted in metrics
- TLS errors handled appropriately
Response Scenarios
- 200 OK responses tracked
- 201 Created responses tracked
- 400 Bad Request responses tracked
- 404 Not Found responses tracked
- 500 Internal Server Error responses tracked
- Slow responses (latency injection) tracked accurately
Test Structure
tests/
├── integration/
│ ├── mod.rs
│ ├── basic_requests.rs
│ ├── load_models.rs
│ ├── metrics.rs
│ └── error_handling.rs
Example Test
use wiremock::{MockServer, Mock, ResponseTemplate};
use wiremock::matchers::{method, path};
#[tokio::test]
async fn test_get_requests_sent_correctly() {
// Start mock server
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.and(path("/test"))
.respond_with(ResponseTemplate::new(200))
.expect(10) // Expect exactly 10 requests
.mount(&mock_server)
.await;
// Run load tester with short duration
let config = TestConfig {
target_url: format!("{}/test", mock_server.uri()),
max_concurrent: 2,
test_duration: Duration::from_secs(1),
load_model: LoadModel::Concurrent,
};
run_load_test(config).await;
// Verify mock received expected requests
// (wiremock will panic if expectations not met)
}
#[tokio::test]
async fn test_rps_rate_limiting() {
let mock_server = MockServer::start().await;
let request_count = Arc::new(AtomicU32::new(0));
let counter = request_count.clone();
Mock::given(method("GET"))
.respond_with(move |_| {
counter.fetch_add(1, Ordering::SeqCst);
ResponseTemplate::new(200)
})
.mount(&mock_server)
.await;
let config = TestConfig {
target_url: mock_server.uri(),
load_model: LoadModel::Rps { target_rps: 10.0 },
test_duration: Duration::from_secs(5),
..Default::default()
};
run_load_test(config).await;
let total_requests = request_count.load(Ordering::SeqCst);
// Should be approximately 50 requests (10 RPS * 5 seconds)
// Allow 20% tolerance for timing variations
assert!(total_requests >= 40 && total_requests <= 60,
"Expected ~50 requests, got {}", total_requests);
}
#[tokio::test]
async fn test_metrics_endpoint_returns_prometheus_format() {
let mock_server = MockServer::start().await;
Mock::given(method("GET"))
.respond_with(ResponseTemplate::new(200))
.mount(&mock_server)
.await;
// Start load tester in background
let handle = tokio::spawn(async move {
run_load_test(config).await;
});
// Give it time to start metrics server
tokio::time::sleep(Duration::from_millis(500)).await;
// Fetch metrics
let metrics = reqwest::get("http://localhost:9090/metrics")
.await.unwrap()
.text()
.await.unwrap();
assert!(metrics.contains("requests_total"));
assert!(metrics.contains("request_duration_seconds"));
handle.abort();
}Acceptance Criteria
- Integration test directory structure created
- Mock server setup utility created
- Basic GET/POST request tests pass
- At least one test per load model
- Metrics endpoint tested
- Error scenarios tested
- Tests run in CI pipeline
- Tests complete in reasonable time (<30 seconds total)
Dependencies
Add to Cargo.toml (dev-dependencies):
[dev-dependencies]
wiremock = "0.5"
tokio-test = "0.4"Priority
High - Integration tests are essential for confidence in the tool's correctness before using it for actual load testing.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request