1 use cfg_if::cfg_if; 2 3 #[macro_export] 4 macro_rules! skip { 5 ($($reason: expr),+) => { 6 use ::std::io::{self, Write}; 7 8 let stderr = io::stderr(); 9 let mut handle = stderr.lock(); 10 writeln!(handle, $($reason),+).unwrap(); 11 return; 12 } 13 } 14 15 cfg_if! { 16 if #[cfg(any(target_os = "android", target_os = "linux"))] { 17 #[macro_export] macro_rules! require_capability { 18 ($name:expr, $capname:ident) => { 19 use ::caps::{Capability, CapSet, has_cap}; 20 21 if !has_cap(None, CapSet::Effective, Capability::$capname) 22 .unwrap() 23 { 24 skip!("{} requires capability {}. Skipping test.", $name, Capability::$capname); 25 } 26 } 27 } 28 } else if #[cfg(not(target_os = "redox"))] { 29 #[macro_export] macro_rules! require_capability { 30 ($name:expr, $capname:ident) => {} 31 } 32 } 33 } 34 35 /// Skip the test if we don't have the ability to mount file systems. 36 #[cfg(target_os = "freebsd")] 37 #[macro_export] 38 macro_rules! require_mount { 39 ($name:expr) => { 40 use ::sysctl::{CtlValue, Sysctl}; 41 use nix::unistd::Uid; 42 43 let ctl = ::sysctl::Ctl::new("vfs.usermount").unwrap(); 44 if !Uid::current().is_root() && CtlValue::Int(0) == ctl.value().unwrap() 45 { 46 skip!( 47 "{} requires the ability to mount file systems. Skipping test.", 48 $name 49 ); 50 } 51 }; 52 } 53 54 #[cfg(any(target_os = "linux", target_os = "android"))] 55 #[macro_export] 56 macro_rules! skip_if_cirrus { 57 ($reason:expr) => { 58 if std::env::var_os("CIRRUS_CI").is_some() { 59 skip!("{}", $reason); 60 } 61 }; 62 } 63 64 #[cfg(target_os = "freebsd")] 65 #[macro_export] 66 macro_rules! skip_if_jailed { 67 ($name:expr) => { 68 use ::sysctl::{CtlValue, Sysctl}; 69 70 let ctl = ::sysctl::Ctl::new("security.jail.jailed").unwrap(); 71 if let CtlValue::Int(1) = ctl.value().unwrap() { 72 skip!("{} cannot run in a jail. Skipping test.", $name); 73 } 74 }; 75 } 76 77 #[cfg(not(any(target_os = "redox", target_os = "fuchsia")))] 78 #[macro_export] 79 macro_rules! skip_if_not_root { 80 ($name:expr) => { 81 use nix::unistd::Uid; 82 83 if !Uid::current().is_root() { 84 skip!("{} requires root privileges. Skipping test.", $name); 85 } 86 }; 87 } 88 89 cfg_if! { 90 if #[cfg(any(target_os = "android", target_os = "linux"))] { 91 #[macro_export] macro_rules! skip_if_seccomp { 92 ($name:expr) => { 93 if let Ok(s) = std::fs::read_to_string("/proc/self/status") { 94 for l in s.lines() { 95 let mut fields = l.split_whitespace(); 96 if fields.next() == Some("Seccomp:") && 97 fields.next() != Some("0") 98 { 99 skip!("{} cannot be run in Seccomp mode. Skipping test.", 100 stringify!($name)); 101 } 102 } 103 } 104 } 105 } 106 } else if #[cfg(not(target_os = "redox"))] { 107 #[macro_export] macro_rules! skip_if_seccomp { 108 ($name:expr) => {} 109 } 110 } 111 } 112 113 cfg_if! { 114 if #[cfg(target_os = "linux")] { 115 #[macro_export] macro_rules! require_kernel_version { 116 ($name:expr, $version_requirement:expr) => { 117 use semver::{Version, VersionReq}; 118 119 let version_requirement = VersionReq::parse($version_requirement) 120 .expect("Bad match_version provided"); 121 122 let uname = nix::sys::utsname::uname().unwrap(); 123 println!("{}", uname.sysname().to_str().unwrap()); 124 println!("{}", uname.nodename().to_str().unwrap()); 125 println!("{}", uname.release().to_str().unwrap()); 126 println!("{}", uname.version().to_str().unwrap()); 127 println!("{}", uname.machine().to_str().unwrap()); 128 129 // Fix stuff that the semver parser can't handle 130 let fixed_release = &uname.release().to_str().unwrap().to_string() 131 // Fedora 33 reports version as 4.18.el8_2.x86_64 or 132 // 5.18.200-fc33.x86_64. Remove the underscore. 133 .replace("_", "-") 134 // Cirrus-CI reports version as 4.19.112+ . Remove the + 135 .replace("+", ""); 136 let mut version = Version::parse(fixed_release).unwrap(); 137 138 //Keep only numeric parts 139 version.pre = semver::Prerelease::EMPTY; 140 version.build = semver::BuildMetadata::EMPTY; 141 142 if !version_requirement.matches(&version) { 143 skip!("Skip {} because kernel version `{}` doesn't match the requirement `{}`", 144 stringify!($name), version, version_requirement); 145 } 146 } 147 } 148 } 149 } 150