use setback::{can_recover, protect, protect_cause, recover, RecoveryError, RecoveryFailure};
const OOM: i32 = 2;
const STACK_OVERFLOW: i32 = 1;
#[test]
fn matching_cause_recovers() {
const TID: usize = 71;
let r: Result<(), RecoveryError> = unsafe {
protect_cause(TID, OOM, || {
let _ = recover(TID, OOM);
})
};
assert_eq!(r, Err(RecoveryError { cause: OOM }));
}
#[test]
fn non_matching_cause_is_skipped() {
const TID: usize = 72;
let r: Result<&str, RecoveryError> = unsafe {
protect_cause(TID, OOM, || {
let miss = recover(TID, STACK_OVERFLOW);
assert_eq!(miss, Err(RecoveryFailure));
"ran to completion"
})
};
assert_eq!(r, Ok("ran to completion"));
}
#[test]
fn non_matching_inner_resolves_to_outer() {
const TID: usize = 73;
let outer: Result<(), RecoveryError> = unsafe {
protect(TID, || {
let _inner: Result<(), RecoveryError> = protect_cause(TID, OOM, || {
let _ = recover(TID, STACK_OVERFLOW);
});
unreachable!("recover jumped to the outer scope, not back here");
})
};
assert_eq!(outer, Err(RecoveryError { cause: STACK_OVERFLOW }));
}
#[test]
fn a_skipped_scope_leaves_the_list_when_the_jump_passes_it() {
const TID: usize = 74;
let outer: Result<(), RecoveryError> = unsafe {
protect(TID, || {
let _inner: Result<(), RecoveryError> = protect_cause(TID, OOM, || {
let _ = recover(TID, STACK_OVERFLOW);
});
unreachable!("recover jumped to the outer scope, not back here");
})
};
assert_eq!(outer, Err(RecoveryError { cause: STACK_OVERFLOW }));
assert!(!can_recover(TID, OOM));
assert!(!can_recover(TID, STACK_OVERFLOW));
}
#[test]
fn every_skipped_scope_leaves_the_list_not_just_the_innermost() {
const TID: usize = 75;
const TIMEOUT: i32 = 3;
let outer: Result<(), RecoveryError> = unsafe {
protect(TID, || {
let _middle: Result<(), RecoveryError> = protect_cause(TID, OOM, || {
let _inner: Result<(), RecoveryError> = protect_cause(TID, TIMEOUT, || {
let _ = recover(TID, STACK_OVERFLOW);
});
unreachable!("the jump passed both inner scopes");
});
unreachable!("recover jumped to the outer scope, not back here");
})
};
assert_eq!(outer, Err(RecoveryError { cause: STACK_OVERFLOW }));
assert!(!can_recover(TID, OOM));
assert!(!can_recover(TID, TIMEOUT));
assert!(!can_recover(TID, STACK_OVERFLOW));
}