Negative test: long multibyte sealing failure must abort and free the target
Fails at 5b421c3 (abort write refused by require_detail).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5b421c3cc7
commit
81ab69046b
1 changed files with 57 additions and 0 deletions
|
|
@ -16866,6 +16866,63 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// A source whose resolve step fails with a fixed message, as a build or
|
||||
/// resolve step does when its output is a long log.
|
||||
struct FailingSource {
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl SourcePort for FailingSource {
|
||||
fn resolve(
|
||||
&self,
|
||||
_: &OperatorBinding,
|
||||
_: &str,
|
||||
_: u64,
|
||||
) -> Result<crate::drivers::ResolvedSource> {
|
||||
bail!("{}", self.message)
|
||||
}
|
||||
|
||||
fn freeze(&self, _: &str, _: &CompiledDeploymentPlan) -> Result<FrozenSourceReceipt> {
|
||||
bail!("this source freezes nothing")
|
||||
}
|
||||
|
||||
fn observe_frozen(
|
||||
&self,
|
||||
_: &CompiledDeploymentPlan,
|
||||
_: &FrozenSourceReceipt,
|
||||
) -> Result<crate::drivers::FrozenSource> {
|
||||
bail!("this source freezes nothing")
|
||||
}
|
||||
|
||||
fn cleanup(&self, _: &str, _: Option<&FrozenSourceReceipt>) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_sealing_failure_with_a_long_multibyte_error_aborts_and_frees_the_target() -> Result<()> {
|
||||
// 3000 chars of 3-byte box drawing: 9000 bytes, the shape of a build log.
|
||||
let log = format!("{}\nthe real error is here", "\u{2500}".repeat(3000));
|
||||
let mut world = sealing_world(&unrouted_recipe())?;
|
||||
world.engine.source = Arc::new(FailingSource { message: log });
|
||||
for _ in 0..8 {
|
||||
let _ = world.engine.run_scheduler_tick();
|
||||
}
|
||||
assert!(
|
||||
resident(&world).is_err(),
|
||||
"the failed transaction still owns the target"
|
||||
);
|
||||
let done = latest(&world)?;
|
||||
let TransactionCompletion::FailedBeforeFencing { error } =
|
||||
done.completion.context("the aborted transaction did not complete")?
|
||||
else {
|
||||
bail!("the transaction did not fail before fencing");
|
||||
};
|
||||
assert!(error.len() <= 2048, "{}", error.len());
|
||||
assert!(error.ends_with("the real error is here"), "the tail was lost");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn admission_takes_a_recipe_that_declares_its_proof() -> Result<()> {
|
||||
let recipe = unrouted_recipe().replace(
|
||||
|
|
|
|||
Loading…
Reference in a new issue