Skip to content

Commit

Permalink
Fix some issues with test_destroy_actually_kills:
Browse files Browse the repository at this point in the history
- it is now cross platform, instead of just unix
- it now avoids sleeping (fixing issue rust-lang#6156)
- it now calls force_destroy() when force = true (was a bug)
  • Loading branch information
gareth authored and gareth committed May 2, 2013
1 parent 23e97ae commit bd979c1
Showing 1 changed file with 38 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,6 @@ mod tests {
use libc;
use option::None;
use os;
use path::Path;
use run::{readclose, writeclose};
use run;

Expand Down Expand Up @@ -870,34 +869,59 @@ mod tests {
p.destroy(); // ...and nor should this (and nor should the destructor)
}

#[cfg(unix)] // there is no way to sleep on windows from inside libcore...
fn test_destroy_actually_kills(force: bool) {
let path = Path(fmt!("test/core-run-test-destroy-actually-kills-%?.tmp", force));

os::remove_file(&path);
#[cfg(unix)]
static BLOCK_COMMAND: &'static str = "cat";

let cmd = fmt!("sleep 5 && echo MurderDeathKill > %s", path.to_str());
let mut p = run::start_program("sh", [~"-c", cmd]);
#[cfg(windows)]
static BLOCK_COMMAND: &'static str = "cmd";

p.destroy(); // destroy the program before it has a chance to echo its message
#[cfg(unix)]
fn process_exists(pid: libc::pid_t) -> bool {
run::program_output("ps", [~"-p", pid.to_str()]).out.contains(pid.to_str())
}

unsafe {
// wait to ensure the program is really destroyed and not just waiting itself
libc::sleep(10);
#[cfg(windows)]
fn process_exists(pid: libc::pid_t) -> bool {

use libc::types::os::arch::extra::DWORD;
use libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
use libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

unsafe {
let proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
if proc.is_null() {
return false;
}
// proc will be non-null if the process is alive, or if it died recently
let mut status = 0;
GetExitCodeProcess(proc, &mut status);
CloseHandle(proc);
return status == STILL_ACTIVE;
}
}

// the program should not have had chance to echo its message
assert!(!path.exists());
// this program will stay alive indefinitely trying to read from stdin
let mut p = run::start_program(BLOCK_COMMAND, []);

assert!(process_exists(p.get_id()));

if force {
p.force_destroy();
} else {
p.destroy();
}

assert!(!process_exists(p.get_id()));
}

#[test]
#[cfg(unix)]
fn test_unforced_destroy_actually_kills() {
test_destroy_actually_kills(false);
}

#[test]
#[cfg(unix)]
fn test_forced_destroy_actually_kills() {
test_destroy_actually_kills(true);
}
Expand Down

0 comments on commit bd979c1

Please sign in to comment.