From 7e5c03e6849c5d54d834b498026b79b0c842d2d1 Mon Sep 17 00:00:00 2001 From: Huan-Cheng Chang Date: Fri, 27 Sep 2024 09:40:49 +0100 Subject: [PATCH] feat(jstzd): implement OctezNode health check --- crates/jstzd/Cargo.toml | 1 + crates/jstzd/src/task/octez_node.rs | 25 +++++++++++++++++++++---- crates/jstzd/tests/octez_node_test.rs | 15 ++------------- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/crates/jstzd/Cargo.toml b/crates/jstzd/Cargo.toml index 9664bb79..78424d42 100644 --- a/crates/jstzd/Cargo.toml +++ b/crates/jstzd/Cargo.toml @@ -12,6 +12,7 @@ async-trait.workspace = true bollard.workspace = true futures-util.workspace = true octez = { path = "../octez" } +reqwest.workspace = true tempfile.workspace = true tokio.workspace = true diff --git a/crates/jstzd/src/task/octez_node.rs b/crates/jstzd/src/task/octez_node.rs index 610298f9..d79c5829 100644 --- a/crates/jstzd/src/task/octez_node.rs +++ b/crates/jstzd/src/task/octez_node.rs @@ -12,7 +12,7 @@ const DEFAULT_RPC_ENDPOINT: &str = "localhost:8732"; const DEFAULT_NETWORK: &str = "sandbox"; const DEFAULT_BINARY_PATH: &str = "octez-node"; -#[derive(Clone)] +#[derive(Default, Clone)] pub struct OctezNodeConfig { /// Path to the octez node binary. binary_path: PathBuf, @@ -132,6 +132,7 @@ impl AsyncDrop for ChildWrapper { #[derive(Default, Clone)] pub struct OctezNode { inner: Arc>>, + config: OctezNodeConfig, } #[async_trait] @@ -141,8 +142,8 @@ impl Task for OctezNode { /// Spins up the task with the given config. async fn spawn(config: Self::Config) -> Result { let node = AsyncOctezNode { - octez_node_bin: Some(config.binary_path), - octez_node_dir: config.data_dir, + octez_node_bin: Some(config.binary_path.clone()), + octez_node_dir: config.data_dir.clone(), }; node.generate_identity().await?; @@ -163,6 +164,7 @@ impl Task for OctezNode { .await?, ), }))), + config, }) } @@ -174,7 +176,22 @@ impl Task for OctezNode { /// Conducts a health check on the running task. async fn health_check(&self) -> Result { - todo!() + // Returns whether or not the node is ready to answer to requests. + // https://gitlab.com/tezos/tezos/-/raw/2e84c439c25c4d9b363127a6685868e223877034/docs/api/rpc-openapi.json + let res = + reqwest::get(format!("http://{}/health/ready", &self.config.rpc_endpoint)) + .await; + if res.is_err() { + return Ok(false); + } + let body = res + .unwrap() + .json::>() + .await?; + if let Some(v) = body.get("ready") { + return Ok(*v); + } + return Err(anyhow::anyhow!("unexpected error: `ready` cannot be retrieved from octez-node health check endpoint")); } } diff --git a/crates/jstzd/tests/octez_node_test.rs b/crates/jstzd/tests/octez_node_test.rs index ea75727e..a4831ec2 100644 --- a/crates/jstzd/tests/octez_node_test.rs +++ b/crates/jstzd/tests/octez_node_test.rs @@ -39,24 +39,13 @@ async fn octez_node_test() { .await .unwrap(); - let health_check_endpoint = format!("http://{}/health/ready", rpc_endpoint); // Should be able to hit the endpoint since the node should have been launched - let node_ready = retry(10, 1000, || async { - let res = reqwest::get(&health_check_endpoint).await; - if let Ok(raw_body) = res { - let body = raw_body - .json::>() - .await - .unwrap(); - return body.get("ready").cloned().ok_or(anyhow::anyhow!("")); - } - Err(anyhow::anyhow!("")) - }) - .await; + let node_ready = retry(10, 1000, || async { f.health_check().await }).await; assert!(node_ready); let _ = f.kill().await; // Wait for the process to shutdown entirely + let health_check_endpoint = format!("http://{}/health/ready", rpc_endpoint); let node_destroyed = retry(10, 1000, || async { let res = reqwest::get(&health_check_endpoint).await; // Should get an error since the node should have been terminated