Skip to main content

libfuse_fs/
lib.rs

1// #[macro_use]
2// extern crate log;
3
4pub mod context;
5pub mod overlayfs;
6pub mod passthrough;
7mod server;
8pub mod unionfs;
9pub mod util;
10
11// Test utilities (only compiled during tests)
12#[cfg(test)]
13pub mod test_utils {
14    pub fn privileged_tests_enabled() -> bool {
15        std::env::var("RUN_PRIVILEGED_TESTS").ok().as_deref() == Some("1")
16    }
17
18    pub fn macfuse_tests_enabled() -> bool {
19        std::env::var("RUN_MACFUSE_TESTS").ok().as_deref() == Some("1")
20    }
21
22    pub fn is_skippable_mount_error(err: &std::io::Error) -> bool {
23        matches!(
24            err.raw_os_error(),
25            Some(libc::EPERM)
26                | Some(libc::EACCES)
27                | Some(libc::ENXIO)
28                | Some(libc::ENODEV)
29                | Some(libc::ENOTCONN)
30        ) || matches!(
31            err.kind(),
32            std::io::ErrorKind::PermissionDenied
33                | std::io::ErrorKind::NotFound
34                | std::io::ErrorKind::TimedOut
35        )
36    }
37
38    /// Macro: unwrap result or skip test when encountering EPERM (Permission denied).
39    ///
40    /// Behavior:
41    /// - On Ok(v): returns v
42    /// - On Err(e) where e -> io::Error has raw_os_error()==EPERM (or PermissionDenied):
43    ///     * If env RUN_PRIVILEGED_TESTS=1 -> panic (treat as hard failure)
44    ///     * Else: print a line indicating skip and `return` from test (so test counted as ignored when used with #[ignore]).
45    /// - On Err(e) other than EPERM -> panic with diagnostic.
46    ///
47    /// Usage examples:
48    /// let handle = unwrap_or_skip_eperm!(some_async_call.await, "mount session");
49    #[macro_export]
50    macro_rules! unwrap_or_skip_eperm {
51        ($expr:expr, $ctx:expr) => {{
52            match $expr {
53                Ok(v) => v,
54                Err(e) => {
55                    let ioerr: std::io::Error = e.into();
56                    let is_eperm = ioerr.raw_os_error() == Some(libc::EPERM)
57                        || ioerr.kind() == std::io::ErrorKind::PermissionDenied;
58                    if is_eperm {
59                        if $crate::test_utils::privileged_tests_enabled() {
60                            panic!(
61                                "{} failed with EPERM while RUN_PRIVILEGED_TESTS=1: {:?}",
62                                $ctx, ioerr
63                            );
64                        } else {
65                            eprintln!("skip (EPERM) {}: {:?}", $ctx, ioerr);
66                            return;
67                        }
68                    }
69                    panic!("{} unexpected error: {:?}", $ctx, ioerr);
70                }
71            }
72        }};
73    }
74
75    #[macro_export]
76    macro_rules! unwrap_or_skip_mount_error {
77        ($expr:expr, $ctx:expr) => {{
78            match $expr {
79                Ok(v) => v,
80                Err(e) => {
81                    let ioerr: std::io::Error = e.into();
82                    if $crate::test_utils::is_skippable_mount_error(&ioerr) {
83                        if $crate::test_utils::macfuse_tests_enabled() {
84                            panic!("{} failed while RUN_MACFUSE_TESTS=1: {:?}", $ctx, ioerr);
85                        } else {
86                            eprintln!("skip (mount environment) {}: {:?}", $ctx, ioerr);
87                            return;
88                        }
89                    }
90                    panic!("{} unexpected error: {:?}", $ctx, ioerr);
91                }
92            }
93        }};
94    }
95}