]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/core-run-destroy.rs
Revert "auto merge of #8645 : alexcrichton/rust/issue-6436-run-non-blocking, r=brson"
[rust.git] / src / test / run-pass / core-run-destroy.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // xfail-fast
12 // compile-flags:--test
13
14 // NB: These tests kill child processes. Valgrind sees these children as leaking
15 // memory, which makes for some *confusing* logs. That's why these are here
16 // instead of in std.
17
18 use std::libc;
19 use std::run::*;
20 use std::run;
21 use std::str;
22
23 #[test]
24 fn test_destroy_once() {
25     let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
26     p.destroy(); // this shouldn't crash (and nor should the destructor)
27 }
28
29 #[test]
30 fn test_destroy_twice() {
31     let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
32     p.destroy(); // this shouldnt crash...
33     p.destroy(); // ...and nor should this (and nor should the destructor)
34 }
35
36 fn test_destroy_actually_kills(force: bool) {
37
38     #[cfg(unix)]
39     static BLOCK_COMMAND: &'static str = "cat";
40
41     #[cfg(windows)]
42     static BLOCK_COMMAND: &'static str = "cmd";
43
44     #[cfg(unix,not(target_os="android"))]
45     fn process_exists(pid: libc::pid_t) -> bool {
46         let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]);
47         str::from_bytes(output).contains(pid.to_str())
48     }
49
50     #[cfg(unix,target_os="android")]
51     fn process_exists(pid: libc::pid_t) -> bool {
52         let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]);
53         str::from_bytes(output).contains(~"root")
54     }
55
56     #[cfg(windows)]
57     fn process_exists(pid: libc::pid_t) -> bool {
58
59         use std::libc::types::os::arch::extra::DWORD;
60         use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
61         use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };
62
63         unsafe {
64             let proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
65             if proc.is_null() {
66                 return false;
67             }
68             // proc will be non-null if the process is alive, or if it died recently
69             let mut status = 0;
70             GetExitCodeProcess(proc, &mut status);
71             CloseHandle(proc);
72             return status == STILL_ACTIVE;
73         }
74     }
75
76     // this process will stay alive indefinitely trying to read from stdin
77     let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new());
78
79     assert!(process_exists(p.get_id()));
80
81     if force {
82         p.force_destroy();
83     } else {
84         p.destroy();
85     }
86
87     assert!(!process_exists(p.get_id()));
88 }
89
90 #[test]
91 fn test_unforced_destroy_actually_kills() {
92     test_destroy_actually_kills(false);
93 }
94
95 #[test]
96 fn test_forced_destroy_actually_kills() {
97     test_destroy_actually_kills(true);
98 }