|
|
|
@ -15,6 +15,47 @@ pub struct DistantServerCtx {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl DistantServerCtx {
|
|
|
|
|
pub fn initialize() -> Self {
|
|
|
|
|
let ip_addr = "127.0.0.1".parse().unwrap();
|
|
|
|
|
let (done_tx, mut done_rx) = mpsc::channel(1);
|
|
|
|
|
let (started_tx, mut started_rx) = mpsc::channel(1);
|
|
|
|
|
|
|
|
|
|
// NOTE: We spawn a dedicated thread that runs our tokio runtime separately
|
|
|
|
|
// from our test itself because using assert_cmd blocks the thread
|
|
|
|
|
// and prevents our runtime from working unless we make the tokio
|
|
|
|
|
// test multi-threaded using `tokio::test(flavor = "multi_thread", worker_threads = 1)`
|
|
|
|
|
// which isn't great because we're only using async tests for our
|
|
|
|
|
// server itself; so, we hide that away since our test logic doesn't need to be async
|
|
|
|
|
thread::spawn(move || match Runtime::new() {
|
|
|
|
|
Ok(rt) => {
|
|
|
|
|
rt.block_on(async move {
|
|
|
|
|
let server = DistantServer::bind(ip_addr, "0".parse().unwrap(), None, 100)
|
|
|
|
|
.await
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
started_tx
|
|
|
|
|
.send(Ok((server.port(), server.to_unprotected_hex_auth_key())))
|
|
|
|
|
.await
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
let _ = done_rx.recv().await;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Err(x) => {
|
|
|
|
|
started_tx.blocking_send(Err(x)).unwrap();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Extract our server startup data if we succeeded
|
|
|
|
|
let (port, auth_key) = started_rx.blocking_recv().unwrap().unwrap();
|
|
|
|
|
|
|
|
|
|
Self {
|
|
|
|
|
addr: SocketAddr::new(ip_addr, port),
|
|
|
|
|
auth_key,
|
|
|
|
|
done_tx,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Produces a new test command that configures some distant command
|
|
|
|
|
/// configured with an environment that can talk to a remote distant server
|
|
|
|
|
pub fn new_cmd(&self, subcommand: impl AsRef<OsStr>) -> Command {
|
|
|
|
@ -34,60 +75,20 @@ impl DistantServerCtx {
|
|
|
|
|
.timeout(Duration::from_secs(TIMEOUT_SECS));
|
|
|
|
|
cmd
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Attempts to shutdown the server if it is not already dead
|
|
|
|
|
pub fn shutdown(&self) {
|
|
|
|
|
let _ = self.done_tx.send(());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for DistantServerCtx {
|
|
|
|
|
/// Kills server upon drop
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
self.shutdown();
|
|
|
|
|
let _ = self.done_tx.send(());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[fixture]
|
|
|
|
|
pub fn ctx() -> DistantServerCtx {
|
|
|
|
|
let ip_addr = "127.0.0.1".parse().unwrap();
|
|
|
|
|
let (done_tx, mut done_rx) = mpsc::channel(1);
|
|
|
|
|
let (started_tx, mut started_rx) = mpsc::channel(1);
|
|
|
|
|
|
|
|
|
|
// NOTE: We spawn a dedicated thread that runs our tokio runtime separately
|
|
|
|
|
// from our test itself because using assert_cmd blocks the thread
|
|
|
|
|
// and prevents our runtime from working unless we make the tokio
|
|
|
|
|
// test multi-threaded using `tokio::test(flavor = "multi_thread", worker_threads = 1)`
|
|
|
|
|
// which isn't great because we're only using async tests for our
|
|
|
|
|
// server itself; so, we hide that away since our test logic doesn't need to be async
|
|
|
|
|
thread::spawn(move || match Runtime::new() {
|
|
|
|
|
Ok(rt) => {
|
|
|
|
|
println!("Starting...");
|
|
|
|
|
rt.block_on(async move {
|
|
|
|
|
println!("Async...");
|
|
|
|
|
let server = DistantServer::bind(ip_addr, "0".parse().unwrap(), None, 100)
|
|
|
|
|
.await
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
started_tx
|
|
|
|
|
.send(Ok((server.port(), server.to_unprotected_hex_auth_key())))
|
|
|
|
|
.await
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
let _ = done_rx.recv().await;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Err(x) => {
|
|
|
|
|
started_tx.blocking_send(Err(x)).unwrap();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Extract our server startup data if we succeeded
|
|
|
|
|
let (port, auth_key) = started_rx.blocking_recv().unwrap().unwrap();
|
|
|
|
|
pub fn ctx() -> &'static DistantServerCtx {
|
|
|
|
|
&DISTANT_SERVER_CTX
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DistantServerCtx {
|
|
|
|
|
addr: SocketAddr::new(ip_addr, port),
|
|
|
|
|
auth_key,
|
|
|
|
|
done_tx,
|
|
|
|
|
}
|
|
|
|
|
lazy_static::lazy_static! {
|
|
|
|
|
static ref DISTANT_SERVER_CTX: DistantServerCtx = DistantServerCtx::initialize();
|
|
|
|
|
}
|
|
|
|
|