rubycdp / cuprite

Headless Chrome/Chromium driver for Capybara
https://cuprite.rubycdp.com
MIT License
1.24k stars 93 forks source link

Process forking causing cuprite/ferrum to never exit #231

Open tekin opened 1 year ago

tekin commented 1 year ago

Here's a scenario where cuprite/ferrum does not exit and the test hangs indefinitely. We've written some concurrency/race-condition tests in our application that involves forking processes. This is resulting in our test suite hanging, and it looks like it may be related to cuprite/ferrum not stopping the browser process. Here is a simple reproduction case:

require "test_helper"
require "capybara/cuprite"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :cuprite

  test "forking processes creates a non-exiting test" do
    process_pids = [1,2].map do |count|
      Process.fork {
        puts "Working #{count}"
        sleep(1)
        puts "Done #{count}"
        exit!
      }
    end

    puts "PIDS are #{process_pids}"
    process_pids.each { |pid| Process.waitpid(pid) }
    puts "Done waiting"

    visit "/"
  end
end

When run this will not exit. I can see that the Chrome browser process is still active in my activity monitor. If I kill the browser, the runner exits.

Note this repro case is in test-unit, but we're seeing this issue in RSpec with the process forking happening in a model spec entirely separate from any cuprite-driven feature specs.

templeman15 commented 1 year ago

Same thing happens to me.. Here's what I did to kill the pid at least until we can figure out what needs to get updated in cuprite.

Capybara / Cuprite / RSpec

RSpec.configure do |config|
  config.before(:suite) do
   # List all process using the port that we're about to use
   pid_output = `lsof -i tcp:#{9500 + ENV['TEST_ENV_NUMBER'].to_i} | awk 'NR!=1 {print $2}'`

   # Kill those processes if any were found
   system("echo '#{pid_output}' | xargs kill -9") unless pid_output.strip.empty?
 end
end