Poll based under load with intg test

This commit is contained in:
Prabhpreet Dua
2024-02-04 20:17:28 +05:30
parent d18107b3a9
commit 0b4699e24a
6 changed files with 127 additions and 50 deletions

View File

@@ -1,4 +1,4 @@
use std::{fs, net::UdpSocket, path::PathBuf, process::Stdio, time::Duration};
use std::{fs, net::UdpSocket, path::PathBuf, process::Stdio, thread::sleep, time::Duration};
const BIN: &str = "rosenpass";
@@ -119,6 +119,7 @@ fn check_exchange_under_normal() {
}
// check that we can exchange keys
#[cfg(feature = "integration_test")]
#[test]
fn check_exchange_under_dos() {
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join("exchange-dos");
@@ -143,6 +144,14 @@ fn check_exchange_under_dos() {
assert!(pub_key_path.is_file());
}
//Create a semaphore. The server will unblock this semaphore after it is under load condition.
//There are parameters setup under app_server to remain in load condition once triggered for this test feature.
let sem_name = b"/rp_integration_test_under_dos\0";
let sem = unsafe { libc::sem_open(sem_name.as_ptr() as *const i8, libc::O_CREAT, 0o644, 1) };
unsafe {
libc::sem_wait(sem);
}
// start first process, the server
let port = find_udp_socket();
let listen_addr = format!("localhost:{port}");
@@ -158,29 +167,56 @@ fn check_exchange_under_dos() {
//.stdout(Stdio::null())
//.stderr(Stdio::null())
.spawn()
.expect("Failed to start {BIN}");
.expect("Test setup failed- Failed to start {server_bin}");
std::thread::sleep(Duration::from_millis(500));
//DoS Sender
//Create a UDP socket
//Create a UDP socket for DOS sender
let socket = UdpSocket::bind("127.0.0.1:0").expect("couldn't bind to address");
//Spawn a thread to send DoS packets
let server_addr = listen_addr.clone();
//Create thread safe atomic bool to stop the DoS attack
let stop_dos = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let stop_dos_handle = stop_dos.clone();
//Spawn a thread to send DoS packets
let dos_attack = std::thread::spawn(move || {
while stop_dos.load(std::sync::atomic::Ordering::Relaxed) == false {
let buf = [0; 10];
socket
.send_to(&buf, &server_addr)
.expect("couldn't send data");
sleep(Duration::from_micros(10));
}
});
//Wait till we are under load condition for upto 5 seconds
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
let now = std::time::SystemTime::now();
let timeout_absolute = now + Duration::from_secs(5);
if let Ok(duration) = timeout_absolute.duration_since(std::time::SystemTime::UNIX_EPOCH) {
ts.tv_sec = duration.as_secs() as libc::time_t;
ts.tv_nsec = duration.subsec_nanos() as _;
} else {
panic!("Test setup failed- Failed to calculate timeout for semaphore");
}
let mut failed_wait = false;
if (unsafe { libc::sem_timedwait(sem, &ts) } == -1) {
failed_wait = true;
}
// Close and unlink the semaphore
if unsafe { libc::sem_close(sem) } == -1 {
panic!("Test setup failed- Failed to close semaphore");
}
if unsafe { libc::sem_unlink(sem_name.as_ptr() as *const i8) } == -1 {
panic!("Test setup failed- Failed to unlink semaphore");
}
if failed_wait {
panic!("Failed to wait for semaphore- load condition not reached");
}
// start second process, the client
let mut client = test_bin::get_test_bin(BIN)
.args(["exchange", "secret-key"])
@@ -197,8 +233,8 @@ fn check_exchange_under_dos() {
.spawn()
.expect("Failed to start {BIN}");
// give them some time to do the key exchange
std::thread::sleep(Duration::from_secs(2));
// give them some time to do the key exchange under load
std::thread::sleep(Duration::from_secs(10));
// time's up, kill the childs
server.kill().unwrap();