Propagate FTP preflight cancellation
CI / checks (pull_request) Successful in 2m37s
Agents / bot (pull_request) Successful in 6m58s

This commit is contained in:
Danny Kim
2026-09-30 20:06:43 +09:00
parent a1c449843f
commit 25d572aa33
3 changed files with 34 additions and 2 deletions
+6 -2
View File
@@ -100,8 +100,12 @@ fn with_control<T>(
/// idle session is replaced and logged in again. Nothing inside a transfer or
/// mutation retries, because its missing reply may hide a completed change.
fn ready() -> Result<(), ErrorCode> {
if with_control(|control| control.expect("NOOP")).is_ok() {
return Ok(());
if !CONTROL.with_borrow(Option::is_none) {
match with_control(|control| control.expect("NOOP")) {
Ok(_) => return Ok(()),
Err(ErrorCode::Unavailable) => {}
Err(error) => return Err(error),
}
}
let session = SESSION
.with_borrow(Clone::clone)
+17
View File
@@ -58,3 +58,20 @@ async fn recovery_before_a_mutation_never_replays_a_lost_mutation_reply()
assert_eq!(summary.mkdir_commands, 1);
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(())
}
+11
View File
@@ -13,6 +13,7 @@ const LISTING: &[u8] = b"type=file;size=3; report.md \r\n";
#[derive(Clone, Copy)]
pub enum Scenario {
CancelledPreflight,
ExpiredListing,
LostMutationReply,
}
@@ -142,6 +143,9 @@ impl Tcp {
state.listings += 1;
"150 Listing\r\n226 Complete\r\n"
}
"NOOP" if matches!(state.scenario, Scenario::CancelledPreflight) => {
return Err(HostError::Cancelled);
}
"NOOP"
if index == 0
&& (matches!(state.scenario, Scenario::LostMutationReply)
@@ -157,6 +161,13 @@ impl Tcp {
state.mkdir_commands += 1;
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),
}
};