Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Process spawn should not raise NoMethodError when true argument is given to :pgroup #1895

Merged
merged 2 commits into from

2 participants

@LTe

No description provided.

spec/ruby/shared/process/spawn.rb
@@ -268,6 +268,10 @@
it "raises an ArgumentError if given a negative :pgroup option" do
lambda { @object.spawn("echo", :pgroup => -1) }.should raise_error(ArgumentError)
end
+
+ it "does not raises an NoMethodError if given a true :pgroup option" do
+ lambda { @object.spawn("echo -n", :pgroup => true) }.should_not raise_error(NoMethodError)
@dbussink Owner

We should try to spec behavior here as how it should work, not that it shouldn't raise an exception. So that means we should specify here that it creates a new pgroup.

In general, any spec that says "should not raise an exception" is almost always a wrong spec.

@LTe
LTe added a note

I update pull request. And spec about "should not raise and exception" can be good: LTe@a16eeac#L0R272 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@LTe

Process.spawn("ls", :pgroup => :true) should raise TypeError.
I updated specs with pgroup. Specs checks now that process executed in new group and also executed (print pid to STDOUT).

@LTe

Pass on travis but rake raise

/home/travis/builds/rubinius/rubinius/Rakefile:131:in `exit': no implicit conversion from nil to integer (TypeError)
2483    from /home/travis/builds/rubinius/rubinius/Rakefile:131:in `block in set_at_exit_handler'`

On my localhost:
3891 files, 21911 examples, 142349 expectations, 0 failures, 0 errors

spec/ruby/shared/process/spawn.rb
@@ -268,6 +268,10 @@
it "raises an ArgumentError if given a negative :pgroup option" do
lambda { @object.spawn("echo", :pgroup => -1) }.should raise_error(ArgumentError)
end
+
+ it "does not raises an TypeError if given a true :pgroup option" do
@dbussink Owner

Looks like this description is wrong. It raises an exception and the description says otherwise.

@LTe
LTe added a note

Good point!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
kernel/common/process19.rb
@@ -73,7 +73,12 @@ def self.adjust_options(options)
when :in, :out, :err, Fixnum, IO
redirects[key] = adjust_redirect_value(key, value)
when :pgroup
- raise ArgumentError, "negative process group ID : #{value}" if value && value < 0
+ if value.kind_of?(Integer) && value < 0
+ raise ArgumentError, "negative process group ID : #{value}"
+ elsif value.kind_of?(Symbol)
+ raise TypeError, "can't convert Symbol into Integer"
@dbussink Owner

It feels to me as what MRI does here is a standard Ruby coercion protocol to Integer. Looks like we need to do that too here, instead of just having a special case for Symbol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@LTe

It feels to me as what MRI does here is a standard Ruby coercion protocol to Integer. Looks like we need to do that too here, instead of just having a special case for Symbol.

We need to consider several options

  • pgroup is true
  • pgroup is positive Integer
  • pgroup is negative Integer
  • pgroup is nil
  • pgroup is false

I moved a little bit of logic from this place to this place

Now when pgroup is true we set pgroup value to 0. Method coerce_to create once again 0 and set value. When pgroup is false or nil this value will set and default behavior will execute because of that. If pgroup will be Integer negative Rubinius will raise argument error because of that. If pgroup will be positive Integer everything will be normal.

@dbussink what do you think?

kernel/common/process19.rb
@@ -73,6 +73,8 @@ def self.adjust_options(options)
when :in, :out, :err, Fixnum, IO
redirects[key] = adjust_redirect_value(key, value)
when :pgroup
+ value = 0 if value == true
+ value = Rubinius::Type.coerce_to value, Integer, :to_int if value
raise ArgumentError, "negative process group ID : #{value}" if value && value < 0
@dbussink Owner

Looks like we have multiple if value checks here. What is the behavior when value is nil? We should try to only have to this check once probably.

@LTe
LTe added a note

When pgroup is nil or false process group will not create.

@LTe
LTe added a note

@dbussink we can do something like that:

value = 0 if value == true
if value
  value = Rubinius::Type.coerce_to value, Integer, :to_int 
  raise ArgumentError, "negative process group ID : #{value}" if value < 0
end
@dbussink Owner

How about something like this?

if value == true
  value = 0
