Files
NLnetLabs-domain/tests/net-client-cache.rs
Philip Homburg 90cc96d632 Add support to client transports for requests that may result in multiple
responses. (#377)

This adds ComposeRequestMulti and other *Multi types. The main change is to
the stream transport, which is the only transport that implements
SendRequestMulti.
2024-09-04 14:03:12 +02:00

128 lines
4.2 KiB
Rust

#![cfg(feature = "net")]
use std::fs::File;
use std::path::PathBuf;
use std::sync::Arc;
use domain::stelline::client::do_client_simple;
use domain::stelline::client::CurrStepValue;
use domain::stelline::connect::Connect;
use domain::stelline::parse_stelline::parse_file;
use rstest::rstest;
use tracing::instrument;
// use domain::net::client::clock::{Clock, FakeClock};
use domain::base::{MessageBuilder, Name, Rtype};
use domain::net::client::request::Error::NoTransportAvailable;
use domain::net::client::request::{RequestMessage, SendRequest};
use domain::net::client::{cache, multi_stream, redundant};
const TEST_FILE_AD: &str = "test-data/client-cache/cache_ad.rpl";
const TEST_FILE_TRANSPORT_ERROR: &str =
"test-data/client-cache/cache_transport_error.rpl";
async fn async_test_cache(filename: &str) {
let file = File::open(filename).unwrap();
let stelline = parse_file(&file, filename);
let step_value = Arc::new(CurrStepValue::new());
let multi_conn = Connect::new(stelline.clone(), step_value.clone());
let (ms, ms_tran) = multi_stream::Connection::new(multi_conn);
tokio::spawn(async move {
ms_tran.run().await;
println!("multi conn run terminated");
});
// let clock = FakeClock::new();
let cached = cache::Connection::new(ms); //_with_time(ms, clock.clone());
do_client_simple(&stelline, &step_value, cached /*, &clock*/).await;
}
async fn async_test_no_cache(filename: &str) {
let file = File::open(filename).unwrap();
let stelline = parse_file(&file, filename);
let step_value = Arc::new(CurrStepValue::new());
let multi_conn = Connect::new(stelline.clone(), step_value.clone());
let (ms, ms_tran) = multi_stream::Connection::new(multi_conn);
tokio::spawn(async move {
ms_tran.run().await;
println!("multi conn run terminated");
});
// let clock = FakeClock::new();
do_client_simple(&stelline, &step_value, ms /*, &clock*/).await;
}
#[tokio::test]
#[should_panic]
async fn test_ad_no_cache() {
async_test_no_cache(TEST_FILE_AD).await;
}
#[tokio::test(start_paused = true)]
async fn test_transport_error() {
// Transport errors should be cached. Create an empty redundant transport
// and manually issue a query to trigger a transport error. Then add a
// transport and issue a new query.
let file = File::open(TEST_FILE_TRANSPORT_ERROR).unwrap();
let stelline = parse_file(&file, TEST_FILE_TRANSPORT_ERROR);
let step_value = Arc::new(CurrStepValue::new());
let (redun, redun_tran) = redundant::Connection::new();
tokio::spawn(async move {
redun_tran.run().await;
println!("redundant conn run terminated");
});
// let clock = FakeClock::new();
let cached = cache::Connection::new(redun.clone()); //_with_time(redun.clone(), clock.clone());
let mut msg = MessageBuilder::new_vec();
msg.header_mut().set_rd(true);
let mut msg = msg.question();
msg.push((Name::vec_from_str("example.com").unwrap(), Rtype::AAAA))
.unwrap();
let req = RequestMessage::new(msg).unwrap();
let mut request = cached.send_request(req.clone());
let reply = request.get_response().await;
println!("got {reply:?}");
if let Err(NoTransportAvailable) = reply {
// This is what we expect.
} else {
panic!("Bad result {reply:?}");
}
let multi_conn = Connect::new(stelline.clone(), step_value.clone());
let (ms, ms_tran) = multi_stream::Connection::new(multi_conn);
tokio::spawn(async move {
ms_tran.run().await;
println!("multi conn run terminated");
});
redun.add(Box::new(ms)).await.unwrap();
let mut request = cached.send_request(req);
let reply = request.get_response().await;
if let Err(NoTransportAvailable) = reply {
// This is what we expect.
} else {
panic!("Bad result {reply:?}");
}
do_client_simple(&stelline, &step_value, redun /*, &clock*/).await;
}
#[instrument(skip_all, fields(rpl = rpl_file.file_name().unwrap().to_str()))]
#[rstest]
#[tokio::test(start_paused = true)]
async fn test_all(
#[files("test-data/client-cache/*.rpl")] rpl_file: PathBuf,
) {
async_test_cache(rpl_file.to_str().unwrap()).await;
}