use std::sync::atomic::{AtomicU64, Ordering};
use super::super::receive::{Reservation, check_space};
use super::*;
#[test]
fn check_space_insufficient_bytes_or_margin_refuses_receive() {
let directory = std::path::Path::new("receive");
let result = check_space(directory, 1, 0, |path| {
assert_eq!(path, directory);
Ok(256 * 1024 * 1024)
});
assert_eq!(result, Err(Failure::NoSpace));
}
#[test]
fn check_space_resumed_bytes_requires_only_remainder_and_margin() {
let directory = std::path::Path::new("receive");
let total = 1024 * 1024 * 1024;
let remainder = 7;
let result = check_space(directory, total, total - remainder, |_| {
Ok(256 * 1024 * 1024 + remainder)
});
assert_eq!(result, Ok(()));
}
#[test]
fn check_space_lookup_failure_allows_receive() {
let directory = std::path::Path::new("receive");
let result = check_space(directory, 1, 0, |_| Err(std::io::ErrorKind::Other.into()));
assert_eq!(result, Ok(()));
}
#[test]
fn check_space_required_bytes_overflow_refuses_receive() {
let directory = std::path::Path::new("receive");
let result = check_space(directory, u64::MAX, 0, |_| Ok(u64::MAX));
assert_eq!(result, Err(Failure::NoSpace));
}
#[tokio::test]
async fn files_finished_no_space_reports_distinct_accept_failure() {
let (mut daemon, _dir) = daemon();
let peer = MachineId::try_from([1; MachineId::LEN].as_slice()).unwrap();
let (reply, response) = oneshot::channel();
daemon.files.accepts.insert((peer, 1), reply);
let (cancel, _) = watch::channel(Failure::Cancelled);
daemon.files.active.insert(
1,
Active {
peer,
link: 0,
wire_id: 1,
offer: 1,
kind: Kind::Offer,
direction: TransferDirection::Receive,
cancel,
progress: Arc::new(Progress::default()),
},
);
daemon.files_finished(1, Err(Failure::NoSpace));
let error = response.await.unwrap().unwrap_err();
assert!(matches!(error, DaemonError::NoSpace));
assert_eq!(
error.to_string(),
"not enough free space in the receive directory"
);
assert!(daemon.files.active.is_empty());
assert!(daemon.files.accepts.is_empty());
}
#[test]
fn reservation_parallel_receives_see_each_other_until_dropped() {
let reserved = AtomicU64::new(0);
let first = Reservation::new(&reserved, 300);
let second = Reservation::new(&reserved, 200);
let others = second.others;
drop(first);
drop(second);
assert_eq!(others, 300);
assert_eq!(reserved.load(Ordering::Relaxed), 0);
}