add end to end test for error data factory

This commit is contained in:
Maksym Vorobiov 2020-01-23 00:34:02 +02:00
parent ef12dbe61b
commit 6e17063a1d
2 changed files with 46 additions and 10 deletions

View File

@ -279,17 +279,20 @@ mod tests {
assert_eq!(num.load(Ordering::SeqCst), 0); assert_eq!(num.load(Ordering::SeqCst), 0);
} }
use actix_service::{IntoServiceFactory, ServiceFactory};
use crate::dev::AppConfig;
#[actix_rt::test] #[actix_rt::test]
async fn test_error_data_service() { async fn test_error_data_service() {
let mut srv = let srv =
init_service(App::new().data_factory(|| async { Err::<u32,_>(()) }).service( App::new().data_factory(|| async { Err::<u32,_>(()) }).service(
web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()), web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok()),
)) )
.into_factory()
.new_service(AppConfig::default())
.await; .await;
// Service should not start
let req = TestRequest::default().to_request(); assert!(srv.is_err());
let resp = srv.call(req).await.expect("response failure");
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
} }
#[actix_rt::test] #[actix_rt::test]
@ -299,9 +302,42 @@ mod tests {
.data_factory(|| async { Err::<u32,_>(()) }) .data_factory(|| async { Err::<u32,_>(()) })
.service(web::resource("/").to(|_: web::Data<usize>| async { "ok" })) .service(web::resource("/").to(|_: web::Data<usize>| async { "ok" }))
}); });
// Server should not start, hence clients should not be able to connect
assert!(srv.get("/").send().await.is_err());
}
let resp = srv.get("/").send().await.expect("response failure"); use crate::HttpServer;
assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR); use awc::Client;
// When there is failure in data_factory HttpServer will keep trying to start,
// it still should return server error via http.
//
// Following test also reproduces one panic which seems unhandled:
// thread 'actix-rt:worker:1' panicked at 'index out of bounds: the len is 0 but the index is 0' in slice
#[actix_rt::test]
async fn test_error_data_http_server() {
env_logger::init();
let (tx, rx) = std::sync::mpsc::channel();
let sys = std::thread::spawn(move || {
let mut rt = actix_rt::System::new("test");
let srv = HttpServer::new(move || {App::new()
.data_factory(|| async { Err::<u32,_>(()) })
.service(web::resource("/").to(|_: web::Data<usize>| async { "ok" }))
})
.workers(1)
.bind("127.0.0.1:0").unwrap();
let addr = srv.addrs().first().unwrap().clone();
let srv = srv.run();
tx.send( (addr, srv.clone()) ).unwrap();
rt.block_on(srv)
});
// Server will not start, hence clients should not be able to connect
let (addr, srv) = rx.recv().unwrap();
let client = Client::new().get(format!("http://127.0.0.1:{}/", addr.port()));
assert!(client.send().await.expect("request failed").status().is_server_error());
srv.stop(true).await;
// But server's thread should exit with Ok()
assert!(sys.join().is_ok());
} }
} }

View File

@ -89,7 +89,7 @@ where
S::InitError: std::fmt::Debug, S::InitError: std::fmt::Debug,
{ {
let srv = app.into_factory(); let srv = app.into_factory();
srv.new_service(AppConfig::default()).await.unwrap() srv.new_service(AppConfig::default()).await.expect("test::init_service failure")
} }
/// Calls service and waits for response future completion. /// Calls service and waits for response future completion.