diff --git a/testing-framework/deployers/compose/src/deployer/orchestrator.rs b/testing-framework/deployers/compose/src/deployer/orchestrator.rs index 13f3228..efc67eb 100644 --- a/testing-framework/deployers/compose/src/deployer/orchestrator.rs +++ b/testing-framework/deployers/compose/src/deployer/orchestrator.rs @@ -118,7 +118,7 @@ impl DeploymentOrchestrator { let (block_feed, block_feed_guard) = client_builder .start_block_feed(&node_clients, &mut environment) .await?; - let cleanup_guard = make_cleanup_guard(environment.into_cleanup(), block_feed_guard); + let cleanup_guard = make_cleanup_guard(environment.into_cleanup()?, block_feed_guard); let context = RunContext::new( descriptors, diff --git a/testing-framework/deployers/compose/src/errors.rs b/testing-framework/deployers/compose/src/errors.rs index 9653eb4..b2f53f0 100644 --- a/testing-framework/deployers/compose/src/errors.rs +++ b/testing-framework/deployers/compose/src/errors.rs @@ -55,6 +55,8 @@ pub enum ComposeRunnerError { #[source] source: anyhow::Error, }, + #[error("internal invariant violated: {message}")] + InternalInvariant { message: &'static str }, } #[derive(Debug, thiserror::Error)] diff --git a/testing-framework/deployers/compose/src/infrastructure/environment.rs b/testing-framework/deployers/compose/src/infrastructure/environment.rs index 1104fb8..1ea8e96 100644 --- a/testing-framework/deployers/compose/src/infrastructure/environment.rs +++ b/testing-framework/deployers/compose/src/infrastructure/environment.rs @@ -84,28 +84,38 @@ impl StackEnvironment { } /// Convert into a cleanup guard while keeping the environment borrowed. - pub fn take_cleanup(&mut self) -> RunnerCleanup { - RunnerCleanup::new( + pub fn take_cleanup(&mut self) -> Result { + let workspace = self + .workspace + .take() + .ok_or(ComposeRunnerError::InternalInvariant { + message: "workspace must be available while cleaning up", + })?; + + Ok(RunnerCleanup::new( self.compose_path.clone(), self.project_name.clone(), self.root.clone(), - self.workspace - .take() - .expect("workspace must be available while cleaning up"), + workspace, self.cfgsync_handle.take(), - ) + )) } /// Convert into a cleanup guard, consuming the environment. - pub fn into_cleanup(self) -> RunnerCleanup { - RunnerCleanup::new( + pub fn into_cleanup(self) -> Result { + let workspace = self + .workspace + .ok_or(ComposeRunnerError::InternalInvariant { + message: "workspace must be available while cleaning up", + })?; + + Ok(RunnerCleanup::new( self.compose_path, self.project_name, self.root, - self.workspace - .expect("workspace must be available while cleaning up"), + workspace, self.cfgsync_handle, - ) + )) } /// Dump compose logs and trigger cleanup after a failure. @@ -115,7 +125,10 @@ impl StackEnvironment { "compose stack failure; dumping docker logs" ); dump_compose_logs(self.compose_path(), self.project_name(), self.root()).await; - Box::new(self.take_cleanup()).cleanup(); + match self.take_cleanup() { + Ok(cleanup) => Box::new(cleanup).cleanup(), + Err(err) => error!(error = %err, "failed to acquire cleanup guard"), + } } } diff --git a/testing-framework/deployers/compose/src/lifecycle/block_feed.rs b/testing-framework/deployers/compose/src/lifecycle/block_feed.rs index 2c27761..c86f869 100644 --- a/testing-framework/deployers/compose/src/lifecycle/block_feed.rs +++ b/testing-framework/deployers/compose/src/lifecycle/block_feed.rs @@ -49,5 +49,7 @@ pub async fn spawn_block_feed_with_retry( } } - Err(last_err.expect("block feed retry should capture an error")) + Err(last_err.unwrap_or(ComposeRunnerError::InternalInvariant { + message: "block feed retry exhausted without capturing an error", + })) }