diff --git a/testing-framework/core/src/nodes/common/node.rs b/testing-framework/core/src/nodes/common/node.rs index 581d5f0..b6f05cb 100644 --- a/testing-framework/core/src/nodes/common/node.rs +++ b/testing-framework/core/src/nodes/common/node.rs @@ -71,23 +71,15 @@ pub struct NodeHandle { pub(crate) tempdir: TempDir, pub(crate) config: T, pub(crate) api: ApiClient, - pub(crate) persist_dir: Option, } impl NodeHandle { - pub fn new( - child: Child, - tempdir: TempDir, - config: T, - api: ApiClient, - persist_dir: Option, - ) -> Self { + pub fn new(child: Child, tempdir: TempDir, config: T, api: ApiClient) -> Self { Self { child, tempdir, config, api, - persist_dir, } } @@ -132,8 +124,9 @@ pub fn prepare_node_config( mut config: T, log_prefix: &str, enable_logging: bool, + persist_dir: Option, ) -> Result, SpawnNodeError> { - let dir = create_tempdir().map_err(|source| SpawnNodeError::TempDir { source })?; + let dir = create_tempdir(persist_dir).map_err(|source| SpawnNodeError::TempDir { source })?; debug!(dir = %dir.path().display(), log_prefix, enable_logging, "preparing node config"); @@ -168,7 +161,7 @@ where C: NodeConfigCommon + Serialize, { let (dir, config, addr, testing_addr) = - prepare_node_config(config, log_prefix, enable_logging)?; + prepare_node_config(config, log_prefix, enable_logging, persist_dir)?; let config_path = dir.path().join(config_filename); write_node_config(&config, &config_path)?; @@ -177,13 +170,7 @@ where let child = spawn_node_process(&binary_path, &config_path, dir.path())?; - let mut handle = NodeHandle::new( - child, - dir, - config, - ApiClient::new(addr, testing_addr), - persist_dir, - ); + let mut handle = NodeHandle::new(child, dir, config, ApiClient::new(addr, testing_addr)); // Wait for readiness via consensus_info let ready = wait_for_consensus_readiness(&handle.api).await; diff --git a/testing-framework/core/src/nodes/mod.rs b/testing-framework/core/src/nodes/mod.rs index 26e70f9..bd5c3b0 100644 --- a/testing-framework/core/src/nodes/mod.rs +++ b/testing-framework/core/src/nodes/mod.rs @@ -2,21 +2,48 @@ mod api_client; pub mod common; pub mod node; -use std::sync::LazyLock; +use std::{ + io::{Error, ErrorKind}, + path::PathBuf, + sync::LazyLock, +}; pub use api_client::{ApiClient, ApiClientError}; use tempfile::TempDir; use testing_framework_env as tf_env; -use tracing::info; pub(crate) const LOGS_PREFIX: &str = "__logs"; static KEEP_NODE_TEMPDIRS: LazyLock = LazyLock::new(tf_env::nomos_tests_keep_logs); -pub(crate) fn create_tempdir() -> std::io::Result { - // It's easier to use the current location instead of OS-default tempfile - // location because Github Actions can easily access files in the current - // location using wildcard to upload them as artifacts. - TempDir::new_in(std::env::current_dir()?) +pub(crate) fn create_tempdir(custom_work_dir: Option) -> std::io::Result { + if let Some(dir) = custom_work_dir { + let final_dir_name = dir + .components() + .last() + .ok_or(Error::new(ErrorKind::Other, "invalid final directory"))? + .as_os_str() + .display() + .to_string() + .to_owned() + + "_"; + let parent_dir = dir + .parent() + .ok_or(Error::new(ErrorKind::Other, "invalid parent directory"))?; + let mut temp_dir = TempDir::with_prefix_in(final_dir_name, parent_dir)?; + if should_persist_tempdir() { + temp_dir.disable_cleanup(true); + } + Ok(temp_dir) + } else { + // It's easier to use the current location instead of OS-default tempfile + // location because Github Actions can easily access files in the current + // location using wildcard to upload them as artifacts. + let mut temp_dir = TempDir::new_in(std::env::current_dir()?)?; + if should_persist_tempdir() { + temp_dir.disable_cleanup(true); + } + Ok(temp_dir) + } } fn persist_tempdir(tempdir: &mut TempDir, label: &str) -> std::io::Result<()> { @@ -25,61 +52,15 @@ fn persist_tempdir(tempdir: &mut TempDir, label: &str) -> std::io::Result<()> { label, tempdir.path().display() ); + if should_persist_tempdir() { + return Ok(()); + } // we need ownership of the dir to persist it let dir = std::mem::replace(tempdir, tempfile::tempdir()?); let _ = dir.keep(); Ok(()) } -pub(crate) fn persist_tempdir_to( - tempdir: &mut TempDir, - target_dir: &std::path::Path, - label: &str, -) -> std::io::Result<()> { - use std::fs; - - info!( - label, - from = %tempdir.path().display(), - to = %target_dir.display(), - "persisting directory" - ); - - // Create parent directory if it doesn't exist - if let Some(parent) = target_dir.parent() { - fs::create_dir_all(parent)?; - } - - // Copy tempdir contents to target directory - if target_dir.exists() { - fs::remove_dir_all(target_dir)?; - } - - /// Recursively copies all contents from src directory to dst directory. - /// - /// # Arguments - /// * `src` - Source directory path to copy from - /// * `dst` - Destination directory path to copy to - fn copy_dir_all(src: &std::path::Path, dst: &std::path::Path) -> std::io::Result<()> { - use std::fs; - fs::create_dir_all(dst)?; - for entry in fs::read_dir(src)? { - let entry = entry?; - let ty = entry.file_type()?; - if ty.is_dir() { - copy_dir_all(&entry.path(), &dst.join(entry.file_name()))?; - } else { - fs::copy(entry.path(), dst.join(entry.file_name()))?; - } - } - Ok(()) - } - - copy_dir_all(tempdir.path(), target_dir)?; - - Ok(()) -} - pub(crate) fn should_persist_tempdir() -> bool { std::thread::panicking() || *KEEP_NODE_TEMPDIRS } diff --git a/testing-framework/core/src/nodes/node.rs b/testing-framework/core/src/nodes/node.rs index 6b7b8da..50878f5 100644 --- a/testing-framework/core/src/nodes/node.rs +++ b/testing-framework/core/src/nodes/node.rs @@ -5,7 +5,6 @@ use nomos_tracing_service::LoggerLayer; pub use testing_framework_config::nodes::node::create_node_config; use tracing::{debug, info}; -use super::{persist_tempdir, persist_tempdir_to, should_persist_tempdir}; use crate::{ IS_DEBUG_TRACING, nodes::{ @@ -67,22 +66,6 @@ impl Deref for Node { impl Drop for Node { fn drop(&mut self) { - if should_persist_tempdir() { - if let Some(ref persist_dir) = self.handle.persist_dir { - if let Err(e) = persist_tempdir_to( - &mut self.handle.tempdir, - persist_dir, - "logos-blockchain-node", - ) { - debug!(error = ?e, persist_dir = %persist_dir.display(), "failed to persist node tempdir to custom directory"); - } - } else { - if let Err(e) = persist_tempdir(&mut self.handle.tempdir, "logos-blockchain-node") { - debug!(error = ?e, "failed to persist node tempdir"); - } - } - } - debug!("stopping node process"); kill_child(&mut self.handle.child); }