Skip to content

Commit b5e1144

Browse files
procr1337hannesdejager
authored andcommitted
simplify tests by using FtpStream
1 parent 522474b commit b5e1144

1 file changed

Lines changed: 34 additions & 67 deletions

File tree

crates/unftp-sbe-fs/tests/main.rs

Lines changed: 34 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -654,20 +654,14 @@ mod mlsd {
654654
}
655655
}
656656

657-
async fn read_response(stream: &TcpStream) -> String {
658-
let mut buffer = vec![0u8; 4096];
659-
loop {
660-
stream.readable().await.unwrap();
661-
match stream.try_read(&mut buffer) {
662-
Ok(n) => return String::from_utf8_lossy(&buffer[0..n]).to_string(),
663-
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => continue,
664-
Err(e) => panic!("Failed to read response: {}", e),
665-
};
666-
}
657+
async fn connect(addr: &str) -> FtpStream {
658+
let mut ftp_stream = FtpStream::connect(addr).await.unwrap();
659+
ftp_stream.login("hoi", "jij").await.unwrap();
660+
ftp_stream
667661
}
668662

669663
fn parse_pasv_response(response: &str) -> u16 {
670-
// Parse "227 Entering Passive Mode (127,0,0,1,p1,p2)"
664+
// Parse "Entering Passive Mode (127,0,0,1,p1,p2)"
671665
// Port = p1 * 256 + p2
672666
let start = response.find('(').unwrap() + 1;
673667
let end = response.find(')').unwrap();
@@ -678,43 +672,28 @@ mod mlsd {
678672
p1 * 256 + p2
679673
}
680674

681-
async fn connect(addr: &str) -> TcpStream {
682-
let stream = TcpStream::connect(addr).await.unwrap();
683-
684-
let greeting = read_response(&stream).await;
685-
assert!(greeting.starts_with("220"), "Expected greeting, got: {}", greeting);
686-
687-
// Authenticate
688-
send_command(&stream, "USER hoi").await;
689-
let response = read_response(&stream).await;
690-
assert!(response.starts_with("331"), "Expected password request, got: {}", response);
691-
692-
send_command(&stream, "PASS jij").await;
693-
let response = read_response(&stream).await;
694-
assert!(response.starts_with("230"), "Expected login success, got: {}", response);
695-
696-
stream
697-
}
698-
699-
async fn connect_pasv(stream: &TcpStream) -> TcpStream {
700-
send_command(&stream, "PASV").await;
701-
let pasv_response = read_response(&stream).await;
702-
assert!(pasv_response.starts_with("227"), "Expected PASV response, got: {}", pasv_response);
703-
let data_port = parse_pasv_response(&pasv_response);
675+
async fn connect_pasv(ftp: &mut FtpStream) -> TcpStream {
676+
send_command(ftp.get_ref(), "PASV").await;
677+
let pasv_response = ftp.read_response(227).await.unwrap();
678+
let data_port = parse_pasv_response(&pasv_response.1);
704679
TcpStream::connect(format!("127.0.0.1:{}", data_port)).await.unwrap()
705680
}
706681

707-
async fn read_all_data(stream: &TcpStream) -> String {
682+
async fn read_all(stream: &TcpStream, until_eof: bool) -> String {
708683
let mut data = String::new();
709684
let mut buffer = vec![0u8; 1024];
710-
685+
let mut blocks = 0;
711686
loop {
712687
match stream.try_read(&mut buffer) {
713688
Ok(0) => break, // EOF
714689
Ok(n) => {
715690
data.push_str(&String::from_utf8_lossy(&buffer[0..n]));
716691
}
717692
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
693+
blocks += 1;
694+
if !until_eof && blocks >= 2 {
695+
break;
696+
}
718697
// Wait a bit for more data or connection close
719698
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
720699
continue;
@@ -740,20 +719,14 @@ mod mlsd {
740719
}
741720
}
742721

743-
async fn consume_226(stream: &TcpStream) {
744-
let response = read_response(&stream).await;
745-
let response = response.strip_suffix("\r\n").unwrap();
746-
assert!(response.starts_with("226 ") && !response.contains("\r\n"), "Expected 226, got: {}", response);
747-
}
748-
749722
#[rstest]
750723
#[awt]
751724
#[tokio::test]
752725
async fn basic_mlsd(#[future] harness: Harness) {
753726
setup_files(&harness.root);
754727

755-
let stream = connect(&harness.addr).await;
756-
let data_stream = connect_pasv(&stream).await;
728+
let mut ftp = connect(&harness.addr).await;
729+
let data_stream = connect_pasv(&mut ftp).await;
757730

758731
// MLSD uses data channel. Example from RFC 3659 (truncated):
759732
//
@@ -764,16 +737,10 @@ mod mlsd {
764737
// D> Type=file;Size=1830;Modify=19940916055648;Perm=r; hatch.c
765738
// ...
766739
// S> 226 MLSD completed
767-
send_command(&stream, "MLSD").await;
768-
let response = read_response(&stream).await;
769-
let response = response.strip_suffix("\r\n").unwrap();
770-
assert!(
771-
response.starts_with("150 ") && !response.trim().contains("\r\n"),
772-
"Expected data connection opening, got: {}",
773-
response
774-
);
775-
776-
let data = read_all_data(&data_stream).await;
740+
send_command(ftp.get_ref(), "MLSD").await;
741+
ftp.read_response(150).await.unwrap();
742+
743+
let data = read_all(&data_stream, true).await;
777744
let mut entries = data.split("\r\n").collect::<Vec<_>>();
778745
assert!(entries.pop().unwrap().is_empty(), "Last line should be empty due to trailing CRLF");
779746

@@ -787,7 +754,7 @@ mod mlsd {
787754
check_facts(file_line, &["type=file", "size=12"]);
788755
check_facts(dir_line, &["type=dir"]);
789756

790-
consume_226(&stream).await;
757+
ftp.read_response(226).await.unwrap();
791758
}
792759

793760
#[rstest]
@@ -796,14 +763,13 @@ mod mlsd {
796763
async fn mlsd_with_path(#[future] harness: Harness) {
797764
setup_files(&harness.root);
798765

799-
let stream = connect(&harness.addr).await;
800-
let data_stream = connect_pasv(&stream).await;
766+
let mut ftp = connect(&harness.addr).await;
767+
let data_stream = connect_pasv(&mut ftp).await;
801768

802-
send_command(&stream, "MLSD test_dir").await;
803-
let response = read_response(&stream).await;
804-
assert!(response.starts_with("150 "), "Expected data connection opening, got: {}", response);
769+
send_command(ftp.get_ref(), "MLSD test_dir").await;
770+
ftp.read_response(150).await.unwrap();
805771

806-
let data = read_all_data(&data_stream).await;
772+
let data = read_all(&data_stream, true).await;
807773
let mut entries = data.split("\r\n").collect::<Vec<_>>();
808774
assert!(entries.pop().unwrap().is_empty(), "Last line should be empty due to trailing CRLF");
809775
assert_eq!(entries.len(), 1);
@@ -815,7 +781,7 @@ mod mlsd {
815781

816782
check_facts(&file_line, &["type=file", "size=0"]);
817783

818-
consume_226(&stream).await;
784+
ftp.read_response(226).await.unwrap();
819785
}
820786

821787
#[rstest]
@@ -824,15 +790,16 @@ mod mlsd {
824790
async fn mlst(#[future] harness: Harness) {
825791
setup_files(&harness.root);
826792

827-
let stream = connect(&harness.addr).await;
793+
let ftp = connect(&harness.addr).await;
828794

829795
// MLST uses control channel, not data channel. Format:
830796
//
831797
// 250- Listing
832798
// Type=file;Size=1234;... filename.txt
833799
// 250 End
834-
send_command(&stream, "MLST test_file.txt").await;
835-
let response = read_response(&stream).await;
800+
let stream = ftp.get_ref();
801+
send_command(stream, "MLST test_file.txt").await;
802+
let response = read_all(stream, false).await;
836803
let line = response
837804
.strip_prefix("250- Listing\r\n ")
838805
.expect("Wrong prefix")
@@ -842,8 +809,8 @@ mod mlsd {
842809
println!("line {line}");
843810
check_facts(line, &["type=file", "size=12"]);
844811

845-
send_command(&stream, "MLST test_dir").await;
846-
let response = read_response(&stream).await;
812+
send_command(stream, "MLST test_dir").await;
813+
let response = read_all(stream, false).await;
847814

848815
let line = response
849816
.strip_prefix("250- Listing\r\n ")

0 commit comments

Comments
 (0)