summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/tests/process.rs
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/process.rs
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/process.rs')
-rw-r--r--vendor/sysinfo/tests/process.rs381
1 files changed, 381 insertions, 0 deletions
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());
+}