test: add basic parallel unit tests (#17)
This commit is contained in:
parent
16f235b9fd
commit
b7f0bf9d81
@ -25,7 +25,12 @@ hyper-tls = { version = "0.5", optional = true }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
futures = "0.3"
|
||||||
|
async-trait = "0.1"
|
||||||
|
tokio-test = "0.4.2"
|
||||||
|
test-context = "0.1.3"
|
||||||
|
tokiotest-httpserver = "0.2.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
https = ["hyper-tls"]
|
https = ["hyper-tls"]
|
||||||
default = ["https"]
|
default = ["https"]
|
82
tests/test_http.rs
Normal file
82
tests/test_http.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use tokio::sync::oneshot::Sender;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
use hyper::service::{make_service_fn, service_fn};
|
||||||
|
use hyper::server::conn::AddrStream;
|
||||||
|
use std::convert::Infallible;
|
||||||
|
use hyper::{Uri, Client, Request, Body, Server, Response, StatusCode};
|
||||||
|
use tokiotest_httpserver::{HttpTestContext, take_port};
|
||||||
|
use test_context::AsyncTestContext;
|
||||||
|
use test_context::test_context;
|
||||||
|
use std::net::{IpAddr, SocketAddr};
|
||||||
|
use tokiotest_httpserver::handler::HandlerBuilder;
|
||||||
|
|
||||||
|
struct ProxyTestContext {
|
||||||
|
sender: Sender<()>,
|
||||||
|
proxy_handler: JoinHandle<Result<(), hyper::Error>>,
|
||||||
|
http_back: HttpTestContext,
|
||||||
|
port: u16
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_context(ProxyTestContext)]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_error_500(ctx: &mut ProxyTestContext) {
|
||||||
|
let resp = Client::new().get(ctx.uri("/500")).await.unwrap();
|
||||||
|
assert_eq!(500, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_context(ProxyTestContext)]
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get(ctx: &mut ProxyTestContext) {
|
||||||
|
ctx.http_back.add(HandlerBuilder::new("/foo").status_code(StatusCode::OK).build());
|
||||||
|
let resp = Client::new().get(ctx.uri("/foo")).await.unwrap();
|
||||||
|
assert_eq!(200, resp.status());
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handle(client_ip: IpAddr, req: Request<Body>, backend_port: u16) -> Result<Response<Body>, Infallible> {
|
||||||
|
match hyper_reverse_proxy::call(client_ip,
|
||||||
|
format!("http://127.0.0.1:{}", backend_port).as_str(),
|
||||||
|
req).await {
|
||||||
|
Ok(response) => {Ok(response)}
|
||||||
|
Err(_) => {Ok(Response::builder()
|
||||||
|
.status(502)
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap())}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl AsyncTestContext for ProxyTestContext {
|
||||||
|
async fn setup() -> ProxyTestContext {
|
||||||
|
let http_back: HttpTestContext = AsyncTestContext::setup().await;
|
||||||
|
let (sender, receiver) = tokio::sync::oneshot::channel::<()>();
|
||||||
|
let bp_to_move = http_back.port;
|
||||||
|
let make_svc = make_service_fn(move |conn: &AddrStream| {
|
||||||
|
let remote_addr = conn.remote_addr().ip();
|
||||||
|
let back_port = bp_to_move;
|
||||||
|
async move {
|
||||||
|
Ok::<_, Infallible>(service_fn(move |req| handle(remote_addr, req, back_port)))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let port = take_port();
|
||||||
|
let addr = SocketAddr::new("127.0.0.1".parse().unwrap(), port);
|
||||||
|
let server = Server::bind(&addr).serve(make_svc).with_graceful_shutdown(async { receiver.await.ok(); });
|
||||||
|
let proxy_handler = tokio::spawn(server);
|
||||||
|
ProxyTestContext {
|
||||||
|
sender,
|
||||||
|
proxy_handler,
|
||||||
|
http_back,
|
||||||
|
port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn teardown(self) {
|
||||||
|
let _ = AsyncTestContext::teardown(self.http_back);
|
||||||
|
let _ = self.sender.send(()).unwrap();
|
||||||
|
let _ = tokio::join!(self.proxy_handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ProxyTestContext {
|
||||||
|
pub fn uri(&self, path: &str) -> Uri {
|
||||||
|
format!("http://{}:{}{}", "localhost", self.port, path).parse::<Uri>().unwrap()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user