elsif value
  value = Rubinius::Type.coerce_to value, Integer, :to_int 
  raise ArgumentError, "negative process group ID : #{value}" if value < 0
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
LTe added some commits
@LTe LTe Add spec for Process.spawn
When user execute method with :pgroup => true Rubinius tried to use '<'
method on TrueClass object. It will throw an exception NoMethotError.

Process.spawn executed with :pgroup => Symbol should raise TypeError
cdc63e1
@LTe LTe Change extract pgroup value
Cases:
1. pgroup value is 'true' => 0
2. pgroup value is kind of true => Rubinius will try coerce_to Integer
3. pgroup value if kind of true and pass coerce then Rubinius will check
check whether the value is < 0. If yes then an ArgumentError exception is thrown
4. pgroup if kind of false (false, nil) - default behavior (like without
pgroup)

Fixes #1894
848849d
@dbussink dbussink merged commit 5aea289 into rubinius:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 22, 2012
  1. @LTe

    Add spec for Process.spawn

    LTe authored
    When user execute method with :pgroup => true Rubinius tried to use '<'
    method on TrueClass object. It will throw an exception NoMethotError.
    
    Process.spawn executed with :pgroup => Symbol should raise TypeError
  2. @LTe

    Change extract pgroup value

    LTe authored
    Cases:
    1. pgroup value is 'true' => 0
    2. pgroup value is kind of true => Rubinius will try coerce_to Integer
    3. pgroup value if kind of true and pass coerce then Rubinius will check
    check whether the value is < 0. If yes then an ArgumentError exception is thrown
    4. pgroup if kind of false (false, nil) - default behavior (like without
    pgroup)
    
    Fixes #1894
This page is out of date. Refresh to see the latest.
Showing with 19 additions and 10 deletions.
  1. +6 −1 kernel/common/process19.rb
  2. +13 −9 spec/ruby/shared/process/spawn.rb
View
7 kernel/common/process19.rb
@@ -73,7 +73,12 @@ def self.adjust_options(options)
when :in, :out, :err, Fixnum, IO
redirects[key] = adjust_redirect_value(key, value)
when :pgroup
- raise ArgumentError, "negative process group ID : #{value}" if value && value < 0
+ if value == true
+ value = 0
+ elsif value
+ value = Rubinius::Type.coerce_to value, Integer, :to_int
+ raise ArgumentError, "negative process group ID : #{value}" if value < 0
+ end
others[key] = value
when :chdir
others[key] = Rubinius::Type.coerce_to_path(value)
View
22 spec/ruby/shared/process/spawn.rb
@@ -242,21 +242,21 @@
end
it "joins a new process group if :pgroup => true" do
- lambda do
+ process = lambda do
Process.wait @object.spawn(ruby_cmd("print Process.getpgid(Process.pid)"), :pgroup => true)
- end.should_not output_to_fd(Process.getpgid(Process.pid).to_s)
- end
+ end
- it "joins a new process group if :pgroup => :true" do
- lambda do
- Process.wait @object.spawn(ruby_cmd("print Process.getpgid(Process.pid)"), :pgroup => :true)
- end.should_not output_to_fd(Process.getpgid(Process.pid).to_s)
+ process.should_not output_to_fd(Process.getpgid(Process.pid).to_s)
+ process.should output_to_fd(/\d+/)
end
it "joins a new process group if :pgroup => 0" do
- lambda do
+ process = lambda do
Process.wait @object.spawn(ruby_cmd("print Process.getpgid(Process.pid)"), :pgroup => 0)
- end.should_not output_to_fd(Process.getpgid(Process.pid).to_s)
+ end
+
+ process.should_not output_to_fd(Process.getpgid(Process.pid).to_s)
+ process.should output_to_fd(/\d+/)
end
it "joins the specified process group if :pgroup => pgid" do
@@ -268,6 +268,10 @@
it "raises an ArgumentError if given a negative :pgroup option" do
lambda { @object.spawn("echo", :pgroup => -1) }.should raise_error(ArgumentError)
end
+
+ it "raises an TypeError if given a symbol as :pgroup option" do
+ lambda { @object.spawn("echo", :pgroup => :true) }.should raise_error(TypeError)
+ end
end
platform_is :windows do
Something went wrong with that request. Please try again.