Skip to content

Commit a3846bf

Browse files
committed
Avoid using fork in Process specs
1 parent c30935a commit a3846bf

4 files changed

Lines changed: 94 additions & 92 deletions

File tree

core/process/detach_spec.rb

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,82 @@
11
require_relative '../../spec_helper'
2+
require_relative 'fixtures/common'
23

34
describe "Process.detach" do
4-
platform_is_not :windows do
5-
it "returns a thread" do
6-
pid = Process.fork { Process.exit! }
7-
thr = Process.detach(pid)
8-
thr.should.is_a?(Thread)
9-
thr.join
10-
end
5+
ProcessSpecs.use_system_ruby(self)
116

12-
it "produces the exit Process::Status as the thread value" do
13-
pid = Process.fork { Process.exit! }
14-
thr = Process.detach(pid)
15-
thr.join
7+
it "returns a thread" do
8+
pid = Process.spawn(*ruby_exe, "-e", "exit")
9+
thr = Process.detach(pid)
10+
thr.should.is_a?(Thread)
11+
thr.join
12+
end
1613

17-
status = thr.value
18-
status.should.is_a?(Process::Status)
19-
status.pid.should == pid
20-
end
14+
it "produces the exit Process::Status as the thread value" do
15+
pid = Process.spawn(*ruby_exe, "-e", "exit")
16+
thr = Process.detach(pid)
17+
thr.join
18+
19+
status = thr.value
20+
status.should.is_a?(Process::Status)
21+
status.pid.should == pid
22+
end
2123

22-
platform_is_not :openbsd do
23-
it "reaps the child process's status automatically" do
24-
pid = Process.fork { Process.exit! }
25-
Process.detach(pid).join
26-
-> { Process.waitpid(pid) }.should.raise(Errno::ECHILD)
27-
end
24+
platform_is_not :openbsd do
25+
it "reaps the child process's status automatically" do
26+
pid = Process.spawn(*ruby_exe, "-e", "exit")
27+
Process.detach(pid).join
28+
-> { Process.waitpid(pid) }.should.raise(Errno::ECHILD)
2829
end
30+
end
2931

30-
it "sets the :pid thread-local to the PID" do
31-
pid = Process.fork { Process.exit! }
32-
thr = Process.detach(pid)
33-
thr.join
32+
it "sets the :pid thread-local to the PID" do
33+
pid = Process.spawn(*ruby_exe, "-e", "exit")
34+
thr = Process.detach(pid)
35+
thr.join
3436

35-
thr[:pid].should == pid
36-
end
37+
thr[:pid].should == pid
38+
end
3739

38-
it "provides a #pid method on the returned thread which returns the PID" do
39-
pid = Process.fork { Process.exit! }
40-
thr = Process.detach(pid)
41-
thr.join
40+
it "provides a #pid method on the returned thread which returns the PID" do
41+
pid = Process.spawn(*ruby_exe, "-e", "exit")
42+
thr = Process.detach(pid)
43+
thr.join
4244

43-
thr.pid.should == pid
44-
end
45+
thr.pid.should == pid
46+
end
4547

46-
it "tolerates not existing child process pid" do
47-
# Use a value that is close to the INT_MAX (pid usually is signed int).
48-
# It should (at least) be greater than allowed pid limit value that depends on OS.
49-
pid_not_existing = 2.pow(30)
48+
it "tolerates not existing child process pid" do
49+
# Use a value that is close to the INT_MAX (pid usually is signed int).
50+
# It should (at least) be greater than allowed pid limit value that depends on OS.
51+
pid_not_existing = 2.pow(30)
5052

51-
# Check that there is no a child process with this hardcoded pid.
52-
# Command `kill 0 pid`:
53-
# - returns "1" if a process exists and
54-
# - raises Errno::ESRCH otherwise
55-
-> { Process.kill(0, pid_not_existing) }.should.raise(Errno::ESRCH)
53+
# Check that there is no a child process with this hardcoded pid.
54+
# Command `kill 0 pid`:
55+
# - returns "1" if a process exists and
56+
# - raises Errno::ESRCH otherwise
57+
-> { Process.kill(0, pid_not_existing) }.should.raise(Errno::ESRCH)
5658

57-
thr = Process.detach(pid_not_existing)
58-
thr.join
59+
thr = Process.detach(pid_not_existing)
60+
thr.join
5961

60-
thr.should.is_a?(Thread)
61-
end
62+
thr.should.is_a?(Thread)
63+
end
6264

63-
it "calls #to_int to implicitly convert non-Integer pid to Integer" do
64-
pid = MockObject.new('mock-enumerable')
65-
pid.should_receive(:to_int).and_return(100500)
65+
it "calls #to_int to implicitly convert non-Integer pid to Integer" do
66+
pid = MockObject.new('mock-enumerable')
67+
pid.should_receive(:to_int).and_return(100500)
6668

67-
Process.detach(pid).join
68-
end
69+
Process.detach(pid).join
70+
end
6971

70-
it "raises TypeError when pid argument does not have #to_int method" do
71-
-> { Process.detach(Object.new) }.should.raise(TypeError, "no implicit conversion of Object into Integer")
72-
end
72+
it "raises TypeError when pid argument does not have #to_int method" do
73+
-> { Process.detach(Object.new) }.should.raise(TypeError, "no implicit conversion of Object into Integer")
74+
end
7375

