diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-20 17:17:38 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-12-21 08:39:33 +0000 |
commit | 9ebdb81cfe6b479ff723df9366e1399598288b1f (patch) | |
tree | 19ac429f4187575582f8c111a6ac965eb16bd638 /subplotlib | |
parent | c25d2a1991bf436bc17161325b677a39853529b4 (diff) | |
download | subplot-9ebdb81cfe6b479ff723df9366e1399598288b1f.tar.gz |
rust: Handle poison differently for cleanups
When cleanup functions are run, permit them to run with
poisoned contexts. Cleanup functions will have to be resilient
to this risk. If cleanup functions fail then the test will panic
properly.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'subplotlib')
-rw-r--r-- | subplotlib/src/scenario.rs | 14 | ||||
-rw-r--r-- | subplotlib/src/step.rs | 8 |
2 files changed, 11 insertions, 11 deletions
diff --git a/subplotlib/src/scenario.rs b/subplotlib/src/scenario.rs index cf272f2..ec3f28f 100644 --- a/subplotlib/src/scenario.rs +++ b/subplotlib/src/scenario.rs @@ -28,16 +28,16 @@ impl ScenarioContext { } /// With the extracted immutable context, run the function f. - pub fn with<C, F>(&self, func: F, permit_poison: bool) -> StepResult + pub fn with<C, F>(&self, func: F, defuse_poison: bool) -> StepResult where F: FnOnce(&C) -> StepResult, C: Default + Send + 'static, { - self.with_mut(|c: &mut C| func(&*c), permit_poison) + self.with_mut(|c: &mut C| func(&*c), defuse_poison) } /// With the extracted mutable context, run the function f. - pub fn with_mut<C, F>(&self, func: F, permit_poison: bool) -> StepResult + pub fn with_mut<C, F>(&self, func: F, defuse_poison: bool) -> StepResult where F: FnOnce(&mut C) -> StepResult, C: Default + Send + 'static, @@ -52,10 +52,10 @@ impl ScenarioContext { let mut lock = match sci.0.lock() { Ok(lock) => lock, Err(pe) => { - if permit_poison { + if defuse_poison { pe.into_inner() } else { - return Err("step paniced".into()); + return Err("context poisoned by panic".into()); } } }; @@ -108,7 +108,7 @@ impl Scenario { let mut highest = None; let mut ret = Ok(()); for (i, step) in self.steps.iter().map(|(step, _)| step).enumerate() { - let res = step.call(&self.contexts); + let res = step.call(&self.contexts, false); if res.is_err() { ret = res; break; @@ -118,7 +118,7 @@ impl Scenario { if let Some(n) = highest { for stepn in (0..=n).rev() { if let (_, Some(cleanup)) = &self.steps[stepn] { - if let Err(e) = cleanup.call(&self.contexts) { + if let Err(e) = cleanup.call(&self.contexts, true) { panic!("Failure during cleanup: {:?}", e); } } diff --git a/subplotlib/src/step.rs b/subplotlib/src/step.rs index f83b29d..ca40550 100644 --- a/subplotlib/src/step.rs +++ b/subplotlib/src/step.rs @@ -16,7 +16,7 @@ use crate::types::StepResult; /// reporting an error encountered in running a scenario. pub struct ScenarioStep { name: String, - func: Box<dyn Fn(&ScenarioContext) -> StepResult>, + func: Box<dyn Fn(&ScenarioContext, bool) -> StepResult>, } impl ScenarioStep { @@ -27,7 +27,7 @@ impl ScenarioStep { /// called from the generated build method for the step. pub fn new<F>(name: &str, func: F) -> Self where - F: Fn(&ScenarioContext) -> StepResult + 'static, + F: Fn(&ScenarioContext, bool) -> StepResult + 'static, { Self { name: name.to_string(), @@ -51,11 +51,11 @@ impl ScenarioStep { /// Call the step function /// /// This simply calls the encased step function - pub fn call(&self, context: &ScenarioContext) -> StepResult { + pub fn call(&self, context: &ScenarioContext, defuse_poison: bool) -> StepResult { // Note, panic here will be absorbed and so there's a risk that // subsequent step calls may not be sound. There's not a lot we can // do to ensure things are good except try. - let func = AssertUnwindSafe(|| (*self.func)(context)); + let func = AssertUnwindSafe(|| (*self.func)(context, defuse_poison)); catch_unwind(func).map_err(|e| Self::render_panic(self.name(), e))? } |