puffing-billy
puffing-billy copied to clipboard
eventmachine not initialized - proxy isn't working
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:
@knagode can you try running on the branch in this PR and see if it works? https://github.com/oesmith/puffing-billy/pull/251
@knagode I tried but it didn't help. Other ideas maybe?
Looks like someone had a similar issue a couple years ago: https://github.com/oesmith/puffing-billy/issues/43#issuecomment-256453041
this seems to be related to https://github.com/oesmith/puffing-billy/pull/239 but I can't understand how exactly
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
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?
In this example, what do you expect WebMock to do and what do you expect PuffingBilly to do?
@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 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 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?
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.
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.
Have you tried the suggestions in that linked issue? Happy to accept a PR with README changes that document it better.
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)
Just updated eventmachine in 1.1.3. Please try it out and see if this issue persists.
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)>'
@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!
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
.
@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!
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)
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 install
ing 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 thanks for your patch, which apparently removes the error in my case too.
@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
Happy to accept a PR with that patch (and tests) if someone wants to put one up.
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
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.