use setback::{can_recover, protect, protect_cause, recover, RecoveryError, RecoveryFailure};
const OOM: i32 = 2;
const STACK_OVERFLOW: i32 = 1;
#[test]
fn tracks_the_scope() {
const TID: usize = 91;
assert!(!can_recover(TID, OOM));
let r: Result<(), RecoveryError> = unsafe {
protect(TID, || {
assert!(can_recover(TID, OOM));
})
};
assert_eq!(r, Ok(()));
assert!(!can_recover(TID, OOM), "the mark is unlinked on the way out");
}
#[test]
fn other_tid_is_not_covered() {
const TID: usize = 92;
const OTHER: usize = 93;
let r: Result<(), RecoveryError> = unsafe {
protect(TID, || {
assert!(can_recover(TID, OOM));
assert!(!can_recover(OTHER, OOM));
})
};
assert_eq!(r, Ok(()));
}
#[test]
fn honours_the_cause_filter() {
const TID: usize = 94;
let r: Result<&str, RecoveryError> = unsafe {
protect_cause(TID, OOM, || {
assert!(can_recover(TID, OOM));
assert!(!can_recover(TID, STACK_OVERFLOW));
let miss = recover(TID, STACK_OVERFLOW);
assert_eq!(miss, Err(RecoveryFailure));
"ran to completion"
})
};
assert_eq!(r, Ok("ran to completion"));
}
#[test]
fn sees_past_a_rejecting_inner_scope() {
const TID: usize = 95;
let outer: Result<(), RecoveryError> = unsafe {
protect(TID, || {
let _inner: Result<(), RecoveryError> = protect_cause(TID, OOM, || {
assert!(can_recover(TID, STACK_OVERFLOW));
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 false_again_after_recovery() {
const TID: usize = 96;
let r: Result<(), RecoveryError> = unsafe {
protect(TID, || {
let _ = recover(TID, OOM);
})
};
assert_eq!(r, Err(RecoveryError { cause: OOM }));
assert!(!can_recover(TID, OOM));
}