puffing-billy icon indicating copy to clipboard operation
puffing-billy copied to clipboard

eventmachine not initialized - proxy isn't working

Open knagode opened this issue 6 years ago • 26 comments

I am getting this error

An error occurred in an `after(:suite)` hook.
Failure/Error: Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first

RuntimeError:
  eventmachine not initialized: evma_get_sockname
# /Users/klemennagode/.rvm/gems/ruby-2.3.7/gems/puffing-billy-1.1.2/lib/billy/proxy.rb:43:in `get_sockname'

Anyone has idea why?

My setup in rails_helper.rb:

Capybara.register_driver :chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('--lang=de')
  options.add_argument('--verbose')
  options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")

  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: options
  )
end

Capybara.javascript_driver = :chrome 

When I run test chrome looks like this:

screenshot 2018-10-17 17 20 37

knagode avatar Oct 17 '18 14:10 knagode

@knagode can you try running on the branch in this PR and see if it works? https://github.com/oesmith/puffing-billy/pull/251

ronwsmith avatar Oct 18 '18 02:10 ronwsmith

@knagode I tried but it didn't help. Other ideas maybe?

knagode avatar Oct 18 '18 15:10 knagode

Looks like someone had a similar issue a couple years ago: https://github.com/oesmith/puffing-billy/issues/43#issuecomment-256453041

ronwsmith avatar Oct 19 '18 13:10 ronwsmith

this seems to be related to https://github.com/oesmith/puffing-billy/pull/239 but I can't understand how exactly

gagalago avatar Oct 25 '18 12:10 gagalago

I tried to install it in clean project on same machine and it worked.. Apparently there is a conflict with another gem/configuration.

I removed all the spec configuration in problematic project (in files rspec_helper.rb and spec_helper.rb).

I noticed that proxy started working but still there is an error

An error occurred in an `after(:suite)` hook.
Failure/Error: Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first

knagode avatar Oct 29 '18 15:10 knagode

I found that problem is happening due to WebMock which we heavily use. I think that both gems are super useful and they should work together.

Example controller method:

  def test_page
    data = HTTParty.get('http://yahoo.com/data.json', format: :json)
    # stub code: WebMock.stub_request('http://yahoo.com/data.json').to_return(body: { data: 'fake' }.to_json, headers: {})
  
    render html: ('<html><body><b>Data=' + data.to_json + '</b> <script src="http://google.com/script.js"></script></body></html>').html_safe
    # stub code:  proxy.stub('http://google.com/script.js').and_return(:text => "document.write('Yeeeyyy')")
  end

Is there no way to make those two gems work together?

knagode avatar Oct 30 '18 13:10 knagode

In this example, what do you expect WebMock to do and what do you expect PuffingBilly to do?

ronwsmith avatar Oct 30 '18 13:10 ronwsmith

@ronwsmith Thnx for question. I would like to stub both Rails&browser based requests:

Browser specific stub (via Puffing Billy proxy):

proxy.stub('http://google.com/script.js').and_return(:text => "document.write('Yeeeyyy')")

Ruby/Rails specific stub (via WebMock) :

WebMock.stub_request('http://yahoo.com/data.json').to_return(body: { data: 'fake' }.to_json, headers: {})

I would like to block all network requests inside tests and wherever they occur by default(either on Rails or browser side). I would then whitelist/handle some specific requests via PuffiingBilly/WebMock.

knagode avatar Oct 30 '18 14:10 knagode

@knagode so it seems to work now but you still get an error in the after suite? Maybe we can just add a check to only shut it down if it's still running?

ronwsmith avatar Nov 04 '18 03:11 ronwsmith

@ronwsmith I was slowly removing gems from my repo and managed to fix eventmachine not initialized: evma_get_sockname.

In my case problem was: gem fake_stripe. Anyway I wasn't able to use Puffing Billy because it doesnt allow me to use WebMock & Chrome proxy together. Why is this not possible? Do you see that this gem would be really powerful if it would allow co-existance of both as they are both super important gems ... Do you know why exactly do they not work together? What should be changed in order to use both?

knagode avatar Jan 02 '19 12:01 knagode

Puffing-billy is a proxy itself. If you use it as the proxy in Chrome, it will work just fine. Not sure what other proxy settings you're using in Chrome or why, but as far as I know you can only use one proxy in any browser.

ronwsmith avatar Jan 03 '19 02:01 ronwsmith

dSure. PuffingBilly is proxy for browser based requests.

But if you are building app which is also making requests to external servers (e.g. requests to Stripe, Facebook Graph, etc ...) you sooner or later need something for stubbing those requests. That is why we use WebMock.

I would expect that those 2 gems would work together because they are solving 2 problems. I saw that I am not the only one who expected that this to work out of the box.

knagode avatar Jan 03 '19 09:01 knagode

Have you tried the suggestions in that linked issue? Happy to accept a PR with README changes that document it better.

ronwsmith avatar Jan 03 '19 14:01 ronwsmith

I saw the same error(eventmachine not initialized: evma_get_sockname) when using knapsackpro queue mode. It seems that knapsackpro queue mode calls after(:suite) hook multiple times on a job.

My current workaround is:

# rails_helper.rb

...

module BillyProxyPatch
  # @see https://github.com/oesmith/puffing-billy/blob/v1.1.2/lib/billy/proxy.rb#L26
  def stop
    super
    @signature = nil
  end
end

Billy::Proxy.prepend(BillyProxyPatch)

fukayatsu avatar Jan 07 '19 08:01 fukayatsu

Just updated eventmachine in 1.1.3. Please try it out and see if this issue persists.

ronwsmith avatar Jan 07 '19 22:01 ronwsmith

This issue persists on puffing-billy v1.1.3 with knapsack_pro queue mode.

