Skip to content
Merged
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
2 changes: 1 addition & 1 deletion core/io/foreach_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
ScratchPad.recorded.should == ["hello\n", "line2\n"]
end

platform_is_not :windows do
guard -> { Process.respond_to?(:fork) } do
it "gets data from a fork when passed -" do
parent_pid = $$

Expand Down
2 changes: 1 addition & 1 deletion core/io/read_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
end
end

platform_is_not :windows do
guard -> { Process.respond_to?(:fork) } do
it "opens a pipe to a fork if the rest is -" do
str = nil
suppress_warning do # https://bugs.ruby-lang.org/issues/19630
Expand Down
2 changes: 1 addition & 1 deletion core/io/readlines_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@
lines.should == ["hello\n", "line2\n"]
end

platform_is_not :windows do
guard -> { Process.respond_to?(:fork) } do
it "gets data from a fork when passed -" do
lines = nil
suppress_warning do # https://bugs.ruby-lang.org/issues/19630
Expand Down
15 changes: 10 additions & 5 deletions core/process/daemon_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'

platform_is_not :windows do
# macOS 15 is not working this examples
return if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`

guard -> {
Process.respond_to?(:fork) and
# macOS 15 is not working for these examples
!(/darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion`)
} do
describe :process_daemon_keep_stdio_open_false, shared: true do
it "redirects stdout to /dev/null" do
@daemon.invoke("keep_stdio_open_false_stdout", @object).should == ""
Expand Down Expand Up @@ -107,8 +108,12 @@
end
end

platform_is :windows do
guard_not -> { Process.respond_to?(:fork) } do
describe "Process.daemon" do
it "returns false from #respond_to?" do
Process.respond_to?(:daemon).should == false
end

it "raises a NotImplementedError" do
-> {
Process.daemon
Expand Down
119 changes: 60 additions & 59 deletions core/process/detach_spec.rb
Original file line number Diff line number Diff line change
@@ -1,81 +1,82 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'

describe "Process.detach" do
platform_is_not :windows do
it "returns a thread" do
pid = Process.fork { Process.exit! }
thr = Process.detach(pid)
thr.should.is_a?(Thread)
thr.join
end
ProcessSpecs.use_system_ruby(self)

it "produces the exit Process::Status as the thread value" do
pid = Process.fork { Process.exit! }
thr = Process.detach(pid)
thr.join
it "returns a thread" do
pid = Process.spawn(*ruby_exe, "-e", "exit")
thr = Process.detach(pid)
thr.should.is_a?(Thread)
thr.join
end

status = thr.value
status.should.is_a?(Process::Status)
status.pid.should == pid
end
it "produces the exit Process::Status as the thread value" do
pid = Process.spawn(*ruby_exe, "-e", "exit")
thr = Process.detach(pid)
thr.join

status = thr.value
status.should.is_a?(Process::Status)
status.pid.should == pid
end

platform_is_not :openbsd do
it "reaps the child process's status automatically" do
pid = Process.fork { Process.exit! }
Process.detach(pid).join
-> { Process.waitpid(pid) }.should.raise(Errno::ECHILD)
end
platform_is_not :openbsd do
it "reaps the child process's status automatically" do
pid = Process.spawn(*ruby_exe, "-e", "exit")
Process.detach(pid).join
-> { Process.waitpid(pid) }.should.raise(Errno::ECHILD)
end
end

it "sets the :pid thread-local to the PID" do
pid = Process.fork { Process.exit! }
thr = Process.detach(pid)
thr.join
it "sets the :pid thread-local to the PID" do
pid = Process.spawn(*ruby_exe, "-e", "exit")
thr = Process.detach(pid)
thr.join

thr[:pid].should == pid
end
thr[:pid].should == pid
end

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

thr.pid.should == pid
end
thr.pid.should == pid
end

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

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

thr = Process.detach(pid_not_existing)
thr.join
thr = Process.detach(pid_not_existing)
thr.join

thr.should.is_a?(Thread)
end
thr.should.is_a?(Thread)
end

it "calls #to_int to implicitly convert non-Integer pid to Integer" do
pid = MockObject.new('mock-enumerable')
pid.should_receive(:to_int).and_return(100500)
it "calls #to_int to implicitly convert non-Integer pid to Integer" do
pid = MockObject.new('mock-enumerable')
pid.should_receive(:to_int).and_return(100500)

Process.detach(pid).join
end
Process.detach(pid).join
end

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

it "raises TypeError when #to_int returns non-Integer value" do
pid = MockObject.new('mock-enumerable')
pid.should_receive(:to_int).and_return(:symbol)
it "raises TypeError when #to_int returns non-Integer value" do
pid = MockObject.new('mock-enumerable')
pid.should_receive(:to_int).and_return(:symbol)

-> { Process.detach(pid) }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_int gives Symbol)")
end
-> { Process.detach(pid) }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_int gives Symbol)")
end
end
2 changes: 1 addition & 1 deletion core/process/setpgid_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'

