1+ use std:: io;
2+ use std:: process:: { Child , ExitStatus } ;
3+ #[ cfg( not( windows) ) ]
4+ use nix:: {
5+ sys:: signal:: { self , Signal } ,
6+ unistd:: Pid ,
7+ } ;
8+
9+ pub struct Processo {
10+ pub processo : Child ,
11+ }
12+
13+ impl Processo {
14+
15+ #[ cfg( windows) ]
16+ pub fn terminate ( & mut self ) -> io:: Result < ( ) > {
17+ self . processo . kill ( )
18+ }
19+
20+ #[ cfg( not( windows) ) ]
21+ pub fn terminate ( & mut self ) -> io:: Result < ( ) > {
22+ let pid = Pid :: from_raw ( self . processo . id ( ) as i32 ) ;
23+ match signal:: kill ( pid, Signal :: SIGTERM ) {
24+ Ok ( _) => Ok ( ( ) ) ,
25+ Err ( e) => Err ( io:: Error :: new ( io:: ErrorKind :: Other , e) ) ,
26+ }
27+ }
28+
29+ pub fn kill ( & mut self ) -> io:: Result < ( ) > {
30+ self . processo . kill ( )
31+ }
32+
33+ }
34+ mod tests {
35+ use super :: * ;
36+ use std:: process:: Command ;
37+ use std:: thread;
38+ use std:: time:: Duration ;
39+
40+ fn create_long_running_command ( ) -> Command {
41+ if cfg ! ( windows) {
42+ let mut cmd = Command :: new ( "timeout" ) ;
43+ cmd. arg ( "/T" ) . arg ( "30" ) ;
44+ cmd
45+ } else {
46+ let mut cmd = Command :: new ( "sleep" ) ;
47+ cmd. arg ( "30" ) ;
48+ cmd
49+ }
50+ }
51+
52+ #[ test]
53+ fn test_terminate_a_running_process ( ) {
54+ let child = create_long_running_command ( )
55+ . spawn ( )
56+ . expect ( "Falha ao iniciar processo para o teste de terminate" ) ;
57+
58+ let mut processo = Processo { processo : child } ;
59+
60+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
61+
62+ processo. terminate ( ) . expect ( "Falha ao chamar terminate" ) ;
63+
64+ let exit_code = processo. wait ( ) . expect ( "Falha ao esperar pelo processo terminado" ) ;
65+
66+ let expected_code = if cfg ! ( windows) { 1 } else { -1 } ;
67+ assert_eq ! ( exit_code, expected_code, "O código de saída após terminate não foi o esperado." ) ;
68+ }
69+
70+ #[ test]
71+ fn test_kill_a_running_process ( ) {
72+ let child = create_long_running_command ( )
73+ . spawn ( )
74+ . expect ( "Falha ao iniciar processo para o teste de kill" ) ;
75+
76+
77+ let mut processo = Processo { processo : child } ;
78+
79+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
80+
81+ processo. kill ( ) . expect ( "Falha ao chamar kill" ) ;
82+
83+
84+ let exit_code = processo. wait ( ) . expect ( "Falha ao esperar pelo processo morto" ) ;
85+
86+ let expected_code = if cfg ! ( windows) { 1 } else { -1 } ;
87+ assert_eq ! ( exit_code, expected_code, "O código de saída após kill não foi o esperado." ) ;
88+ }
89+
90+ #[ test]
91+ fn test_wait_on_a_process_that_finishes_normally ( ) {
92+ let mut command = if cfg ! ( windows) {
93+ let mut cmd = Command :: new ( "timeout" ) ;
94+ cmd. arg ( "/T" ) . arg ( "1" ) ;
95+ cmd
96+ } else {
97+ let mut cmd = Command :: new ( "sleep" ) ;
98+ cmd. arg ( "1" ) ;
99+ cmd
100+ } ;
101+
102+ let child = command. spawn ( ) . expect ( "Falha ao iniciar processo curto" ) ;
103+ let mut processo = Processo { processo : child } ;
104+
105+ let exit_code = processo. wait ( ) . expect ( "Falha ao esperar pelo processo" ) ;
106+ assert_eq ! ( exit_code, 0 ) ;
107+ }
108+ }
0 commit comments