fix(local-deployer): align keep-tempdir env and artifact persistence

This commit is contained in:
andrussal 2026-02-17 10:28:50 +01:00
parent 603437e0dd
commit 6c7b66db02
7 changed files with 79 additions and 21 deletions

View File

@ -21,7 +21,7 @@ fn set_default_env(key: &str, value: &str) {
}
pub fn init_logging_defaults() {
set_default_env("LOGOS_BLOCKCHAIN_TESTS_KEEP_LOGS", "1");
set_default_env("TF_KEEP_LOGS", "1");
set_default_env("LOGOS_BLOCKCHAIN_LOG_LEVEL", "info");
set_default_env("RUST_LOG", "info");
}

View File

@ -25,6 +25,7 @@ use tracing::{debug, info, warn};
use crate::{
env::{LocalDeployerEnv, Node, wait_local_http_readiness},
keep_tempdir_from_env,
manual::ManualCluster,
node_control::{NodeManager, NodeManagerSeed},
};
@ -395,8 +396,8 @@ const fn default_local_retry_policy() -> RetryPolicy {
)
}
const fn keep_tempdir(policy: DeploymentPolicy) -> bool {
policy.cleanup_policy.preserve_artifacts
fn keep_tempdir(policy: DeploymentPolicy) -> bool {
policy.cleanup_policy.preserve_artifacts || keep_tempdir_from_env()
}
async fn spawn_feed_with<E: Application>(

View File

@ -1,4 +1,7 @@
use std::{collections::HashMap, path::Path};
use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use testing_framework_core::scenario::{
Application, DynError, HttpReadinessRequirement, ReadinessError, StartNodeOptions,
@ -36,6 +39,14 @@ where
topology: &Self::Deployment,
) -> Result<Vec<NodeConfigEntry<<Self as Application>::NodeConfig>>, ProcessSpawnError>;
fn initial_persist_dir(
_topology: &Self::Deployment,
_node_name: &str,
_index: usize,
) -> Option<PathBuf> {
None
}
fn build_launch_spec(
config: &<Self as Application>::NodeConfig,
dir: &Path,

View File

@ -14,3 +14,15 @@ pub use process::{
LaunchEnvVar, LaunchFile, LaunchSpec, NodeEndpointPort, NodeEndpoints, ProcessNode,
ProcessSpawnError,
};
const KEEP_LOGS_ENV: &str = "TF_KEEP_LOGS";
pub(crate) fn keep_tempdir_from_env() -> bool {
env_enabled(KEEP_LOGS_ENV)
}
fn env_enabled(key: &str) -> bool {
std::env::var(key).ok().is_some_and(|value| {
value == "1" || value.eq_ignore_ascii_case("true") || value.eq_ignore_ascii_case("yes")
})
}

View File

@ -6,7 +6,8 @@ use thiserror::Error;
use crate::{
env::LocalDeployerEnv,
node_control::{NodeManager, NodeManagerError},
keep_tempdir_from_env,
node_control::{NodeManager, NodeManagerError, NodeManagerSeed},
};
#[derive(Debug, Error)]
@ -22,9 +23,11 @@ pub struct ManualCluster<E: LocalDeployerEnv> {
impl<E: LocalDeployerEnv> ManualCluster<E> {
pub fn from_topology(descriptors: E::Deployment) -> Self {
let nodes = NodeManager::new(
let nodes = NodeManager::new_with_seed(
descriptors,
testing_framework_core::scenario::NodeClients::default(),
keep_tempdir_from_env(),
NodeManagerSeed::default(),
);
Self { nodes }

View File

@ -75,13 +75,15 @@ impl<E: LocalDeployerEnv> NodeManager<E> {
) -> Result<Vec<Node<E>>, ProcessSpawnError> {
let configs = E::build_initial_node_configs(descriptors)?;
let mut spawned = Vec::with_capacity(configs.len());
for config_entry in configs {
for (index, config_entry) in configs.into_iter().enumerate() {
let persist_dir = E::initial_persist_dir(descriptors, &config_entry.name, index);
spawned.push(
spawn_node_from_config::<E>(
config_entry.name,
config_entry.config,
keep_tempdir,
None,
persist_dir.as_deref(),
)
.await?,
);

View File

@ -1,6 +1,8 @@
use std::{
collections::HashMap,
fs, io, mem,
env, fs,
io::{self, Error, ErrorKind},
mem,
net::{Ipv4Addr, SocketAddr},
path::{Path, PathBuf},
process::Stdio,
@ -192,18 +194,8 @@ impl<Config: Clone + Send + Sync + 'static, Client: Clone + Send + Sync + 'stati
persist_dir: Option<&Path>,
client_from_endpoints: impl FnOnce(&NodeEndpoints) -> Client,
) -> Result<Self, ProcessSpawnError> {
let tempdir = match persist_dir {
Some(path) => {
std::fs::create_dir_all(path).map_err(|source| ProcessSpawnError::TempDir {
source: io::Error::new(
source.kind(),
format!("failed to create persist dir {}: {source}", path.display()),
),
})?;
TempDir::new_in(path).map_err(|source| ProcessSpawnError::TempDir { source })?
}
None => TempDir::new().map_err(|source| ProcessSpawnError::TempDir { source })?,
};
let tempdir = create_tempdir(persist_dir)?;
let launch = build_launch_spec(&config, tempdir.path(), label)
.map_err(|source| ProcessSpawnError::Config { source })?;
let endpoints = endpoints_from_config(&config);
@ -340,6 +332,43 @@ fn default_api_socket() -> SocketAddr {
SocketAddr::from((Ipv4Addr::LOCALHOST, 0))
}
fn create_tempdir(persist_dir: Option<&Path>) -> Result<TempDir, ProcessSpawnError> {
match persist_dir {
Some(dir) => {
let final_dir_name = dir
.components()
.last()
.ok_or_else(|| ProcessSpawnError::TempDir {
source: Error::new(ErrorKind::Other, "invalid final directory"),
})?
.as_os_str()
.display()
.to_string()
+ "_";
let parent_dir = dir.parent().ok_or_else(|| ProcessSpawnError::TempDir {
source: Error::new(ErrorKind::Other, "invalid parent directory"),
})?;
fs::create_dir_all(parent_dir).map_err(|source| ProcessSpawnError::TempDir {
source: Error::new(
source.kind(),
format!(
"failed to create parent dir for persist path {}: {source}",
dir.display()
),
),
})?;
TempDir::with_prefix_in(final_dir_name, parent_dir)
.map_err(|source| ProcessSpawnError::TempDir { source })
}
None => {
let cwd = env::current_dir().map_err(|source| ProcessSpawnError::TempDir { source })?;
TempDir::new_in(cwd).map_err(|source| ProcessSpawnError::TempDir { source })
}
}
}
#[cfg(test)]
mod tests {
use super::{NodeEndpointPort, NodeEndpoints};