Skip to content

Commit f8bc31c

Browse files
jiangliubergwolf
authored andcommitted
ptfs: add unit tests for mount fd
Add unit tests for mount fd. Signed-off-by: Jiang Liu <[email protected]>
1 parent fb73858 commit f8bc31c

File tree

3 files changed

+127
-9
lines changed

3 files changed

+127
-9
lines changed

src/passthrough/file_handle.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Copyright (C) 2023 Alibaba Cloud. All rights reserved.
12
// Copyright 2021 Red Hat, Inc. All rights reserved.
23
// Use of this source code is governed by a BSD-style license that can be
34
// found in the LICENSE-BSD-3-Clause file.
@@ -281,10 +282,7 @@ impl OpenableFileHandle {
281282
})
282283
}
283284

284-
/// Open a file handle (low-level wrapper).
285-
///
286-
/// `mount_fd` must be an open non-`O_PATH` file descriptor for an inode on the same mount as
287-
/// the file to be opened, i.e. the mount given by `self.mnt_id`.
285+
/// Open a file from an openable file handle.
288286
pub fn open(&self, flags: libc::c_int) -> io::Result<File> {
289287
let ret = unsafe {
290288
open_by_handle_at(
@@ -316,6 +314,8 @@ impl OpenableFileHandle {
316314
#[cfg(test)]
317315
mod tests {
318316
use super::*;
317+
use std::ffi::CString;
318+
use std::io::Read;
319319

320320
fn generate_c_file_handle(
321321
handle_bytes: usize,
@@ -367,12 +367,12 @@ mod tests {
367367
};
368368

369369
assert!(fh1 > fh2);
370-
assert!(fh1 != fh2);
370+
assert_ne!(fh1, fh2);
371371
assert!(fh1 < fh3);
372-
assert!(fh1 != fh3);
372+
assert_ne!(fh1, fh3);
373373
assert!(fh1 < fh4);
374-
assert!(fh1 != fh4);
375-
assert!(fh1 == fh5);
374+
assert_ne!(fh1, fh4);
375+
assert_eq!(fh1, fh5);
376376

377377
unsafe {
378378
fh1.handle
@@ -389,7 +389,7 @@ mod tests {
389389
.f_handle
390390
.as_mut_slice(128)[0] = 1;
391391
}
392-
assert!(fh1 == fh5);
392+
assert_eq!(fh1, fh5);
393393
}
394394

395395
#[test]
@@ -405,4 +405,47 @@ mod tests {
405405
buf.as_slice(),
406406
);
407407
}
408+
409+
#[test]
410+
fn test_file_handle_from_name_at() {
411+
let topdir = env!("CARGO_MANIFEST_DIR");
412+
let dir = File::open(topdir).unwrap();
413+
let filename = CString::new("build.rs").unwrap();
414+
415+
let dir_handle =
416+
FileHandle::from_name_at(dir.as_raw_fd(), &CString::new("").unwrap()).unwrap();
417+
let file_handle = FileHandle::from_name_at(dir.as_raw_fd(), &filename).unwrap();
418+
419+
assert_eq!(dir_handle.mnt_id, file_handle.mnt_id);
420+
assert_ne!(
421+
dir_handle.handle.wrapper.as_fam_struct_ref().handle_bytes,
422+
0
423+
);
424+
assert_ne!(
425+
file_handle.handle.wrapper.as_fam_struct_ref().handle_bytes,
426+
0
427+
);
428+
}
429+
430+
#[test]
431+
fn test_openable_file_handle() {
432+
let topdir = env!("CARGO_MANIFEST_DIR");
433+
let dir = File::open(topdir).unwrap();
434+
let filename = CString::new("build.rs").unwrap();
435+
let mount_fds = MountFds::new(None).unwrap();
436+
437+
let file_handle = OpenableFileHandle::from_name_at(
438+
dir.as_raw_fd(),
439+
&filename,
440+
&mount_fds,
441+
|_fd, _flags, _mode| File::open(topdir),
442+
)
443+
.unwrap();
444+
assert_eq!(file_handle.handle.mnt_id, file_handle.mount_id());
445+
446+
let mut file = file_handle.open(libc::O_RDONLY).unwrap();
447+
let mut buffer = [0u8; 1024];
448+
let res = file.read(&mut buffer).unwrap();
449+
assert!(res > 0);
450+
}
408451
}

src/passthrough/mount_fd.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,57 @@ impl std::fmt::Display for MPRError {
436436
}
437437

438438
impl std::error::Error for MPRError {}
439+
440+
#[cfg(test)]
441+
mod tests {
442+
use super::*;
443+
use crate::passthrough::file_handle::FileHandle;
444+
445+
#[test]
446+
fn test_mount_fd_get() {
447+
let topdir = env!("CARGO_MANIFEST_DIR");
448+
let dir = File::open(topdir).unwrap();
449+
let filename = CString::new("build.rs").unwrap();
450+
let mount_fds = MountFds::new(None).unwrap();
451+
let handle = FileHandle::from_name_at(dir.as_raw_fd(), &filename).unwrap();
452+
453+
// Ensure that `MountFds::get()` works for new entry.
454+
let fd1 = mount_fds
455+
.get(handle.mnt_id, |_fd, _flags, _mode| File::open(topdir))
456+
.unwrap();
457+
assert_eq!(Arc::strong_count(&fd1), 1);
458+
assert_eq!(mount_fds.map.read().unwrap().len(), 1);
459+
460+
// Ensure that `MountFds::get()` works for existing entry.
461+
let fd2 = mount_fds
462+
.get(handle.mnt_id, |_fd, _flags, _mode| File::open(topdir))
463+
.unwrap();
464+
assert_eq!(Arc::strong_count(&fd2), 2);
465+
assert_eq!(mount_fds.map.read().unwrap().len(), 1);
466+
467+
// Ensure fd1 and fd2 are the same object.
468+
assert_eq!(fd1.file().as_raw_fd(), fd2.file().as_raw_fd());
469+
470+
drop(fd1);
471+
assert_eq!(Arc::strong_count(&fd2), 1);
472+
assert_eq!(mount_fds.map.read().unwrap().len(), 1);
473+
474+
// Ensure that `MountFd::drop()` works as expected.
475+
drop(fd2);
476+
assert_eq!(mount_fds.map.read().unwrap().len(), 0);
477+
}
478+
479+
#[test]
480+
fn test_mpr_error() {
481+
let io_error = io::Error::new(io::ErrorKind::Other, "test");
482+
let mpr_error = MPRError::from(io_error);
483+
484+
assert!(!mpr_error.silent);
485+
assert!(mpr_error.fs_mount_id.is_none());
486+
assert!(mpr_error.fs_mount_root.is_none());
487+
let mpr_error = mpr_error.silence();
488+
let msg = format!("{}", mpr_error);
489+
assert!(msg.len() > 0);
490+
assert!(mpr_error.silent());
491+
}
492+
}

src/passthrough/statx.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,24 @@ pub fn statx(dir: &impl AsRawFd, path: Option<&CStr>) -> io::Result<StatExt> {
193193
Err(io::Error::last_os_error())
194194
}
195195
}
196+
197+
#[cfg(test)]
198+
mod tests {
199+
use super::*;
200+
use std::ffi::CString;
201+
use std::fs::File;
202+
203+
#[test]
204+
fn test_statx() {
205+
let topdir = env!("CARGO_MANIFEST_DIR");
206+
let dir = File::open(topdir).unwrap();
207+
let filename = CString::new("build.rs").unwrap();
208+
209+
let st1 = statx(&dir, None).unwrap();
210+
let st2 = statx(&dir, Some(&filename)).unwrap();
211+
let mnt_id = get_mount_id(&dir, &filename).unwrap();
212+
213+
assert_eq!(st1.mnt_id, st2.mnt_id);
214+
assert_eq!(st1.mnt_id, mnt_id);
215+
}
216+
}

0 commit comments

Comments
 (0)