Test von HTTPS Endpunkten mit hyper
hyper stellt eine schnelle HTTP Implementierung in Rust für Server und Clients zur Verfügung. Das Zusatz-Crate hyper-tls bringt die Implementierung von TLS mit.
Aufsetzend auf die asynchrone Laufzeitumgebung Tokio benötigen wir für Tests auch das tokio crate.
extern crate hyper;
extern crate hyper_tls;
extern crate tokio;
use hyper::rt::{Future, Stream};
use hyper::Client;
use hyper_tls::HttpsConnector;
use std::str;
use tokio::prelude::*;
In der Testumgebung müssen wir eine eigene Runtime
instanzieren. Zum Auswerten des erfolgreichen Ablaufs des asynchronen Future
verwende ich folgende Hilfsfunktion.
#[allow(dead_code)]
pub fn test_future<F>(f: F) -> Result<F::Item, F::Error>
where
F: IntoFuture,
F::Future: Send + 'static,
F::Item: Send + 'static,
F::Error: Send + 'static,
{
let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime");
runtime.block_on(f.into_future())
}
Der eigentliche Test spezifiziert den HttpsConnector
und baut einen Client
.
Wir fragen hier per HTTP-GET eine kleine Textdatei ab.
Das Future
gibt den HTTP-StatusCode als Nummer und die Textdatei als String als Ergebnis zurück.
Über concat2()
wird hier der Body-Stream zusammengefasst.
#[test]
fn main_test() {
let https = HttpsConnector::new(4).expect("TLS initialization failed");
let client = Client::builder().build::<_, hyper::Body>(https);
let fut = client
.get(
"https://mta-sts.gmail.com/.well-known/mta-sts.txt"
.parse()
.unwrap(),
).and_then(move |res| {
let status = res.status().as_u16();
res.into_body().concat2().and_then(move |body| {
let s = str::from_utf8(&body).expect("mta-sts sends no utf-8");
Ok((status, s.to_string()))
})
});
Der Aufruf unseres fut: Future
und das match
en des Ergebnisses mit Überprüfung von status
und body
-Anfang. Ein evtl. Fehler würde den Test fehlschlagen lassen und den Fehler ausgeben.
let r = test_future(fut);
match r {
Ok((status, body)) => {
assert_eq!(status, 200);
assert!(body.starts_with("version: STSv1"), format!("{}", body));
}
Err(e) => assert!(false, format!("error: {:?}", e)),
}
}