An error occurred in an `after(:suite)` hook.
--
  | Failure/Error: Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first
  |  
  | RuntimeError:
  | eventmachine not initialized: evma_get_sockname
  | # /bundle/gems/puffing-billy-1.1.3/lib/billy/proxy.rb:43:in `get_sockname'
  | # /bundle/gems/puffing-billy-1.1.3/lib/billy/proxy.rb:43:in `port'
  | # /bundle/gems/puffing-billy-1.1.3/lib/billy/proxy.rb:29:in `stop'
  | # /bundle/gems/puffing-billy-1.1.3/lib/billy/init/rspec.rb:17:in `block (2 levels) in <top (required)>'
  | # /bundle/gems/knapsack_pro-1.2.0/lib/knapsack_pro/runners/queue/rspec_runner.rb:81:in `run_tests'
  | # /bundle/gems/knapsack_pro-1.2.0/lib/knapsack_pro/runners/queue/rspec_runner.rb:34:in `run'
  | # /bundle/gems/knapsack_pro-1.2.0/lib/tasks/queue/rspec.rake:6:in `block (3 levels) in <top (required)>'

fukayatsu avatar Jan 08 '19 03:01 fukayatsu

@AlanFoster can you take a look at this issue? Seems to be introduced by your PR https://github.com/oesmith/puffing-billy/pull/239 . Thanks!

ronwsmith avatar Jan 10 '19 03:01 ronwsmith

I don't want to add much noise, but we've been looking into an issue similar to this one today. Seems like eventmachine's reactor is a singleton, right? So other gems that use it could theoretically stop it before puffing-billy does? We'll work around this for now by adding a check for EM.reactor_running? before Billy::Proxy#stop and see how that goes, so just sharing in case it makes sense to add this to puffing-billy.

julioolvr avatar Jan 29 '19 16:01 julioolvr

@knagode is this still an issue for you?

@julioolvr how did that workaround work? If it works, can you submit a PR with it? Thanks!

ronwsmith avatar Jun 16 '19 01:06 ronwsmith

We haven’t had issues in a while to the point I had completely forgot about this, so I guess the workaround was a success. I’ll see if I have time to send a PR during the week, but in the meantime this is the whole code for the patch (we have it in our rails_helper.rb file)

# Patch `puffing-billy`'s proxy so that it doesn't try to stop
# eventmachine's reactor if it's not running.
module BillyProxyPatch
  def stop
    return unless EM.reactor_running?

    super
  end
end

Billy::Proxy.prepend(BillyProxyPatch)

julioolvr avatar Jun 16 '19 07:06 julioolvr

I looked a bit into opening a PR but I'm not sure how I'd write a test for it. Additionally, I had some issues bundle installing on macOS (when trying to compile capybara-webkit, apparently) and I wasn't able to build an image out of the provided Dockerfile. In any case, the change would literally be adding that guard clause with EM.reactor_running?, in case someone with the project already up and running wants to give it a try.

julioolvr avatar Jun 17 '19 14:06 julioolvr

@julioolvr thanks for your patch, which apparently removes the error in my case too.

thbar avatar Sep 23 '19 11:09 thbar

@fukayatsu You asked about the case when puffing-billy gem fails when using knapsack_pro gem in Queue Mode to run your tests in parallel on CI server. I got patch fix from one of users that was helpful:

# rails_helper.rb or spec_helper.rb

# A patch to `puffing-billy`'s proxy so that it doesn't try to stop
# eventmachine's reactor if it's not running.
module BillyProxyPatch
  def stop
    return unless EM.reactor_running?
    super
  end
end
Billy::Proxy.prepend(BillyProxyPatch)

# A patch to `puffing-billy` to start EM if it has been stopped
Billy.module_eval do
  def self.proxy
    if @billy_proxy.nil? || !(EventMachine.reactor_running? && EventMachine.reactor_thread.alive?)
      proxy = Billy::Proxy.new
      proxy.start
      @billy_proxy = proxy
    else
      @billy_proxy
    end
  end
end

if ENV["KNAPSACK_PRO_TEST_SUITE_TOKEN_RSPEC"]
  KnapsackPro::Hooks::Queue.before_queue do
    # executes before Queue Mode starts work
    Billy.proxy.start
  end

  KnapsackPro::Hooks::Queue.after_queue do
    # executes after Queue Mode finishes work
    Billy.proxy.stop
  end
end

I've updated FAQ in my docs https://github.com/KnapsackPro/knapsack_pro-ruby#how-to-configure-puffing-billy-gem-with-knapsack-pro-queue-mode

ArturT avatar Oct 08 '19 21:10 ArturT

Happy to accept a PR with that patch (and tests) if someone wants to put one up.

ronwsmith avatar Oct 27 '19 02:10 ronwsmith

I am also having the this issue when I switch to unicorn as Capybara rack server. In addition to @ArturT patch I needed to patch port_in_use?

I use both puffing-billy and webmock

module BillyProxyPatch
  def stop
    return unless EM.reactor_running?
    super
  end

  def port_in_use?(port)
    return unless EM.reactor_running?
    super
  end
end

dlozano avatar Mar 22 '21 16:03 dlozano

I have a similar problem but none of above fixes didn't work for me

following works for me

module BillyProxyPatch
  protected

  def port_in_use?(port)
    Timeout::timeout(1) do
      super
    end
  rescue Timeout::Error
    false
  end
end

Billy::Proxy.prepend(BillyProxyPatch)

because in my case TCPSocket#new hangs for 60 seconds (then timeout in wait_for_server_shutdown being called)

PS TCPSocket#new has a connection_timeout option, but we use socksify as a dependency of one of our gems which monkey patch TCPSocket and removes this option.

senid231 avatar Apr 18 '22 12:04 senid231