#![allow(clippy::expect_used)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::panic)]
#![allow(clippy::match_wild_err_arm)]
#![allow(clippy::uninlined_format_args)]
use std::{
env, fs,
path::{Path, PathBuf},
process::exit,
thread,
time::Duration,
};
use fork::{Fork, WEXITSTATUS, WIFEXITED, chdir, fork, waitpid};
#[test]
fn test_chdir_basic_success() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status), "Child should exit normally");
assert_eq!(WEXITSTATUS(status), 0, "Child should exit with code 0");
}
Fork::Child => {
match chdir() {
Ok(()) => {
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/", "Should be in root directory");
exit(0);
}
Err(e) => {
eprintln!("chdir failed: {}", e);
exit(1);
}
}
}
}
}
#[test]
fn test_chdir_returns_unit() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
let result: std::io::Result<()> = chdir();
assert!(result.is_ok());
let _unit: () = result.unwrap();
exit(0);
}
}
}
#[test]
fn test_chdir_changes_actual_working_directory() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
let original = env::current_dir().expect("Failed to get original dir");
chdir().expect("chdir failed");
let new_dir = env::current_dir().expect("Failed to get new dir");
assert_eq!(new_dir, PathBuf::from("/"), "Should be in root");
if original.as_path() != Path::new("/") {
assert_ne!(
original, new_dir,
"Directory should change when not already at /"
);
}
exit(0);
}
}
}
#[test]
fn test_chdir_idempotent() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
chdir().expect("First chdir failed");
chdir().expect("Second chdir failed");
chdir().expect("Third chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
exit(0);
}
}
}
#[test]
fn test_chdir_process_isolation() {
let parent_dir = env::current_dir().expect("Failed to get parent dir");
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
let current = env::current_dir().expect("Failed to get current dir");
assert_eq!(current, parent_dir, "Parent directory should not change");
}
Fork::Child => {
chdir().expect("chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
exit(0);
}
}
}
#[test]
fn test_chdir_with_file_operations() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
chdir().expect("chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
fs::metadata(".").expect("Root directory metadata should be readable");
exit(0);
}
}
}
#[test]
fn test_chdir_with_absolute_path_operations() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
let temp_file = std::env::temp_dir().join("fork_test_chdir");
fs::write(&temp_file, "test").expect("Failed to write test file");
chdir().expect("chdir failed");
let content =
fs::read_to_string(&temp_file).expect("Failed to read with absolute path");
assert_eq!(content, "test");
fs::remove_file(&temp_file).ok();
exit(0);
}
}
}
#[test]
fn test_chdir_error_type() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
let result: std::io::Result<()> = chdir();
assert!(result.is_ok());
match result {
Ok(()) => exit(0),
Err(e) => {
let _: std::io::Error = e;
exit(1);
}
}
}
}
}
#[test]
fn test_chdir_concurrent_forks() {
let mut children = Vec::new();
for _ in 0..3 {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
children.push(child);
}
Fork::Child => {
chdir().expect("chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
thread::sleep(Duration::from_millis(10));
exit(0);
}
}
}
for child in children {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
}
#[test]
fn test_chdir_before_and_after_setsid() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
use fork::setsid;
setsid().expect("setsid failed");
chdir().expect("chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
let pgid = fork::getpgrp();
assert!(pgid > 0);
exit(0);
}
}
}
#[test]
fn test_chdir_uses_c_string_literal() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
for _ in 0..100 {
chdir().expect("chdir failed");
}
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
exit(0);
}
}
}
#[test]
fn test_chdir_with_env_manipulation() {
match fork().expect("Fork failed") {
Fork::Parent(child) => {
let status = waitpid(child).expect("waitpid failed");
assert!(WIFEXITED(status));
assert_eq!(WEXITSTATUS(status), 0);
}
Fork::Child => {
unsafe {
env::set_var("PWD", "/some/fake/path");
}
chdir().expect("chdir failed");
let cwd = env::current_dir().expect("Failed to get current dir");
assert_eq!(cwd.to_str().unwrap(), "/");
exit(0);
}
}
}