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