Propagate FTP preflight cancellation
This commit is contained in:
+6
-2
@@ -100,8 +100,12 @@ fn with_control<T>(
|
|||||||
/// idle session is replaced and logged in again. Nothing inside a transfer or
|
/// idle session is replaced and logged in again. Nothing inside a transfer or
|
||||||
/// mutation retries, because its missing reply may hide a completed change.
|
/// mutation retries, because its missing reply may hide a completed change.
|
||||||
fn ready() -> Result<(), ErrorCode> {
|
fn ready() -> Result<(), ErrorCode> {
|
||||||
if with_control(|control| control.expect("NOOP")).is_ok() {
|
if !CONTROL.with_borrow(Option::is_none) {
|
||||||
return Ok(());
|
match with_control(|control| control.expect("NOOP")) {
|
||||||
|
Ok(_) => return Ok(()),
|
||||||
|
Err(ErrorCode::Unavailable) => {}
|
||||||
|
Err(error) => return Err(error),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let session = SESSION
|
let session = SESSION
|
||||||
.with_borrow(Clone::clone)
|
.with_borrow(Clone::clone)
|
||||||
|
|||||||
@@ -58,3 +58,20 @@ async fn recovery_before_a_mutation_never_replays_a_lost_mutation_reply()
|
|||||||
assert_eq!(summary.mkdir_commands, 1);
|
assert_eq!(summary.mkdir_commands, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn cancelled_preflight_never_reconnects_or_executes_the_mutation()
|
||||||
|
-> TestResult {
|
||||||
|
let fixture = test_host::install(test_host::Scenario::CancelledPreflight);
|
||||||
|
guest(Ftp::open("ftp".into(), config()))?;
|
||||||
|
assert!(matches!(
|
||||||
|
Ftp::mkdir(Locator::Path("/cancelled".into())),
|
||||||
|
Err(ErrorCode::Cancelled)
|
||||||
|
));
|
||||||
|
Ftp::close();
|
||||||
|
let summary = fixture.summary();
|
||||||
|
assert_eq!(summary.control_connections, 1);
|
||||||
|
assert_eq!(summary.listings, 0);
|
||||||
|
assert_eq!(summary.mkdir_commands, 0);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ const LISTING: &[u8] = b"type=file;size=3; report.md \r\n";
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Scenario {
|
pub enum Scenario {
|
||||||
|
CancelledPreflight,
|
||||||
ExpiredListing,
|
ExpiredListing,
|
||||||
LostMutationReply,
|
LostMutationReply,
|
||||||
}
|
}
|
||||||
@@ -142,6 +143,9 @@ impl Tcp {
|
|||||||
state.listings += 1;
|
state.listings += 1;
|
||||||
"150 Listing\r\n226 Complete\r\n"
|
"150 Listing\r\n226 Complete\r\n"
|
||||||
}
|
}
|
||||||
|
"NOOP" if matches!(state.scenario, Scenario::CancelledPreflight) => {
|
||||||
|
return Err(HostError::Cancelled);
|
||||||
|
}
|
||||||
"NOOP"
|
"NOOP"
|
||||||
if index == 0
|
if index == 0
|
||||||
&& (matches!(state.scenario, Scenario::LostMutationReply)
|
&& (matches!(state.scenario, Scenario::LostMutationReply)
|
||||||
@@ -157,6 +161,13 @@ impl Tcp {
|
|||||||
state.mkdir_commands += 1;
|
state.mkdir_commands += 1;
|
||||||
return Ok(bytes.len() as u32);
|
return Ok(bytes.len() as u32);
|
||||||
}
|
}
|
||||||
|
"MKD /cancelled"
|
||||||
|
if index == 1
|
||||||
|
&& matches!(state.scenario, Scenario::CancelledPreflight) =>
|
||||||
|
{
|
||||||
|
state.mkdir_commands += 1;
|
||||||
|
return Err(HostError::Unavailable);
|
||||||
|
}
|
||||||
_ => return Err(HostError::InvalidInput),
|
_ => return Err(HostError::InvalidInput),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user