describe "Process.setpgid" do
platform_is_not :windows do
guard -> { Process.respond_to?(:fork) } do
# Must use fork as setpgid(2) gives EACCESS after execve()
it "sets the process group id of the specified process" do
rd, wr = IO.pipe
Expand Down
2 changes: 1 addition & 1 deletion core/process/setpgrp_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# TODO: put these in the right files.
describe "Process.setpgrp and Process.getpgrp" do
platform_is_not :windows do
guard -> { Process.respond_to?(:fork) } do
it "sets and gets the process group ID of the calling process" do
# there are two synchronization points here:
# One for the child to let the parent know that it has finished
Expand Down
36 changes: 19 additions & 17 deletions core/process/status/wait_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,27 @@
end

# This spec is probably system-dependent.
it "doesn't block if no child is available when WNOHANG is used" do
read, write = IO.pipe
pid = Process.fork do
read.close
Signal.trap("TERM") { Process.exit! }
write << 1
guard -> { Process.respond_to?(:fork) } do
it "doesn't block if no child is available when WNOHANG is used" do
read, write = IO.pipe
pid = Process.fork do
read.close
Signal.trap("TERM") { Process.exit! }
write << 1
write.close
sleep
end

Process::Status.wait(pid, Process::WNOHANG).should == nil

# wait for the child to setup its TERM handler
write.close
sleep
end

Process::Status.wait(pid, Process::WNOHANG).should == nil

# wait for the child to setup its TERM handler
write.close
read.read(1)
read.close
read.read(1)
read.close

Process.kill("TERM", pid)
Process::Status.wait.pid.should == pid
Process.kill("TERM", pid)
Process::Status.wait.pid.should == pid
end
end

it "always accepts flags=0" do
Expand Down
19 changes: 10 additions & 9 deletions core/process/wait2_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'

describe "Process.wait2" do
ProcessSpecs.use_system_ruby(self)

before :all do
# HACK: this kludge is temporarily necessary because some
# misbehaving spec somewhere else does not clear processes
Expand All @@ -18,15 +21,13 @@
end
end

platform_is_not :windows do
it "returns the pid and status of child process" do
pidf = Process.fork { Process.exit! 99 }
results = Process.wait2
results.size.should == 2
pidw, status = results
pidf.should == pidw
status.exitstatus.should == 99
end
it "returns the pid and status of child process" do
pidf = Process.spawn(*ruby_exe, "-e", "exit 99")
results = Process.wait2
results.size.should == 2
pidw, status = results
pidf.should == pidw
status.exitstatus.should == 99
end

it "raises a StandardError if no child processes exist" do
Expand Down
28 changes: 16 additions & 12 deletions core/process/wait_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
-> { Process.wait }.should.raise(Errno::ECHILD)
end

platform_is_not :windows do
it "returns its child pid" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait.should == pid
end
it "returns its child pid" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait.should == pid
end

it "sets $? to a Process::Status" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait
$?.should.is_a?(Process::Status)
$?.pid.should == pid
end
it "sets $? to a Process::Status" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait
$?.should.is_a?(Process::Status)
$?.pid.should == pid
end

platform_is_not :windows do
it "waits for any child process if no pid is given" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait.should == pid
Expand Down Expand Up @@ -59,8 +59,10 @@
Process.wait(0).should == pid2
Process.wait.should == pid1
end
end

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

platform_is_not :windows do
it "always accepts flags=0" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait(-1, 0).should == pid
Expand Down
20 changes: 8 additions & 12 deletions core/process/waitall_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'

describe "Process.waitall" do
ProcessSpecs.use_system_ruby(self)

before :all do
begin
Process.waitall
Expand All @@ -17,23 +20,16 @@
end

platform_is_not :windows do
it "waits for all children" do
it "waits for all children and returns an array of pid/status pairs" do
pids = []
pids << Process.fork { Process.exit! 2 }
pids << Process.fork { Process.exit! 1 }
pids << Process.fork { Process.exit! 0 }
Process.waitall
pids << Process.spawn(ruby_cmd('exit 2'))
pids << Process.spawn(ruby_cmd('exit 1'))
pids << Process.spawn(ruby_cmd('exit 0'))
a = Process.waitall
pids.each { |pid|
-> { Process.kill(0, pid) }.should.raise(Errno::ESRCH)
}
end

it "returns an array of pid/status pairs" do
pids = []
pids << Process.fork { Process.exit! 2 }
pids << Process.fork { Process.exit! 1 }
pids << Process.fork { Process.exit! 0 }
a = Process.waitall
a.should.is_a?(Array)
a.size.should == 3
pids.each { |pid|
Expand Down
Loading
Loading