use super::*;
#[test]
fn unconfigured_limits_allow_anything_that_fits() {
let free = MIN_FREE_BYTES * 100;
assert_eq!(
check_write(WriteLimits::default(), 0, free / 2, Some(free)),
WriteVerdict::Allow
);
}
#[test]
fn a_write_that_would_fill_the_disk_is_refused() {
let verdict = check_write(WriteLimits::default(), 0, 500, Some(MIN_FREE_BYTES + 100));
assert_eq!(
verdict,
WriteVerdict::OutOfSpace {
available: MIN_FREE_BYTES + 100,
required: MIN_FREE_BYTES,
}
);
assert_eq!(
check_write(WriteLimits::default(), 0, 500, Some(MIN_FREE_BYTES * 2)),
WriteVerdict::Allow
);
}
#[test]
fn an_unmeasurable_filesystem_does_not_refuse() {
assert_eq!(
check_write(WriteLimits::default(), 0, u64::MAX / 2, None),
WriteVerdict::Allow
);
}
#[test]
fn an_unmeasurable_filesystem_still_obeys_the_configured_ceilings() {
let limits = WriteLimits {
per_call: Some(100),
per_run: None,
};
assert!(matches!(
check_write(limits, 0, 101, None),
WriteVerdict::CallTooLarge { .. }
));
}
#[test]
fn the_per_call_ceiling_is_exclusive_at_the_boundary() {
let limits = WriteLimits {
per_call: Some(100),
per_run: None,
};
let plenty = Some(MIN_FREE_BYTES * 100);
assert_eq!(check_write(limits, 0, 100, plenty), WriteVerdict::Allow);
assert_eq!(
check_write(limits, 0, 101, plenty),
WriteVerdict::CallTooLarge {
bytes: 101,
limit: 100
}
);
}
#[test]
fn the_per_run_ceiling_counts_earlier_calls() {
let limits = WriteLimits {
per_call: Some(1000),
per_run: Some(1000),
};
let plenty = Some(MIN_FREE_BYTES * 100);
assert_eq!(check_write(limits, 0, 600, plenty), WriteVerdict::Allow);
assert_eq!(
check_write(limits, 600, 600, plenty),
WriteVerdict::RunTooLarge {
written: 1200,
limit: 1000
}
);
}
#[test]
fn a_run_already_over_budget_refuses_even_an_empty_write() {
let limits = WriteLimits {
per_call: None,
per_run: Some(100),
};
assert!(matches!(
check_write(limits, 200, 0, Some(MIN_FREE_BYTES * 100)),
WriteVerdict::RunTooLarge { .. }
));
}
#[test]
fn a_full_disk_is_reported_before_a_configured_ceiling() {
let limits = WriteLimits {
per_call: Some(10),
per_run: Some(10),
};
assert!(matches!(
check_write(limits, 0, 5_000, Some(MIN_FREE_BYTES)),
WriteVerdict::OutOfSpace { .. }
));
}
#[test]
fn a_run_total_that_would_overflow_saturates_rather_than_wrapping() {
let limits = WriteLimits {
per_call: None,
per_run: Some(100),
};
assert!(matches!(
check_write(limits, u64::MAX, 10, Some(MIN_FREE_BYTES * 100)),
WriteVerdict::RunTooLarge { .. }
));
}
#[test]
fn every_refusal_names_its_number_and_allow_says_nothing() {
assert_eq!(WriteVerdict::Allow.refusal(), None);
for verdict in [
WriteVerdict::OutOfSpace {
available: 7,
required: 9,
},
WriteVerdict::CallTooLarge {
bytes: 11,
limit: 13,
},
WriteVerdict::RunTooLarge {
written: 17,
limit: 19,
},
] {
let message = verdict.refusal().expect("a refusal explains itself");
assert!(message.starts_with("[denied]"), "{message}");
assert!(
message.chars().any(|c| c.is_ascii_digit()),
"no figure in: {message}"
);
}
let disk = WriteVerdict::OutOfSpace {
available: 7,
required: 9,
}
.refusal()
.expect("a refusal");
assert!(!disk.contains("max_"), "{disk}");
}