summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/sysinfo/tests
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/sysinfo/tests')
-rw-r--r--vendor/sysinfo/tests/code_checkers/docs.rs135
-rw-r--r--vendor/sysinfo/tests/code_checkers/headers.rs59
-rw-r--r--vendor/sysinfo/tests/code_checkers/mod.rs49
-rw-r--r--vendor/sysinfo/tests/code_checkers/signals.rs64
-rw-r--r--vendor/sysinfo/tests/code_checkers/utils.rs49
-rw-r--r--vendor/sysinfo/tests/cpu.rs32
-rw-r--r--vendor/sysinfo/tests/disk_list.rs14
-rw-r--r--vendor/sysinfo/tests/extras.rs3
-rw-r--r--vendor/sysinfo/tests/network.rs15
-rw-r--r--vendor/sysinfo/tests/process.rs381
-rw-r--r--vendor/sysinfo/tests/send_sync.rs10
-rw-r--r--vendor/sysinfo/tests/uptime.rs12
12 files changed, 823 insertions, 0 deletions
diff --git a/vendor/sysinfo/tests/code_checkers/docs.rs b/vendor/sysinfo/tests/code_checkers/docs.rs
new file mode 100644
index 000000000..918e64bb0
--- /dev/null
+++ b/vendor/sysinfo/tests/code_checkers/docs.rs
@@ -0,0 +1,135 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use super::utils::{show_error, TestResult};
+use std::ffi::OsStr;
+use std::path::Path;
+
+fn to_correct_name(s: &str) -> String {
+ let mut out = String::with_capacity(s.len());
+
+ for c in s.chars() {
+ if c.is_uppercase() {
+ if !out.is_empty() {
+ out.push('_');
+ }
+ out.push_str(c.to_lowercase().to_string().as_str());
+ } else {
+ out.push(c);
+ }
+ }
+ out
+}
+
+fn check_md_doc_path(p: &Path, md_line: &str, ty_line: &str) -> bool {
+ let parts = md_line.split("/").collect::<Vec<_>>();
+ if let Some(md_name) = parts.last().and_then(|n| n.split(".md").next()) {
+ if let Some(name) = ty_line
+ .split_whitespace()
+ .filter(|s| !s.is_empty())
+ .skip(2)
+ .next()
+ {
+ if let Some(name) = name
+ .split('<')
+ .next()
+ .and_then(|n| n.split('{').next())
+ .and_then(|n| n.split('(').next())
+ .and_then(|n| n.split(';').next())
+ {
+ let correct = to_correct_name(name);
+ if correct.as_str() == md_name {
+ return true;
+ }
+ show_error(
+ p,
+ &format!(
+ "Invalid markdown file name `{}`, should have been `{}`",
+ md_name, correct
+ ),
+ );
+ return false;
+ }
+ }
+ show_error(p, &format!("Cannot extract type name from `{}`", ty_line));
+ } else {
+ show_error(p, &format!("Cannot extract md name from `{}`", md_line));
+ }
+ return false;
+}
+
+fn check_doc_comments_before(p: &Path, lines: &[&str], start: usize) -> bool {
+ let mut found_docs = false;
+
+ for pos in (0..start).rev() {
+ let trimmed = lines[pos].trim();
+ if trimmed.starts_with("///") {
+ if !lines[start].trim().starts_with("pub enum ThreadStatus {") {
+ show_error(
+ p,
+ &format!(
+ "Types should use common documentation by using `#[doc = include_str!(` \
+ and by putting the markdown file in the `md_doc` folder instead of `{}`",
+ &lines[pos],
+ ),
+ );
+ return false;
+ }
+ return true;
+ } else if trimmed.starts_with("#[doc = include_str!(") {
+ found_docs = true;
+ if !check_md_doc_path(p, trimmed, lines[start]) {
+ return false;
+ }
+ } else if !trimmed.starts_with("#[") && !trimmed.starts_with("//") {
+ break;
+ }
+ }
+ if !found_docs {
+ show_error(
+ p,
+ &format!(
+ "Missing documentation for public item: `{}` (if it's not supposed to be a public \
+ item, use `pub(crate)` instead)",
+ lines[start],
+ ),
+ );
+ return false;
+ }
+ true
+}
+
+pub fn check_docs(content: &str, p: &Path) -> TestResult {
+ let mut res = TestResult {
+ nb_tests: 0,
+ nb_errors: 0,
+ };
+
+ // No need to check if we are in the `src` folder or if we are in a `ffi.rs` file.
+ if p.parent().unwrap().file_name().unwrap() == OsStr::new("src")
+ || p.file_name().unwrap() == OsStr::new("ffi.rs")
+ {
+ return res;
+ }
+ let lines = content.lines().collect::<Vec<_>>();
+
+ for pos in 1..lines.len() {
+ let line = lines[pos];
+ let trimmed = line.trim();
+ if trimmed.starts_with("//!") {
+ show_error(p, "There shouln't be inner doc comments (`//!`)");
+ res.nb_tests += 1;
+ res.nb_errors += 1;
+ continue;
+ } else if !line.starts_with("pub fn ")
+ && !trimmed.starts_with("pub struct ")
+ && !trimmed.starts_with("pub enum ")
+ {
+ continue;
+ }
+ res.nb_tests += 1;
+ if !check_doc_comments_before(p, &lines, pos) {
+ res.nb_errors += 1;
+ }
+ }
+ res
+}
diff --git a/vendor/sysinfo/tests/code_checkers/headers.rs b/vendor/sysinfo/tests/code_checkers/headers.rs
new file mode 100644
index 000000000..ac7a34ddb
--- /dev/null
+++ b/vendor/sysinfo/tests/code_checkers/headers.rs
@@ -0,0 +1,59 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use super::utils::{show_error, TestResult};
+use std::path::Path;
+
+pub fn check_license_header(content: &str, p: &Path) -> TestResult {
+ let mut lines = content.lines();
+ let next = lines.next();
+ let header = "// Take a look at the license at the top of the repository in the LICENSE file.";
+
+ match next {
+ Some(s) if s == header => {
+ let next = lines.next();
+ match next {
+ Some("") => TestResult {
+ nb_tests: 1,
+ nb_errors: 0,
+ },
+ Some(s) => {
+ show_error(
+ p,
+ &format!("Expected empty line after license header, found `{}`", s),
+ );
+ TestResult {
+ nb_tests: 1,
+ nb_errors: 1,
+ }
+ }
+ None => {
+ show_error(p, "This file should very likely not exist...");
+ TestResult {
+ nb_tests: 1,
+ nb_errors: 1,
+ }
+ }
+ }
+ }
+ Some(s) => {
+ show_error(
+ p,
+ &format!(
+ "Expected license header at the top of the file (`{}`), found: `{}`",
+ header, s
+ ),
+ );
+ TestResult {
+ nb_tests: 1,
+ nb_errors: 1,
+ }
+ }
+ None => {
+ show_error(p, "This (empty?) file should very likely not exist...");
+ TestResult {
+ nb_tests: 1,
+ nb_errors: 1,
+ }
+ }
+ }
+}
diff --git a/vendor/sysinfo/tests/code_checkers/mod.rs b/vendor/sysinfo/tests/code_checkers/mod.rs
new file mode 100644
index 000000000..f6012da95
--- /dev/null
+++ b/vendor/sysinfo/tests/code_checkers/mod.rs
@@ -0,0 +1,49 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+mod docs;
+mod headers;
+mod signals;
+mod utils;
+
+use std::path::Path;
+use utils::TestResult;
+
+const CHECKS: &[(fn(&str, &Path) -> TestResult, &[&str])] = &[
+ (headers::check_license_header, &["src", "tests", "examples"]),
+ (signals::check_signals, &["src"]),
+ (docs::check_docs, &["src"]),
+];
+
+fn handle_tests(res: &mut [TestResult]) {
+ utils::read_dirs(
+ &["benches", "examples", "src", "tests"],
+ &mut |p: &Path, c: &str| {
+ if let Some(first) = p.iter().next().and_then(|first| first.to_str()) {
+ for (pos, (check, filter)) in CHECKS.iter().enumerate() {
+ if filter.contains(&first) {
+ res[pos] += check(c, p);
+ }
+ }
+ }
+ },
+ );
+}
+
+#[test]
+fn code_checks() {
+ let mut res = Vec::new();
+
+ for _ in CHECKS {
+ res.push(TestResult {
+ nb_tests: 0,
+ nb_errors: 0,
+ });
+ }
+
+ handle_tests(&mut res);
+
+ for r in res {
+ assert_eq!(r.nb_errors, 0);
+ assert_ne!(r.nb_tests, 0);
+ }
+}
diff --git a/vendor/sysinfo/tests/code_checkers/signals.rs b/vendor/sysinfo/tests/code_checkers/signals.rs
new file mode 100644
index 000000000..68e47f76e
--- /dev/null
+++ b/vendor/sysinfo/tests/code_checkers/signals.rs
@@ -0,0 +1,64 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use super::utils::{show_error, TestResult};
+use std::path::Path;
+
+fn check_supported_signals_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p: &Path) -> usize {
+ for line in lines {
+ let trimmed = line.trim();
+ if trimmed.starts_with("const SUPPORTED_SIGNALS: &'static [Signal]") {
+ if trimmed != "const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();" {
+ show_error(
+ p,
+ "SystemExt::SUPPORTED_SIGNALS should be declared using `supported_signals()`",
+ );
+ return 1;
+ }
+ break;
+ }
+ }
+ 0
+}
+
+fn check_kill_decl<'a>(lines: &mut impl Iterator<Item = &'a str>, p: &Path) -> usize {
+ let mut errors = 0;
+
+ while let Some(line) = lines.next() {
+ let trimmed = line.trim();
+ if trimmed.starts_with("fn kill(") {
+ show_error(p, "`ProcessExt::kill` should not be reimplemented!");
+ errors += 1;
+ } else if trimmed.starts_with("fn kill_with(") {
+ if let Some(line) = lines.next() {
+ let trimmed = line.trim();
+ if trimmed.ends_with("::system::convert_signal(signal)?;") || trimmed == "None" {
+ continue;
+ } else {
+ show_error(p, "`ProcessExt::kill_with` should use `convert_signal`");
+ errors += 1;
+ }
+ }
+ }
+ }
+ errors
+}
+
+pub fn check_signals(content: &str, p: &Path) -> TestResult {
+ let mut lines = content.lines();
+ let mut res = TestResult {
+ nb_tests: 0,
+ nb_errors: 0,
+ };
+
+ while let Some(line) = lines.next() {
+ let trimmed = line.trim();
+ if trimmed.starts_with("impl SystemExt for System {") {
+ res.nb_tests += 1;
+ res.nb_errors += check_supported_signals_decl(&mut lines, p);
+ } else if trimmed.starts_with("impl ProcessExt for Process {") {
+ res.nb_tests += 1;
+ res.nb_errors += check_kill_decl(&mut lines, p);
+ }
+ }
+ res
+}
diff --git a/vendor/sysinfo/tests/code_checkers/utils.rs b/vendor/sysinfo/tests/code_checkers/utils.rs
new file mode 100644
index 000000000..dadbc0a54
--- /dev/null
+++ b/vendor/sysinfo/tests/code_checkers/utils.rs
@@ -0,0 +1,49 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use std::fs::{self, File};
+use std::io::Read;
+use std::path::Path;
+
+pub struct TestResult {
+ pub nb_tests: usize,
+ pub nb_errors: usize,
+}
+
+impl std::ops::AddAssign for TestResult {
+ fn add_assign(&mut self, other: Self) {
+ self.nb_tests += other.nb_tests;
+ self.nb_errors += other.nb_errors;
+ }
+}
+
+pub fn read_dirs<P: AsRef<Path>, F: FnMut(&Path, &str)>(dirs: &[P], callback: &mut F) {
+ for dir in dirs {
+ read_dir(dir, callback);
+ }
+}
+
+fn read_dir<P: AsRef<Path>, F: FnMut(&Path, &str)>(dir: P, callback: &mut F) {
+ for entry in fs::read_dir(dir).expect("read_dir failed") {
+ let entry = entry.expect("entry failed");
+ let path = entry.path();
+ if path.is_dir() {
+ read_dir(path, callback);
+ } else {
+ let content = read_file(&path);
+ callback(&path, &content);
+ }
+ }
+}
+
+fn read_file<P: AsRef<Path>>(p: P) -> String {
+ let mut f = File::open(p).expect("read_file::open failed");
+ let mut content =
+ String::with_capacity(f.metadata().map(|m| m.len() as usize + 1).unwrap_or(0));
+ f.read_to_string(&mut content)
+ .expect("read_file::read_to_end failed");
+ content
+}
+
+pub fn show_error(p: &Path, err: &str) {
+ eprintln!("=> [{}]: {}", p.display(), err);
+}
diff --git a/vendor/sysinfo/tests/cpu.rs b/vendor/sysinfo/tests/cpu.rs
new file mode 100644
index 000000000..fbeb65b81
--- /dev/null
+++ b/vendor/sysinfo/tests/cpu.rs
@@ -0,0 +1,32 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+// This test is used to ensure that the CPUs are not loaded by default.
+
+#[test]
+fn test_cpu() {
+ use sysinfo::{CpuExt, SystemExt};
+
+ if sysinfo::System::IS_SUPPORTED {
+ let mut s = sysinfo::System::new();
+ assert!(s.cpus().is_empty());
+ s.refresh_cpu();
+ assert!(!s.cpus().is_empty());
+
+ let s = sysinfo::System::new_all();
+ assert!(!s.cpus().is_empty());
+
+ assert!(!s.cpus()[0].brand().chars().any(|c| c == '\0'));
+ }
+}
+
+#[test]
+fn test_physical_core_numbers() {
+ use sysinfo::SystemExt;
+
+ if sysinfo::System::IS_SUPPORTED {
+ let s = sysinfo::System::new();
+ let count = s.physical_core_count();
+ assert_ne!(count, None);
+ assert!(count.unwrap() > 0);
+ }
+}
diff --git a/vendor/sysinfo/tests/disk_list.rs b/vendor/sysinfo/tests/disk_list.rs
new file mode 100644
index 000000000..164d5b931
--- /dev/null
+++ b/vendor/sysinfo/tests/disk_list.rs
@@ -0,0 +1,14 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+#[test]
+fn test_disks() {
+ use sysinfo::SystemExt;
+
+ if sysinfo::System::IS_SUPPORTED {
+ let s = sysinfo::System::new_all();
+ // If we don't have any physical core present, it's very likely that we're inside a VM...
+ if s.physical_core_count().unwrap_or_default() > 0 {
+ assert!(!s.disks().is_empty());
+ }
+ }
+}
diff --git a/vendor/sysinfo/tests/extras.rs b/vendor/sysinfo/tests/extras.rs
new file mode 100644
index 000000000..140dd1131
--- /dev/null
+++ b/vendor/sysinfo/tests/extras.rs
@@ -0,0 +1,3 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+mod code_checkers;
diff --git a/vendor/sysinfo/tests/network.rs b/vendor/sysinfo/tests/network.rs
new file mode 100644
index 000000000..6925cb3c8
--- /dev/null
+++ b/vendor/sysinfo/tests/network.rs
@@ -0,0 +1,15 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+// This test is used to ensure that the networks are not loaded by default.
+
+#[test]
+fn test_networks() {
+ use sysinfo::{NetworksExt, SystemExt};
+
+ if sysinfo::System::IS_SUPPORTED {
+ let s = sysinfo::System::new();
+ assert_eq!(s.networks().iter().count(), 0);
+ let s = sysinfo::System::new_all();
+ assert!(s.networks().iter().count() > 0);
+ }
+}
diff --git a/vendor/sysinfo/tests/process.rs b/vendor/sysinfo/tests/process.rs
new file mode 100644
index 000000000..6745fc444
--- /dev/null
+++ b/vendor/sysinfo/tests/process.rs
@@ -0,0 +1,381 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+use sysinfo::{Pid, PidExt, ProcessExt, SystemExt};
+
+#[test]
+fn test_process() {
+ let mut s = sysinfo::System::new();
+ assert_eq!(s.processes().len(), 0);
+ s.refresh_processes();
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ assert!(!s.processes().is_empty());
+ #[cfg(not(windows))]
+ assert!(s
+ .processes()
+ .values()
+ .any(|p| !p.exe().to_str().unwrap_or("").is_empty()));
+}
+
+#[test]
+fn test_cwd() {
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("3")
+ .arg("CwdSignal")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("3")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ };
+
+ let pid = Pid::from_u32(p.id() as u32);
+ std::thread::sleep(std::time::Duration::from_secs(1));
+ let mut s = sysinfo::System::new();
+ s.refresh_processes();
+ p.kill().expect("Unable to kill process.");
+
+ let processes = s.processes();
+ let p = processes.get(&pid);
+
+ if let Some(p) = p {
+ assert_eq!(p.pid(), pid);
+ assert_eq!(p.cwd(), std::env::current_dir().unwrap());
+ } else {
+ panic!("Process not found!");
+ }
+}
+
+#[test]
+fn test_cmd() {
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("3")
+ .arg("CmdSignal")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("3")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ };
+ std::thread::sleep(std::time::Duration::from_millis(500));
+ let mut s = sysinfo::System::new();
+ assert!(s.processes().is_empty());
+ s.refresh_processes();
+ p.kill().expect("Unable to kill process.");
+ assert!(!s.processes().is_empty());
+ if let Some(process) = s.process(Pid::from_u32(p.id() as u32)) {
+ if cfg!(target_os = "windows") {
+ // Sometimes, we get the full path instead for some reasons... So just in case,
+ // we check for the command independently that from the arguments.
+ assert!(process.cmd()[0].contains("waitfor"));
+ assert_eq!(&process.cmd()[1..], &["/t", "3", "CmdSignal"]);
+ } else {
+ assert_eq!(process.cmd(), &["sleep", "3"]);
+ }
+ } else {
+ panic!("Process not found!");
+ }
+}
+
+#[test]
+fn test_environ() {
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("3")
+ .arg("EnvironSignal")
+ .stdout(std::process::Stdio::null())
+ .env("FOO", "BAR")
+ .env("OTHER", "VALUE")
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("3")
+ .stdout(std::process::Stdio::null())
+ .env("FOO", "BAR")
+ .env("OTHER", "VALUE")
+ .spawn()
+ .unwrap()
+ };
+
+ let pid = Pid::from_u32(p.id() as u32);
+ std::thread::sleep(std::time::Duration::from_secs(1));
+ let mut s = sysinfo::System::new();
+ s.refresh_processes();
+ p.kill().expect("Unable to kill process.");
+
+ let processes = s.processes();
+ let p = processes.get(&pid);
+
+ if let Some(p) = p {
+ assert_eq!(p.pid(), pid);
+ // FIXME: instead of ignoring the test on CI, try to find out what's wrong...
+ if std::env::var("APPLE_CI").is_err() {
+ assert!(p.environ().iter().any(|e| e == "FOO=BAR"));
+ assert!(p.environ().iter().any(|e| e == "OTHER=VALUE"));
+ }
+ } else {
+ panic!("Process not found!");
+ }
+}
+
+#[test]
+fn test_process_refresh() {
+ let mut s = sysinfo::System::new();
+ assert_eq!(s.processes().len(), 0);
+
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ s.refresh_process(sysinfo::get_current_pid().expect("failed to get current pid"));
+ assert!(s
+ .process(sysinfo::get_current_pid().expect("failed to get current pid"))
+ .is_some(),);
+}
+
+#[test]
+fn test_process_disk_usage() {
+ use std::fs;
+ use std::fs::File;
+ use std::io::prelude::*;
+ use sysinfo::{get_current_pid, ProcessExt, SystemExt};
+
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ if std::env::var("FREEBSD_CI").is_ok() {
+ // For an unknown reason, when running this test on Cirrus CI, it fails. It works perfectly
+ // locally though... Dark magic...
+ return;
+ }
+
+ fn inner() -> sysinfo::System {
+ {
+ let mut file = File::create("test.txt").expect("failed to create file");
+ file.write_all(b"This is a test file\nwith test data.\n")
+ .expect("failed to write to file");
+ }
+ fs::remove_file("test.txt").expect("failed to remove file");
+ // Waiting a bit just in case...
+ std::thread::sleep(std::time::Duration::from_millis(250));
+ let mut system = sysinfo::System::new();
+ assert!(system.processes().is_empty());
+ system.refresh_processes();
+ assert!(!system.processes().is_empty());
+ system
+ }
+
+ let mut system = inner();
+ let mut p = system
+ .process(get_current_pid().expect("Failed retrieving current pid."))
+ .expect("failed to get process");
+
+ if cfg!(any(target_os = "macos", target_os = "ios")) && p.disk_usage().total_written_bytes == 0
+ {
+ // For whatever reason, sometimes, mac doesn't work on the first time when running
+ // `cargo test`. Two solutions, either run with "cargo test -- --test-threads 1", or
+ // check twice...
+ system = inner();
+ p = system
+ .process(get_current_pid().expect("Failed retrieving current pid."))
+ .expect("failed to get process");
+ }
+
+ assert!(
+ p.disk_usage().total_written_bytes > 0,
+ "found {} total written bytes...",
+ p.disk_usage().total_written_bytes
+ );
+ assert!(
+ p.disk_usage().written_bytes > 0,
+ "found {} written bytes...",
+ p.disk_usage().written_bytes
+ );
+}
+
+#[test]
+fn cpu_usage_is_not_nan() {
+ let mut system = sysinfo::System::new();
+ system.refresh_processes();
+
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+
+ let first_pids = system
+ .processes()
+ .iter()
+ .take(10)
+ .map(|(&pid, _)| pid)
+ .collect::<Vec<_>>();
+ let mut checked = 0;
+
+ first_pids.into_iter().for_each(|pid| {
+ system.refresh_process(pid);
+ if let Some(p) = system.process(pid) {
+ assert!(!p.cpu_usage().is_nan());
+ checked += 1;
+ }
+ });
+ assert!(checked > 0);
+}
+
+#[test]
+fn test_process_times() {
+ use std::time::{SystemTime, UNIX_EPOCH};
+
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("3")
+ .arg("ProcessTimes")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("3")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ };
+
+ let pid = Pid::from_u32(p.id() as u32);
+ std::thread::sleep(std::time::Duration::from_secs(1));
+ let mut s = sysinfo::System::new();
+ s.refresh_processes();
+ p.kill().expect("Unable to kill process.");
+
+ if let Some(p) = s.process(pid) {
+ assert_eq!(p.pid(), pid);
+ assert!(p.run_time() >= 1);
+ assert!(p.run_time() <= 2);
+ assert!(p.start_time() > p.run_time());
+ // On linux, for whatever reason, the uptime seems to be older than the boot time, leading
+ // to this weird `+ 3` to ensure the test is passing as it should...
+ assert!(
+ p.start_time() + 3
+ > SystemTime::now()
+ .duration_since(UNIX_EPOCH)
+ .unwrap()
+ .as_secs(),
+ );
+ assert!(p.start_time() >= s.boot_time());
+ } else {
+ panic!("Process not found!");
+ }
+}
+
+// Checks that `refresh_processes` is removing dead processes.
+#[test]
+fn test_refresh_processes() {
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("300")
+ .arg("RefreshProcesses")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("300")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ };
+
+ let pid = Pid::from_u32(p.id() as u32);
+ std::thread::sleep(std::time::Duration::from_secs(1));
+
+ // Checks that the process is listed as it should.
+ let mut s = sysinfo::System::new();
+ s.refresh_processes();
+ assert!(s.process(pid).is_some());
+
+ // Check that the process name is not empty.
+ assert!(!s.process(pid).unwrap().name().is_empty());
+
+ p.kill().expect("Unable to kill process.");
+ // We need this, otherwise the process will still be around as a zombie on linux.
+ let _ = p.wait();
+ // Let's give some time to the system to clean up...
+ std::thread::sleep(std::time::Duration::from_secs(1));
+
+ s.refresh_processes();
+ // Checks that the process isn't listed anymore.
+ assert!(s.process(pid).is_none());
+}
+
+// Checks that `refresh_process` is NOT removing dead processes.
+#[test]
+fn test_refresh_process() {
+ if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") {
+ return;
+ }
+ let mut p = if cfg!(target_os = "windows") {
+ std::process::Command::new("waitfor")
+ .arg("/t")
+ .arg("300")
+ .arg("RefreshProcess")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ } else {
+ std::process::Command::new("sleep")
+ .arg("300")
+ .stdout(std::process::Stdio::null())
+ .spawn()
+ .unwrap()
+ };
+
+ let pid = Pid::from_u32(p.id() as u32);
+ std::thread::sleep(std::time::Duration::from_secs(1));
+
+ // Checks that the process is listed as it should.
+ let mut s = sysinfo::System::new();
+ s.refresh_process(pid);
+ assert!(s.process(pid).is_some());
+
+ // Check that the process name is not empty.
+ assert!(!s.process(pid).unwrap().name().is_empty());
+
+ p.kill().expect("Unable to kill process.");
+ // We need this, otherwise the process will still be around as a zombie on linux.
+ let _ = p.wait();
+ // Let's give some time to the system to clean up...
+ std::thread::sleep(std::time::Duration::from_secs(1));
+
+ assert!(!s.refresh_process(pid));
+ // Checks that the process is still listed.
+ assert!(s.process(pid).is_some());
+}
diff --git a/vendor/sysinfo/tests/send_sync.rs b/vendor/sysinfo/tests/send_sync.rs
new file mode 100644
index 000000000..1f8cc192c
--- /dev/null
+++ b/vendor/sysinfo/tests/send_sync.rs
@@ -0,0 +1,10 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+#[test]
+fn test_send_sync() {
+ fn is_send<T: Send>() {}
+ fn is_sync<T: Sync>() {}
+
+ is_send::<sysinfo::System>();
+ is_sync::<sysinfo::System>();
+}
diff --git a/vendor/sysinfo/tests/uptime.rs b/vendor/sysinfo/tests/uptime.rs
new file mode 100644
index 000000000..d5eae7323
--- /dev/null
+++ b/vendor/sysinfo/tests/uptime.rs
@@ -0,0 +1,12 @@
+// Take a look at the license at the top of the repository in the LICENSE file.
+
+#[test]
+fn test_uptime() {
+ use sysinfo::SystemExt;
+
+ if sysinfo::System::IS_SUPPORTED {
+ let mut s = sysinfo::System::new();
+ s.refresh_all();
+ assert!(s.uptime() != 0);
+ }
+}