74-
it "raises TypeError when #to_int returns non-Integer value" do
75-
pid = MockObject.new('mock-enumerable')
76-
pid.should_receive(:to_int).and_return(:symbol)
76+
it "raises TypeError when #to_int returns non-Integer value" do
77+
pid = MockObject.new('mock-enumerable')
78+
pid.should_receive(:to_int).and_return(:symbol)
7779

78-
-> { Process.detach(pid) }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_int gives Symbol)")
79-
end
80+
-> { Process.detach(pid) }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_int gives Symbol)")
8081
end
8182
end

core/process/wait2_spec.rb

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
require_relative '../../spec_helper'
2+
require_relative 'fixtures/common'
23

34
describe "Process.wait2" do
5+
ProcessSpecs.use_system_ruby(self)
6+
47
before :all do
58
# HACK: this kludge is temporarily necessary because some
69
# misbehaving spec somewhere else does not clear processes
@@ -18,15 +21,13 @@
1821
end
1922
end
2023

21-
platform_is_not :windows do
22-
it "returns the pid and status of child process" do
23-
pidf = Process.fork { Process.exit! 99 }
24-
results = Process.wait2
25-
results.size.should == 2
26-
pidw, status = results
27-
pidf.should == pidw
28-
status.exitstatus.should == 99
29-
end
24+
it "returns the pid and status of child process" do
25+
pidf = Process.spawn(*ruby_exe, "-e", "exit 99")
26+
results = Process.wait2
27+
results.size.should == 2
28+
pidw, status = results
29+
pidf.should == pidw
30+
status.exitstatus.should == 99
3031
end
3132

3233
it "raises a StandardError if no child processes exist" do

core/process/wait_spec.rb

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@
1717
-> { Process.wait }.should.raise(Errno::ECHILD)
1818
end
1919

20-
platform_is_not :windows do
21-
it "returns its child pid" do
22-
pid = Process.spawn(ruby_cmd('exit'))
23-
Process.wait.should == pid
24-
end
20+
it "returns its child pid" do
21+
pid = Process.spawn(ruby_cmd('exit'))
22+
Process.wait.should == pid
23+
end
2524

26-
it "sets $? to a Process::Status" do
27-
pid = Process.spawn(ruby_cmd('exit'))
28-
Process.wait
29-
$?.should.is_a?(Process::Status)
30-
$?.pid.should == pid
31-
end
25+
it "sets $? to a Process::Status" do
26+
pid = Process.spawn(ruby_cmd('exit'))
27+
Process.wait
28+
$?.should.is_a?(Process::Status)
29+
$?.pid.should == pid
30+
end
3231

32+
platform_is_not :windows do
3333
it "waits for any child process if no pid is given" do
3434
pid = Process.spawn(ruby_cmd('exit'))
3535
Process.wait.should == pid
@@ -59,8 +59,10 @@
5959
Process.wait(0).should == pid2
6060
Process.wait.should == pid1
6161
end
62+
end
6263

63-
# This spec is probably system-dependent.
64+
# This spec is probably system-dependent.
65+
guard -> { Process.respond_to?(:fork) } do
6466
it "doesn't block if no child is available when WNOHANG is used" do
6567
read, write = IO.pipe
6668
pid = Process.fork do
@@ -81,7 +83,9 @@
8183
Process.kill("TERM", pid)
8284
Process.wait.should == pid
8385
end
86+
end
8487

88+
platform_is_not :windows do
8589
it "always accepts flags=0" do
8690
pid = Process.spawn(ruby_cmd('exit'))
8791
Process.wait(-1, 0).should == pid

core/process/waitall_spec.rb

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
require_relative '../../spec_helper'
2+
require_relative 'fixtures/common'
23

34
describe "Process.waitall" do
5+
ProcessSpecs.use_system_ruby(self)
6+
47
before :all do
58
begin
69
Process.waitall
@@ -17,23 +20,16 @@
1720
end
1821

1922
platform_is_not :windows do
20-
it "waits for all children" do
23+
it "waits for all children and returns an array of pid/status pairs" do
2124
pids = []
22-
pids << Process.fork { Process.exit! 2 }
23-
pids << Process.fork { Process.exit! 1 }
24-
pids << Process.fork { Process.exit! 0 }
25-
Process.waitall
25+
pids << Process.spawn(ruby_cmd('exit 2'))
26+
pids << Process.spawn(ruby_cmd('exit 1'))
27+
pids << Process.spawn(ruby_cmd('exit 0'))
28+
a = Process.waitall
2629
pids.each { |pid|
2730
-> { Process.kill(0, pid) }.should.raise(Errno::ESRCH)
2831
}
29-
end
3032

31-
it "returns an array of pid/status pairs" do
32-
pids = []
33-
pids << Process.fork { Process.exit! 2 }
34-
pids << Process.fork { Process.exit! 1 }
35-
pids << Process.fork { Process.exit! 0 }
36-
a = Process.waitall
3733
a.should.is_a?(Array)
3834
a.size.should == 3
3935
pids.each { |pid|

0 commit comments

Comments
 (0)