in src/enclave_proc/connection_listener.rs [403:515]
fn test_connection_listener_run_connection_stop() {
let old_log_path = env::var(SOCKETS_DIR_PATH_ENV_VAR);
env::set_var(SOCKETS_DIR_PATH_ENV_VAR, TMP_DIR);
let resources_dir = get_sockets_dir_path();
let path_existed = resources_dir.as_path().exists();
let _ = fs::create_dir(resources_dir.as_path());
let dummy_sock_name = "run_connection_stop.sock";
let dummy_sock_path = format!(
"{}/{}",
resources_dir.as_path().to_str().unwrap(),
dummy_sock_name
);
// Remove pre-existing socket file
let _ = std::fs::remove_file(&dummy_sock_path);
let mut connection_listener = ConnectionListener::new().unwrap();
connection_listener
.socket
.set_path(PathBuf::from(&dummy_sock_path));
// Get number of running threads before spawning the listener thread
let out_cmd0 = Command::new("cat")
.arg(format!("/proc/{}/status", std::process::id()))
.output()
.expect("Failed to run cat");
let out0 = std::str::from_utf8(&out_cmd0.stdout).unwrap();
let crt_num_threads0 = get_num_threads_from_status_output(out0.to_string());
let pair = Arc::new((Mutex::new(false), Condvar::new()));
let pair2 = pair.clone();
let listener_thread = thread::spawn(move || {
{
let (lock, cvar) = &*pair2;
let mut started = lock.lock().unwrap();
*started = true;
cvar.notify_one();
}
// Bind the listener to the socket and spawn the listener thread.
let listener = UnixListener::bind(connection_listener.socket.get_path())
.map_err(|e| format!("Failed to bind connection listener: {:?}", e))
.unwrap();
connection_listener.enable_credentials_passing(&listener);
connection_listener
.socket
.start_monitoring(true)
.map_err(|e| format!("Failed to start socket monitoring: {:?}", e))
.unwrap();
let res = connection_listener.connection_listener_run(listener);
assert!(res.is_ok());
});
// Allow thread to finish spawning
let (lock, cvar) = &*pair;
let mut started = lock.lock().unwrap();
while !*started {
started = cvar.wait(started).unwrap();
}
// Check that the listener thread is running
let out_cmd1 = Command::new("cat")
.arg(format!("/proc/{}/status", std::process::id()))
.output()
.expect("Failed to run cat");
let out1 = std::str::from_utf8(&out_cmd1.stdout).unwrap();
let crt_num_threads1 = get_num_threads_from_status_output(out1.to_string());
assert!(crt_num_threads0 < crt_num_threads1);
let my_stream = UnixStream::connect(&dummy_sock_path);
if let Ok(mut my_stream) = my_stream {
// Close the listener thread
let cmd = EnclaveProcessCommandType::ConnectionListenerStop;
let _ = enclave_proc_command_send_single::<EmptyArgs>(cmd, None, &mut my_stream);
}
// Wait for thread to join after exiting
listener_thread
.join()
.expect("Failed to join on the associated thread");
// Check number of threads after closing the listener thread
let out_cmd2 = Command::new("cat")
.arg(format!("/proc/{}/status", std::process::id()))
.output()
.expect("Failed to run cat");
let out2 = std::str::from_utf8(&out_cmd2.stdout).unwrap();
let crt_num_threads2 = get_num_threads_from_status_output(out2.to_string());
assert_eq!(crt_num_threads0, crt_num_threads2);
assert!(crt_num_threads2 < crt_num_threads1);
if !path_existed {
// Remove whole resources_dir
let _ = fs::remove_dir_all(resources_dir.as_path().to_str().unwrap());
} else {
// Only remove the socket file
let _ = fs::remove_file(&dummy_sock_path);
}
// Restore previous environment variable value
if let Ok(old_log_path) = old_log_path {
env::set_var(SOCKETS_DIR_PATH_ENV_VAR, old_log_path);
} else {
env::set_var(SOCKETS_DIR_PATH_ENV_VAR, "");
unset_envvar(&String::from(SOCKETS_DIR_PATH_ENV_VAR));
}
}