Skip to content

Move core::run tests of process killing into standalone run-pass tests #6228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -855,74 +855,4 @@ mod tests {
fn waitpid_non_existant_pid() {
run::waitpid(123456789); // assume that this pid doesn't exist
}

#[test]
fn test_destroy_once() {
let mut p = run::start_program("echo", []);
p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
let mut p = run::start_program("echo", []);
p.destroy(); // this shouldnt crash...
p.destroy(); // ...and nor should this (and nor should the destructor)
}

fn test_destroy_actually_kills(force: bool) {

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

#[cfg(windows)]
static BLOCK_COMMAND: &'static str = "cmd";

#[cfg(unix)]
fn process_exists(pid: libc::pid_t) -> bool {
run::program_output("ps", [~"-p", pid.to_str()]).out.contains(pid.to_str())
}

#[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;
}
}

// 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]
fn test_unforced_destroy_actually_kills() {
test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
test_destroy_actually_kills(true);
}
}
89 changes: 89 additions & 0 deletions src/test/run-pass/core-run-destroy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-fast
// compile-flags:--test

// NB: These tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in core.

use core::run;
use core::run::*;

#[test]
fn test_destroy_once() {
let mut p = run::start_program("echo", []);
p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
let mut p = run::start_program("echo", []);
p.destroy(); // this shouldnt crash...
p.destroy(); // ...and nor should this (and nor should the destructor)
}

fn test_destroy_actually_kills(force: bool) {

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

#[cfg(windows)]
static BLOCK_COMMAND: &'static str = "cmd";

#[cfg(unix)]
fn process_exists(pid: libc::pid_t) -> bool {
run::program_output("ps", [~"-p", pid.to_str()]).out.contains(pid.to_str())
}

#[cfg(windows)]
fn process_exists(pid: libc::pid_t) -> bool {

use core::libc::types::os::arch::extra::DWORD;
use core::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
use core::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;
}
}

// 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]
fn test_unforced_destroy_actually_kills() {
test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
test_destroy_actually_kills(true);
}