commit 36b9f628c76d74f86d5d6a4635cf426b42fa9191
parent baeb77af99dc3315304814e40f85465e090018ed
Author: Greg Heartsfield <scsibug@imap.cc>
Date: Sat, 17 Sep 2022 16:02:57 -0500
test: check for relay health after startup
Diffstat:
2 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
@@ -1,12 +1,15 @@
-use anyhow::Result;
+use anyhow::{anyhow, Result};
use log::*;
use nostr_rs_relay::config;
use nostr_rs_relay::server::start_server;
+//use http::{Request, Response};
+use hyper::{Client, StatusCode, Uri};
use std::net::TcpListener;
use std::sync::mpsc as syncmpsc;
use std::sync::mpsc::{Receiver as MpscReceiver, Sender as MpscSender};
use std::thread;
use std::thread::JoinHandle;
+use std::time::Duration;
pub struct Relay {
pub port: u16,
@@ -20,8 +23,9 @@ pub fn start_relay() -> Result<Relay> {
// replace default settings
let mut settings = config::Settings::default();
// identify open port
+ info!("Checking for address...");
let port = get_available_port().unwrap();
- info!("Starting relay on port {}", port);
+ info!("Found open port: {}", port);
// bind to local interface only
settings.network.address = "127.0.0.1".to_owned();
settings.network.port = port;
@@ -31,8 +35,10 @@ pub fn start_relay() -> Result<Relay> {
settings.database.max_conn = 8;
let (shutdown_tx, shutdown_rx): (MpscSender<()>, MpscReceiver<()>) = syncmpsc::channel();
let handle = thread::spawn(|| {
+ // server will block the thread it is run on.
let _ = start_server(settings, shutdown_rx);
});
+ // how do we know the relay has finished starting up?
return Ok(Relay {
port,
handle,
@@ -40,11 +46,50 @@ pub fn start_relay() -> Result<Relay> {
});
}
+// check if the server is healthy via HTTP request
+async fn server_ready(relay: &Relay) -> Result<bool> {
+ let uri: String = format!("http://127.0.0.1:{}/", relay.port.to_string());
+ let client = Client::new();
+ let uri: Uri = uri.parse().unwrap();
+ let res = client.get(uri).await?;
+ Ok(res.status() == StatusCode::OK)
+}
+
+pub async fn wait_for_healthy_relay(relay: &Relay) -> Result<()> {
+ // TODO: maximum time to wait for server to become healthy.
+ // give it a little time to start up before we start polling
+ tokio::time::sleep(Duration::from_millis(10)).await;
+ loop {
+ let server_check = server_ready(&relay).await;
+ match server_check {
+ Ok(true) => {
+ // server responded with 200-OK.
+ break;
+ }
+ Ok(false) => {
+ // server responded with an error, we're done.
+ return Err(anyhow!("Got non-200-OK from relay"));
+ }
+ Err(_) => {
+ // server is not yet ready, probably connection refused...
+ debug!("Got ERR from Relay!");
+ tokio::time::sleep(Duration::from_millis(10)).await;
+ }
+ }
+ }
+ info!("relay is ready");
+ Ok(())
+ // simple message sent to web browsers
+ //let mut request = Request::builder()
+ // .uri("https://www.rust-lang.org/")
+ // .header("User-Agent", "my-awesome-agent/1.0");
+}
+
// from https://elliotekj.com/posts/2017/07/25/find-available-tcp-port-rust/
fn get_available_port() -> Option<u16> {
- (4000..20000).find(|port| port_is_available(*port))
+ (4030..20000).find(|port| port_is_available(*port))
}
-fn port_is_available(port: u16) -> bool {
+pub fn port_is_available(port: u16) -> bool {
match TcpListener::bind(("127.0.0.1", port)) {
Ok(_) => true,
Err(_) => false,
diff --git a/tests/integration_test.rs b/tests/integration_test.rs
@@ -1,12 +1,20 @@
use anyhow::Result;
+use log::*;
use std::thread;
use std::time::Duration;
mod common;
-#[test]
-fn startup() -> Result<()> {
+#[tokio::test]
+async fn start_and_stop() -> Result<()> {
+ // this will be the common pattern for acquiring a new relay:
+ // start a fresh relay, on a port to-be-provided back to us:
let relay = common::start_relay()?;
+ // wait for the relay's webserver to start up and deliver a page:
+ common::wait_for_healthy_relay(&relay).await?;
+
+ let relay = common::start_relay()?;
+ let port = relay.port;
// just make sure we can startup and shut down.
// if we send a shutdown message before the server is listening,
// we will get a SendError. Keep sending until someone is
@@ -25,5 +33,15 @@ fn startup() -> Result<()> {
// wait for relay to shutdown
let thread_join = relay.handle.join();
assert!(thread_join.is_ok());
+ // assert that port is now available.
+ assert!(common::port_is_available(port));
+ Ok(())
+}
+
+#[tokio::test]
+async fn relay_home_page() -> Result<()> {
+ // get a relay and wait for startup...
+ let relay = common::start_relay()?;
+ common::wait_for_healthy_relay(&relay).await?;
Ok(())
}