1use cfg_if::cfg_if;
2
3#[macro_export]
4macro_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
15cfg_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]
38macro_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]
56macro_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]
66macro_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]
79macro_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
89cfg_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
113cfg_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