use super::handlers::{ignore_signal, install_signal_handler, restore_default_handler};
use super::*;
use serial_test::serial;
use std::sync::atomic::Ordering;
#[test]
#[serial]
fn test_signal_flag_operations() {
const TEST_IDX: usize = 3;
SIGNAL_FLAGS[TEST_IDX].store(false, Ordering::Release);
assert!(!SIGNAL_FLAGS[TEST_IDX].load(Ordering::Acquire));
SIGNAL_FLAGS[TEST_IDX].store(true, Ordering::Release);
assert!(SIGNAL_FLAGS[TEST_IDX].load(Ordering::Acquire));
let was_set = SIGNAL_FLAGS[TEST_IDX].swap(false, Ordering::Acquire);
assert!(was_set);
assert!(!SIGNAL_FLAGS[TEST_IDX].load(Ordering::Acquire));
let was_set = SIGNAL_FLAGS[TEST_IDX].swap(false, Ordering::Acquire);
assert!(!was_set);
SIGNAL_FLAGS[TEST_IDX].store(false, Ordering::Release);
}
#[cfg(unix)]
#[test]
#[serial]
fn test_signal_handler_installation() {
let result = install_signal_handler(libc::SIGUSR1);
assert!(result.is_ok(), "Failed to install SIGUSR1 handler");
let result = restore_default_handler(libc::SIGUSR1);
assert!(result.is_ok(), "Failed to restore SIGUSR1 default handler");
}
#[cfg(unix)]
#[test]
#[serial]
fn test_signal_delivery() {
install_signal_handler(libc::SIGUSR1).expect("Failed to install handler");
SIGNAL_FLAGS[libc::SIGUSR1 as usize].store(false, Ordering::Release);
unsafe {
libc::kill(libc::getpid(), libc::SIGUSR1);
}
std::thread::sleep(std::time::Duration::from_millis(1));
let received = SIGNAL_FLAGS[libc::SIGUSR1 as usize].swap(false, Ordering::Acquire);
assert!(received, "Signal was not received");
restore_default_handler(libc::SIGUSR1).expect("Failed to restore handler");
}
#[cfg(unix)]
#[test]
#[serial]
fn test_invalid_signal_fails() {
let result = install_signal_handler(libc::SIGKILL);
assert!(result.is_err(), "SIGKILL should not be catchable");
let result = install_signal_handler(libc::SIGSTOP);
assert!(result.is_err(), "SIGSTOP should not be catchable");
}
#[cfg(unix)]
#[test]
#[serial]
fn test_signal_ignore() {
let result = ignore_signal(libc::SIGUSR2);
assert!(result.is_ok(), "Failed to ignore SIGUSR2");
let result = restore_default_handler(libc::SIGUSR2);
assert!(result.is_ok(), "Failed to restore SIGUSR2 default handler");
}
#[cfg(unix)]
#[test]
#[serial]
fn test_multiple_signals_independent() {
install_signal_handler(libc::SIGUSR1).expect("Failed to install SIGUSR1");
install_signal_handler(libc::SIGUSR2).expect("Failed to install SIGUSR2");
SIGNAL_FLAGS[libc::SIGUSR1 as usize].store(false, Ordering::Release);
SIGNAL_FLAGS[libc::SIGUSR2 as usize].store(false, Ordering::Release);
unsafe {
libc::kill(libc::getpid(), libc::SIGUSR1);
}
std::thread::sleep(std::time::Duration::from_millis(1));
assert!(SIGNAL_FLAGS[libc::SIGUSR1 as usize].load(Ordering::Acquire));
assert!(!SIGNAL_FLAGS[libc::SIGUSR2 as usize].load(Ordering::Acquire));
restore_default_handler(libc::SIGUSR1).expect("Failed to restore SIGUSR1");
restore_default_handler(libc::SIGUSR2).expect("Failed to restore SIGUSR2");
}
#[cfg(unix)]
#[test]
fn test_signal_constants_valid() {
assert!(libc::SIGINT > 0 && (libc::SIGINT as usize) < MAX_SIGNAL);
assert!(libc::SIGTERM > 0 && (libc::SIGTERM as usize) < MAX_SIGNAL);
assert!(libc::SIGHUP > 0 && (libc::SIGHUP as usize) < MAX_SIGNAL);
assert!(libc::SIGPIPE > 0 && (libc::SIGPIPE as usize) < MAX_SIGNAL);
assert!(libc::SIGUSR1 > 0 && (libc::SIGUSR1 as usize) < MAX_SIGNAL);
assert!(libc::SIGUSR2 > 0 && (libc::SIGUSR2 as usize) < MAX_SIGNAL);
}