Skip to content

Commit 07b38b2

Browse files
committed
Add bigfile and openfile flag testcases
1 parent 016aec2 commit 07b38b2

File tree

5 files changed

+164
-39
lines changed

5 files changed

+164
-39
lines changed

clients/filesystem-fuse/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ doc-test:
6262
unit-test: doc-test
6363
cargo test --no-fail-fast --lib --all-features --workspace
6464

65+
test-it:
66+
cargo test --test fuse_test
67+
6568
test-fuse-it:
6669
@bash ./tests/bin/run_fuse_testers.sh test
6770

clients/filesystem-fuse/src/filesystem.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ pub trait FileWriter: Sync + Send {
297297
#[cfg(test)]
298298
pub(crate) mod tests {
299299
use super::*;
300-
use libc::{O_APPEND, O_CREAT, O_RDONLY};
300+
use libc::{O_CREAT, O_RDONLY, O_RDWR};
301301
use std::collections::HashMap;
302302
use std::path::Component;
303303

@@ -548,7 +548,7 @@ pub(crate) mod tests {
548548
async fn test_create_file(&mut self, root_file_id: u64, name: &OsStr) -> FileHandle {
549549
let file = self
550550
.fs
551-
.create_file(root_file_id, name, (O_CREAT | O_APPEND) as u32)
551+
.create_file(root_file_id, name, (O_CREAT | O_RDWR) as u32)
552552
.await;
553553
assert!(file.is_ok());
554554
let file = file.unwrap();

clients/filesystem-fuse/src/memory_filesystem.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl PathFileSystem for MemoryFileSystem {
9191
Ok(results)
9292
}
9393

94-
async fn open_file(&self, path: &Path, _flags: OpenFileFlags) -> Result<OpenedFile> {
94+
async fn open_file(&self, path: &Path, flags: OpenFileFlags) -> Result<OpenedFile> {
9595
let file_stat = self.stat(path).await?;
9696
let mut opened_file = OpenedFile::new(file_stat);
9797
match opened_file.file_stat.kind {
@@ -105,8 +105,18 @@ impl PathFileSystem for MemoryFileSystem {
105105
.unwrap()
106106
.data
107107
.clone();
108-
opened_file.reader = Some(Box::new(MemoryFileReader { data: data.clone() }));
109-
opened_file.writer = Some(Box::new(MemoryFileWriter { data: data }));
108+
if flags.is_read() {
109+
110+
opened_file.reader = Some(Box::new(MemoryFileReader { data: data.clone() }));
111+
}
112+
if flags.is_write() || flags.is_append() {
113+
opened_file.writer = Some(Box::new(MemoryFileWriter { data: data.clone() }));
114+
}
115+
116+
if flags.is_truncate() {
117+
let mut data = data.lock().unwrap();
118+
data.clear();
119+
}
110120
Ok(opened_file)
111121
}
112122
_ => Err(Errno::from(libc::EBADF)),
@@ -117,27 +127,19 @@ impl PathFileSystem for MemoryFileSystem {
117127
self.open_file(path, flags).await
118128
}
119129

120-
async fn create_file(&self, path: &Path, _flags: OpenFileFlags) -> Result<OpenedFile> {
121-
let mut file_map = self.file_map.write().unwrap();
122-
if file_map.contains_key(path) {
130+
async fn create_file(&self, path: &Path, flags: OpenFileFlags) -> Result<OpenedFile> {
131+
if self.file_map.read().unwrap().contains_key(path) && flags.is_exclusive() {
123132
return Err(Errno::from(libc::EEXIST));
124133
}
125134

126-
let mut opened_file = OpenedFile::new(FileStat::new_file_filestat_with_path(path, 0));
127-
128-
let data = Arc::new(Mutex::new(Vec::new()));
129-
file_map.insert(
130-
opened_file.file_stat.path.clone(),
135+
self.file_map.write().unwrap().insert(
136+
path.to_path_buf(),
131137
MemoryFile {
132138
kind: RegularFile,
133-
data: data.clone(),
139+
data: Arc::new(Mutex::new(Vec::new())),
134140
},
135141
);
136-
137-
opened_file.reader = Some(Box::new(MemoryFileReader { data: data.clone() }));
138-
opened_file.writer = Some(Box::new(MemoryFileWriter { data: data }));
139-
140-
Ok(opened_file)
142+
self.open_file(path, flags).await
141143
}
142144

143145
async fn create_dir(&self, path: &Path) -> Result<FileStat> {

clients/filesystem-fuse/src/open_dal_filesystem.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,11 @@ impl PathFileSystem for OpenDalFileSystem {
120120
.map_err(opendal_error_to_errno)?;
121121
file.reader = Some(Box::new(FileReaderImpl { reader }));
122122
}
123-
if flags.is_write() || flags.is_create() || flags.is_append() || flags.is_truncate() {
123+
if !flags.is_create() && flags.is_append() {
124+
return Err(Errno::from(libc::EBADF));
125+
}
126+
127+
if flags.is_write() || flags.is_truncate() {
124128
let writer = self
125129
.op
126130
.writer_with(&file_name)

clients/filesystem-fuse/tests/fuse_test.rs

+135-19
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use gvfs_fuse::config::AppConfig;
2222
use gvfs_fuse::RUN_TEST_WITH_FUSE;
2323
use gvfs_fuse::{gvfs_mount, gvfs_unmount, test_enable_with};
2424
use log::{error, info};
25-
use std::fs::File;
25+
use std::fs::{File, OpenOptions};
26+
use std::io::{Read, Seek, SeekFrom, Write};
2627
use std::path::Path;
2728
use std::sync::Arc;
2829
use std::thread::sleep;
@@ -89,11 +90,6 @@ impl Drop for FuseTest {
8990
fn test_fuse_with_memory_fs() {
9091
tracing_subscriber::fmt().init();
9192

92-
panic::set_hook(Box::new(|info| {
93-
error!("A panic occurred: {:?}", info);
94-
process::exit(1);
95-
}));
96-
9793
let mount_point = "target/gvfs";
9894
let _ = fs::create_dir_all(mount_point);
9995

@@ -104,26 +100,31 @@ fn test_fuse_with_memory_fs() {
104100
};
105101

106102
test.setup();
107-
test_fuse_filesystem(mount_point);
103+
104+
let test_dir = Path::new(&test.mount_point).join("test_dir");
105+
run_tests(&test_dir);
106+
}
107+
108+
fn run_tests(test_dir: &Path) {
109+
fs::create_dir_all(test_dir).expect("Failed to create test dir");
110+
test_fuse_filesystem(test_dir);
111+
test_big_file(test_dir);
112+
test_open_file_flag(test_dir);
108113
}
109114

110115
#[test]
111116
fn fuse_it_test_fuse() {
112117
test_enable_with!(RUN_TEST_WITH_FUSE);
118+
let mount_point = Path::new("target/gvfs");
119+
let test_dir = mount_point.join("test_dir");
113120

114-
test_fuse_filesystem("target/gvfs/gvfs_test");
121+
run_tests(&test_dir);
115122
}
116123

117-
fn test_fuse_filesystem(mount_point: &str) {
124+
fn test_fuse_filesystem(test_path: &Path) {
118125
info!("Test startup");
119-
let base_path = Path::new(mount_point);
120-
121-
if !file_exists(base_path) {
122-
fs::create_dir_all(base_path).expect("Failed to create test dir");
123-
}
124-
125126
//test create file
126-
let test_file = base_path.join("test_create");
127+
let test_file = test_path.join("test_create");
127128
let file = File::create(&test_file).expect("Failed to create file");
128129
assert!(file.metadata().is_ok(), "Failed to get file metadata");
129130
assert!(file_exists(&test_file));
@@ -140,16 +141,16 @@ fn test_fuse_filesystem(mount_point: &str) {
140141
assert!(!file_exists(&test_file));
141142

142143
//test create directory
143-
let test_dir = base_path.join("test_dir");
144+
let test_dir = test_path.join("test_dir");
144145
fs::create_dir(&test_dir).expect("Failed to create directory");
145146

146147
//test create file in directory
147-
let test_file = base_path.join("test_dir/test_file");
148+
let test_file = test_path.join("test_dir/test_file");
148149
let file = File::create(&test_file).expect("Failed to create file");
149150
assert!(file.metadata().is_ok(), "Failed to get file metadata");
150151

151152
//test write file in directory
152-
let test_file = base_path.join("test_dir/test_read");
153+
let test_file = test_path.join("test_dir/test_read");
153154
fs::write(&test_file, "read test").expect("Failed to write file");
154155

155156
//test read file in directory
@@ -167,6 +168,121 @@ fn test_fuse_filesystem(mount_point: &str) {
167168
info!("Success test");
168169
}
169170

171+
#[allow(clippy::needless_range_loop)]
172+
fn test_big_file(test_dir: &Path) {
173+
if !file_exists(test_dir) {
174+
fs::create_dir_all(test_dir).expect("Failed to create test dir");
175+
}
176+
177+
let test_file = test_dir.join("test_big_file");
178+
let mut file = File::create(&test_file).expect("Failed to create file");
179+
assert!(file.metadata().is_ok(), "Failed to get file metadata");
180+
assert!(file_exists(&test_file));
181+
182+
let round_size: usize = 1024 * 1024;
183+
let round: u8 = 10;
184+
185+
for i in 0..round {
186+
let mut content = vec![0; round_size];
187+
for j in 0..round_size {
188+
content[j] = (i as usize + j) as u8;
189+
}
190+
191+
file.write_all(&content).expect("Failed to write file");
192+
}
193+
file.flush().expect("Failed to flush file");
194+
195+
file = File::open(&test_file).expect("Failed to open file");
196+
for i in 0..round {
197+
let mut buffer = vec![0; round_size];
198+
file.read_exact(&mut buffer).unwrap();
199+
200+
for j in 0..round_size {
201+
assert_eq!(buffer[j], (i as usize + j) as u8, "File content mismatch");
202+
}
203+
}
204+
205+
fs::remove_file(&test_file).expect("Failed to delete file");
206+
assert!(!file_exists(&test_file));
207+
}
208+
209+
fn test_open_file_flag(test_dir: &Path) {
210+
// test open file with read and write create flag
211+
let file_path = test_dir.join("test_open_file");
212+
let mut file = OpenOptions::new()
213+
.write(true)
214+
.read(true)
215+
.create(true)
216+
.open(&file_path)
217+
.expect("Failed to open file");
218+
// test file offset is 0
219+
let offset = file.stream_position().expect("Failed to seek file");
220+
assert_eq!(offset, 0, "File offset mismatch");
221+
222+
// test write can be done
223+
let write_content = "write content";
224+
file.write_all(write_content.as_bytes())
225+
.expect("Failed to write file");
226+
let mut content = vec![0; write_content.len()];
227+
228+
// test read can be done
229+
file.seek(SeekFrom::Start(0)).expect("Failed to seek file");
230+
file.read_exact(&mut content).expect("Failed to read file");
231+
assert_eq!(content, write_content.as_bytes(), "File content mismatch");
232+
233+
// test open file with read flag
234+
let mut file = OpenOptions::new()
235+
.read(true)
236+
.open(&file_path)
237+
.expect("Failed to open file");
238+
// test reaad can be done
239+
let mut content = vec![0; write_content.len()];
240+
file.read_exact(&mut content).expect("Failed to read file");
241+
assert_eq!(content, write_content.as_bytes(), "File content mismatch");
242+
243+
// test write can be have error
244+
let result = file.write_all(write_content.as_bytes());
245+
if let Err(e) = result {
246+
assert_eq!(e.to_string(), "Bad file descriptor (os error 9)");
247+
}
248+
249+
// test open file with truncate file
250+
// test file size is not 0
251+
let old_file_size = file.metadata().expect("Failed to get file metadata").len();
252+
assert_eq!(old_file_size, write_content.len() as u64);
253+
254+
let mut file = OpenOptions::new()
255+
.write(true)
256+
.truncate(true)
257+
.open(&file_path)
258+
.expect("Failed to open file");
259+
// validate file size is 0
260+
let file_size = file.metadata().expect("Failed to get file metadata").len();
261+
assert_eq!(file_size, 0, "File size mismatch");
262+
// validate file offset is 0
263+
let offset = file.stream_position().expect("Failed to seek file");
264+
assert_eq!(offset, 0, "File offset mismatch");
265+
266+
file.write_all(write_content.as_bytes())
267+
.expect("Failed to write file");
268+
269+
// test open file with append flag
270+
let mut file = OpenOptions::new()
271+
.append(true)
272+
.open(&file_path)
273+
.expect("Failed to open file");
274+
// test append
275+
file.write_all(write_content.as_bytes())
276+
.expect("Failed to write file");
277+
let file_len = file.metadata().expect("Failed to get file metadata").len();
278+
// validate file size is 2 * write_content.len()
279+
assert_eq!(
280+
file_len,
281+
2 * write_content.len() as u64,
282+
"File size mismatch"
283+
);
284+
}
285+
170286
fn file_exists<P: AsRef<Path>>(path: P) -> bool {
171287
fs::metadata(path).is_ok()
172288
}

0 commit comments

Comments
 (0)