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 | |