This commit is contained in:
hansieodendaal 2026-02-05 16:27:35 +02:00
parent cee6b1a8a2
commit a641525034
No known key found for this signature in database
GPG Key ID: 4B3B15868823687C
3 changed files with 42 additions and 91 deletions

View File

@ -71,23 +71,15 @@ pub struct NodeHandle<T> {
pub(crate) tempdir: TempDir,
pub(crate) config: T,
pub(crate) api: ApiClient,
pub(crate) persist_dir: Option<PathBuf>,
}
impl<T> NodeHandle<T> {
pub fn new(
child: Child,
tempdir: TempDir,
config: T,
api: ApiClient,
persist_dir: Option<PathBuf>,
) -> 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<T: NodeConfigCommon>(
mut config: T,
log_prefix: &str,
enable_logging: bool,
persist_dir: Option<PathBuf>,
) -> Result<PreparedNodeConfig<T>, 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;

View File

@ -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<bool> = LazyLock::new(tf_env::nomos_tests_keep_logs);
pub(crate) fn create_tempdir() -> std::io::Result<TempDir> {
// 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<PathBuf>) -> std::io::Result<TempDir> {
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
}

View File

@ -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);
}