• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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