Skip to content

Commit d38ca15

Browse files
committed
test concurrent requests
1 parent 4821c4b commit d38ca15

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

tests/any_component.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
select $component as component;
2+
select
3+
'It works !' as title,
4+
'It works !' as description;
5+
6+
select 'divider' as component, 'the end' as contents;

tests/index.rs

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ async fn test_index_ok() {
1111
assert_eq!(resp.status(), http::StatusCode::OK);
1212
let body = test::read_body(resp).await;
1313
assert!(body.starts_with(b"<!DOCTYPE html>"));
14-
// the body should contain the strint "It works!" and should not contain the string "error"
14+
// the body should contain the string "It works!" and should not contain the string "error"
1515
let body = String::from_utf8(body.to_vec()).unwrap();
1616
assert!(body.contains("It works !"));
1717
assert!(!body.contains("error"));
@@ -43,6 +43,44 @@ async fn test_404() {
4343
}
4444
}
4545

46+
#[actix_web::test]
47+
async fn test_concurrent_requests() {
48+
// send 32 requests (less than the default postgres pool size)
49+
// at the same time to /tests/multiple_components.sql
50+
let components = [
51+
"table", "form", "card", "datagrid", "hero", "list", "timeline",
52+
];
53+
let app_data = make_app_data().await;
54+
let reqs = (0..64)
55+
.map(|i| {
56+
let component = components[i % components.len()];
57+
req_path_with_app_data(
58+
format!("/tests/any_component.sql?component={}", component),
59+
app_data.clone(),
60+
)
61+
})
62+
.collect::<Vec<_>>();
63+
// send all requests at the same time
64+
let results = futures_util::future::join_all(reqs).await;
65+
// check that all requests succeeded
66+
for result in results.into_iter() {
67+
let resp = result.unwrap();
68+
assert_eq!(resp.status(), http::StatusCode::OK);
69+
let body = test::read_body(resp).await;
70+
assert!(
71+
body.starts_with(b"<!DOCTYPE html>"),
72+
"Expected html doctype"
73+
);
74+
// the body should contain the string "It works!" and should not contain the string "error"
75+
let body = String::from_utf8(body.to_vec()).unwrap();
76+
assert!(
77+
body.contains("It works !"),
78+
"Expected to contain: It works !, but got: {body}"
79+
);
80+
assert!(!body.contains("error"));
81+
}
82+
}
83+
4684
#[actix_web::test]
4785
async fn test_files() {
4886
// Iterate over all the sql test files in the tests/ directory
@@ -59,7 +97,7 @@ async fn test_files() {
5997
let resp = req_path(&req_str).await.unwrap();
6098
let body = test::read_body(resp).await;
6199
assert!(body.starts_with(b"<!DOCTYPE html>"));
62-
// the body should contain the strint "It works!" and should not contain the string "error"
100+
// the body should contain the string "It works!" and should not contain the string "error"
63101
let body = String::from_utf8(body.to_vec()).unwrap();
64102
let lowercase_body = body.to_lowercase();
65103
if stem.starts_with("it_works") {
@@ -141,28 +179,46 @@ async fn test_csv_upload() -> actix_web::Result<()> {
141179
}
142180

143181
async fn get_request_to(path: &str) -> actix_web::Result<TestRequest> {
182+
let data = make_app_data().await;
183+
Ok(test::TestRequest::get().uri(path).app_data(data))
184+
}
185+
186+
async fn make_app_data() -> actix_web::web::Data<AppState> {
144187
init_log();
145188
let config = test_config();
146189
let state = AppState::init(&config).await.unwrap();
147190
let data = actix_web::web::Data::new(state);
148-
Ok(test::TestRequest::get().uri(path).app_data(data))
191+
data
149192
}
150193

151-
async fn req_path(path: &str) -> Result<actix_web::dev::ServiceResponse, actix_web::Error> {
152-
let req = get_request_to(path)
194+
async fn req_path(
195+
path: impl AsRef<str>,
196+
) -> Result<actix_web::dev::ServiceResponse, actix_web::Error> {
197+
let req = get_request_to(path.as_ref())
153198
.await?
154199
.insert_header(ContentType::plaintext())
155200
.to_srv_request();
156201
main_handler(req).await
157202
}
158203

204+
async fn req_path_with_app_data(
205+
path: impl AsRef<str>,
206+
app_data: actix_web::web::Data<AppState>,
207+
) -> Result<actix_web::dev::ServiceResponse, actix_web::Error> {
208+
let req = test::TestRequest::get()
209+
.uri(path.as_ref())
210+
.app_data(app_data)
211+
.to_srv_request();
212+
main_handler(req).await
213+
}
214+
159215
pub fn test_config() -> AppConfig {
160216
let db_url = std::env::var("DATABASE_URL").unwrap_or_else(|_| "sqlite::memory:".to_string());
161217
serde_json::from_str::<AppConfig>(&format!(
162218
r#"{{
163219
"database_url": "{}",
164220
"database_connection_retries": 2,
165-
"database_connection_acquire_timeout_seconds": 1,
221+
"database_connection_acquire_timeout_seconds": 10,
166222
"allow_exec": true,
167223
"listen_on": "111.111.111.111:1"
168224
}}"#,

0 commit comments

Comments
 (0)