Skip to content

Commit

Permalink
feat: windows process constructor, windows tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtread committed May 22, 2024
1 parent 0624cb5 commit 3cf01ef
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct KillportSignal(pub nix::sys::signal::Signal);

/// On a platform where we don't have the proper signals enum
#[cfg(not(unix))]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct KillportSignal(pub String);

impl Display for KillportSignal {
Expand Down
8 changes: 7 additions & 1 deletion src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ pub struct WindowsProcess {
name: Option<String>,
}

impl WindowsProcess {
pub fn new(pid: u32, name: Option<String>) -> Self {
Self { pid, name }
}
}

/// Finds the processes associated with the specified `port`.
///
/// Returns a `Vec` of native processes.
Expand Down Expand Up @@ -65,7 +71,7 @@ pub fn find_target_processes(port: u16) -> Result<Vec<WindowsProcess>> {
// Collect the processes
let mut processes: Vec<WindowsProcess> = pids
.into_iter()
.map(|pid| WindowsProcess { pid, name: None })
.map(|pid| WindowsProcess::new(pid, None))
.collect();

lookup_proccess_names(&mut processes)?;
Expand Down
149 changes: 149 additions & 0 deletions tests/killport_windows_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#![cfg(windows)]

use killport::cli::Mode;
use killport::killport::{Killable, KillableType};
use killport::signal::KillportSignal;
use killport::windows::WindowsProcess;
use mockall::*;

use std::io::Error;

// Setup Mocks
mock! {
DockerContainer {}

impl Killable for DockerContainer {
fn kill(&self, signal: KillportSignal) -> Result<bool, Error>;
fn get_type(&self) -> KillableType;
fn get_name(&self) -> String;
}
}

mock! {
WindowsProcess {}

impl Killable for WindowsProcess {
fn kill(&self, signal: KillportSignal) -> Result<bool, Error>;
fn get_type(&self) -> KillableType;
fn get_name(&self) -> String;
}
}
mock! {
KillportOperations {
fn find_target_killables(&self, port: u16, mode: Mode) -> Result<Vec<Box<dyn Killable>>, Error>;
fn kill_service_by_port(&self, port: u16, signal: KillportSignal, mode: Mode, dry_run: bool) -> Result<Vec<(KillableType, String)>, Error>;
}
}

#[test]
fn native_process_kill_succeeds() {
let mut mock_process = MockWindowsProcess::new();
// Setup the expectation for the mock
mock_process
.expect_kill()
.with(mockall::predicate::eq(KillportSignal(
"SIGKILL".to_string(),
)))
.times(1) // Ensure the kill method is called exactly once
.returning(|_| Ok(true)); // Simulate successful kill

assert!(mock_process
.kill(KillportSignal("SIGKILL".to_string()))
.unwrap());
}

#[test]
fn docker_container_kill_succeeds() {
let mut mock_container = MockDockerContainer::new();
mock_container
.expect_kill()
.with(mockall::predicate::eq(KillportSignal(
"SIGKILL".to_string(),
)))
.times(1)
.returning(|_| Ok(true));

assert!(mock_container
.kill(KillportSignal("SIGKILL".to_string()))
.unwrap());
}

#[test]
fn find_killables_processes_only() {
let mut mock_killport = MockKillportOperations::new();

mock_killport
.expect_find_target_killables()
.withf(|&port, &mode| port == 8080 && mode == Mode::Process)
.returning(|_, _| {
let mut mock_process = MockWindowsProcess::new();
mock_process
.expect_get_type()
.return_const(KillableType::Process);
mock_process
.expect_get_name()
.return_const("mock_process".to_string());
Ok(vec![Box::new(mock_process)])
});

let port = 8080;
let mode = Mode::Process;
let found_killables = mock_killport.find_target_killables(port, mode).unwrap();
assert!(found_killables
.iter()
.all(|k| k.get_type() == KillableType::Process));
}

#[test]
fn kill_service_by_port_dry_run() {
let mut mock_killport = MockKillportOperations::new();
let mut mock_process = MockWindowsProcess::new();

mock_process.expect_kill().never();
mock_process
.expect_get_type()
.return_const(KillableType::Process);
mock_process
.expect_get_name()
.return_const("mock_process".to_string());

mock_killport
.expect_kill_service_by_port()
.returning(|_, _, _, _| Ok(vec![(KillableType::Process, "mock_process".to_string())]));

let port = 8080;
let mode = Mode::Process;
let dry_run = true;
let signal = KillportSignal("SIGKILL".to_string());

let results = mock_killport
.kill_service_by_port(port, signal, mode, dry_run)
.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].0, KillableType::Process);
assert_eq!(results[0].1, "mock_process");
}

#[test]
fn check_process_type_and_name() {
let process = WindowsProcess::new(1234, Some("unique_process".to_string()));

assert_eq!(process.get_type(), KillableType::Process);
assert_eq!(process.get_name(), "unique_process");
}

#[test]
fn check_docker_container_type_and_name() {
let mut mock_container = MockDockerContainer::new();
mock_container
.expect_get_type()
.times(1)
.returning(|| KillableType::Container);
mock_container
.expect_get_name()
.times(1)
.returning(|| "docker_container".to_string());

assert_eq!(mock_container.get_type(), KillableType::Container);
assert_eq!(mock_container.get_name(), "docker_container");
}

0 comments on commit 3cf01ef

Please sign in to comment.