@@ -43,21 +43,47 @@ def bisect(cli_args, expected_status=nil)
43
43
end
44
44
45
45
it 'does not leave zombie processes' , :unless => RSpec ::Support ::OS . windows? do
46
- original_pids = pids ( )
47
- bisect ( %W[ spec/rspec/core/resources/blocking_pipe_bisect_spec.rb_ ] , 1 )
48
- cursor = 0
49
- while ( ( extra_pids = pids ( ) - original_pids ) . join =~ /[RE]/i )
50
- raise "Extra process detected" if cursor > 10
51
- cursor += 1
52
- sleep 0.1
53
- end
54
- expect ( extra_pids . join ) . to_not include "Z"
46
+ bisect ( [ '--format' , 'json' , 'spec/rspec/core/resources/blocking_pipe_bisect_spec.rb_' ] , 1 )
47
+
48
+ zombie_process = RSpecChildProcess . new ( Process . pid ) . zombie_process
49
+ expect ( zombie_process ) . to eq ( [ ] ) , <<-MSG
50
+ Expected no zombie processes got #{ zombie_process . count } :
51
+ #{ zombie_process }
52
+ MSG
55
53
end
56
54
end
57
55
58
- def pids
59
- %x[ps -ho pid,state,cmd | grep "[r]uby"] . split ( "\n " ) . map do |line |
60
- line . split ( /\s +/ ) . compact . join ( ' ' )
56
+ class RSpecChildProcess
57
+ Ps = Struct . new ( :pid , :ppid , :state , :command )
58
+
59
+ def initialize ( pid )
60
+ @list = child_process_list ( pid )
61
+ end
62
+
63
+ def zombie_process
64
+ @list . select { |child_process | child_process . state =~ /Z/ }
65
+ end
66
+
67
+ private
68
+
69
+ def child_process_list ( pid )
70
+ childs_process_list = [ ]
71
+ ps_pipe = `ps -o pid=,ppid=,state=,args= | grep #{ pid } `
72
+
73
+ ps_pipe . split ( /\n / ) . map do |line |
74
+ ps_part = line . lstrip . split ( /\s +/ )
75
+
76
+ next unless ps_part [ 1 ] . to_i == pid
77
+
78
+ child_process = Ps . new
79
+ child_process . pid = ps_part [ 0 ]
80
+ child_process . ppid = ps_part [ 1 ]
81
+ child_process . state = ps_part [ 2 ]
82
+ child_process . command = ps_part [ 3 ..-1 ] . join ( ' ' )
83
+
84
+ childs_process_list << child_process
85
+ end
86
+ childs_process_list
61
87
end
62
88
end
63
89
end
0 commit comments