Shouldn't rely on result value returned by DRb to be implicitly convertible to integer #382

Merged
merged 1 commit into from May 21, 2011

Projects

None yet

5 participants

@jscheid
jscheid commented May 21, 2011

Hi there,

this fixes a problem that occurs when using rspec 2.6.1 together with spork 0.9.0.rc (and possibly other versions). I am mystified why apparently nobody else is running into this issue, but I can reproduce it like so:

  • Run spork 0.9.0.rc in rspec mode (on a sporkified rails 3 app in my case)
  • Run latest rspec with the --drb flag on any old test

Everything works fine, but a "TypeError: can't convert DRb::DRbObject into Integer" will be raised at the very end. Not a big problem but definitely irritating as it makes it harder to see rspec's "X examples, Y failures" output.

I've had a look at both rspec and spork code and here's what I think happens. Spork runs the tests in a forked child process and marshals/unmarshals the test result (an integer in rspec's case) via an IO object to bridge the parent/child process boundary, then passes the IO object back to rspec proxied by a DRb::DRbObject. The combination of DRbObject and IO object prevents an implicit conversion to integer, causing the TypeError to be raised.

At first I was thinking of fixing this issue in spork code, however this is tricky due to spork's generic architecture. Casting the IO object to an integer or even just a string on the spork side of things feels like it's taking away from spork's genericalness. For example, as far as I can tell it would preclude other spork clients from lazy-loading or incrementally loading a large result value.

In comparison, this fix appears to be straightforward and unintrusive, and in line with Postel's Law. Do you agree?

I thought about including a test case but due to the problem occurring at the shell/rspec process boundary under only very specific circumstances I found it hard to come up with a concise one that doesn't complicate things unnecessarily. If you insist on having a test, could somebody give me a hand with it?

Julian Scheid Explicitly convert exit code to integer, avoiding TypeError when retu…
…rn value of run is IO object proxied by DRb::DRbObject
0998854
@dchelimsky
Member

What ruby version are you running?

@dchelimsky dchelimsky merged commit c4427b7 into rspec:master May 21, 2011
@jscheid
jscheid commented May 21, 2011

Thanks for merging this.

FWIW I am running JRuby 1.6.1 but I verified Ruby 1.8 and 1.9 to barf in the same way when int-in-IO-in-DRbObject is passed to exit().

@molfar
molfar commented Jun 29, 2013

Still have this problem. Using latest
gem 'rspec-rails', git: 'git://github.com/rspec/rspec-rails.git'
gem 'rspec-mocks', git: 'git://github.com/rspec/rspec-mocks.git'

and get error message
Exception encountered:
TypeError: can't convert DRb::DRbObject to Integer (DRb::DRbObject to_int gives DRb::DRbObject)
backtrace:
(druby://localhost:52358) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:375:in `_id2ref'

@alindeman
Contributor

Can you paste the full backtrace?

@molfar
molfar commented Jun 29, 2013

iMac:my_project molfar$ bundle exec spork
Using RSpec, Rails
Preloading Rails environment
Loading Spork.prefork block...
Spork is ready and listening on 8989!
Running tests with args ["--color", "--format", "documentation", "spec/controllers/"]...
Exception encountered: #<TypeError: can't convert DRb::DRbObject to Integer (DRb::DRbObject#to_int gives DRb::DRbObject)>
backtrace:
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:375:in _id2ref' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:375:into_obj'
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1410:in to_obj' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1708:into_obj'
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:613:in recv_request' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:908:inrecv_request'
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1523:in init_with_client' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1535:insetup_message'
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1487:in perform' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1586:inblock (2 levels) in main_loop'
(druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1582:in loop' (druby://localhost:52915) /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1582:inblock in main_loop'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1074:in respond_to?' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/run_strategy/forking.rb:10:inblock in run'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/forker.rb:21:in block in initialize' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/forker.rb:18:infork'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/forker.rb:18:in initialize' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/run_strategy/forking.rb:9:innew'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/run_strategy/forking.rb:9:in run' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/spork-1.0.0rc3/lib/spork/server.rb:48:inrun'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1548:in perform_without_block' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1508:inperform'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1586:in block (2 levels) in main_loop' /Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1582:inloop'
/Users/molfar/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/drb/drb.rb:1582:in `block in main_loop'
Done.

@alindeman
Contributor

RSpec isn't in that backtrace. I'm not sure where to start looking. Maybe it's more of a spork issue?

@molfar
molfar commented Jun 29, 2013

Issue num.1
Using rspec-core (2.14.0.rc1)
Using rspec-expectations (2.14.0.rc1)
Using rspec-mocks (2.14.0.rc1)
Using rspec-rails (2.14.0.rc1) from git://github.com/rspec/rspec-rails.git (at master)

-->> Spork runs ok, but when I run rspec spec/ --drb - I have no output at all. But spork shows that tests had been running. With --no-drb - everything works ok.

Issue num.2
Using rspec-core (2.14.0.rc1)
Using rspec-expectations (2.14.0.rc1)
Using rspec-mocks (2.14.0.rc1) from git://github.com/rspec/rspec-mocks.git (at master)
Using rspec-rails (2.14.0.rc1) from git://github.com/rspec/rspec-rails.git (at master)

-->> The same no output from rspec spec/ --drb. But spork at this time shows error Exception encountered: TypeError: can't convert DRb::DRbObject to Integer (DRb::DRbObject to_int gives DRb::DRbObject). Without drb everything is ok again.

No output means
iMac:proj molfar$ bundle exec rspec spec/
iMac:proj molfar$

@myronmarston
Member

This sounds like the other drb issue reported this week. It was an issue with rspec-mocks' marshal extension. There's a fix for it in an rspec-mocks PR. I'd include links but I'm on my phone.

Sent from my iPhone

On Jun 29, 2013, at 1:37 PM, molfar notifications@github.com wrote:

Issue num.1
Using rspec-core (2.14.0.rc1)
Using rspec-expectations (2.14.0.rc1)
Using rspec-mocks (2.14.0.rc1)
Using rspec-rails (2.14.0.rc1) from git://github.com/rspec/rspec-rails.git (at master)

-->> Spork runs ok, but when I run rspec spec/ --drb - I have no output at all. But spork shows that tests had been running. With --no-drb - everything works ok.

Issue num.2
Using rspec-core (2.14.0.rc1)
Using rspec-expectations (2.14.0.rc1)
Using rspec-mocks (2.14.0.rc1) from git://github.com/rspec/rspec-mocks.git (at master)
Using rspec-rails (2.14.0.rc1) from git://github.com/rspec/rspec-rails.git (at master)

-->> The same no output from rspec spec/ --drb. But spork at this time shows error Exception encountered: TypeError: can't convert DRb::DRbObject to Integer (DRb::DRbObject to_int gives DRb::DRbObject). Without drb everything is ok too.


Reply to this email directly or view it on GitHub.

@molfar
molfar commented Jun 30, 2013

I saw that pull request. And yes, branch fix-rspec-core-issue-950 fixes the issue. DRB error has gone away. But why that patch isnt in maaster branch yet?

@myronmarston
Member

We were trying to figure out how to test it to prevent future regressions.

Sent from my iPhone

On Jun 29, 2013, at 9:07 PM, molfar notifications@github.com wrote:

I saw that pull request. And yes, branch fix-rspec-core-issue-950 fixes the issue. DRB error has gone away. But why that patch isnt in maaster branch yet?


Reply to this email directly or view it on GitHub.

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