class RSpec::Parallel::Runner

Attributes

args[R]

@return [Array<String>]

master[R]

@return [RSpec::Parallel::Master]

pids[R]

@return [Array<Integer>] array of pids of spawned worker processes

Public Class Methods

new(args) click to toggle source

@param args [Array<String>] command line arguments

# File lib/rspec/parallel/runner.rb, line 13
def initialize(args)
  @args = args
  @pids = []

  # Configure RSpec core before initialize master instance and spawning
  # worker processes to share its configuration.
  configure_rspec
  @master = Master.new(args)
end

Public Instance Methods

start() click to toggle source

@return [Integer] exit status code

# File lib/rspec/parallel/runner.rb, line 24
def start
  waiters = []
  RSpec::Parallel.configuration.concurrency.times do
    waiters << spawn_worker
  end
  master.run
  statuses = waiters.map {|waiter| waiter.value }
  statuses.all? {|status| status.success? } ? 0 : 1
ensure
  pids.each.with_index do |pid, index|
    puts "----> output from worker[#{index}]"
    File.open(output_file_path(pid)) do |file|
      puts file.read
    end
  end
end

Private Instance Methods

configure_rspec() click to toggle source
# File lib/rspec/parallel/runner.rb, line 78
def configure_rspec
  options = ::RSpec::Core::ConfigurationOptions.new(args)
  options.configure(::RSpec.configuration)
end
output_file_path(pid) click to toggle source

@param pid [Integer] @return [String]

# File lib/rspec/parallel/runner.rb, line 74
def output_file_path(pid)
  "/tmp/parallel-rspec-worker-#{pid}"
end
spawn_worker() click to toggle source

@param master [RSpec::Parallel::Master]

# File lib/rspec/parallel/runner.rb, line 50
def spawn_worker
  pid = Kernel.fork do
    master.close

    exit_code = File.open(output_file_path($PID), "w") do |file|
      # Redirect stdout and stderr to temp file
      STDOUT.reopen(file)
      STDERR.reopen(STDOUT)
      STDOUT.sync = STDERR.sync = true

      worker = Worker.new(master, pids.size)
      $0 = "parallel-rspec worker [#{worker.number}]"
      RSpec::Parallel.configuration.after_fork_block.call(worker)
      worker.run
    end

    Kernel.exit!(exit_code == 0) # avoid running any `at_exit` functions.
  end
  pids << pid
  Process.detach(pid)
end