fn test_connection_listener_run_connection_stop()

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));
        }
    }