Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Last active December 30, 2015 12:49
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tenderlove/7831239 to your computer and use it in GitHub Desktop.
Save tenderlove/7831239 to your computer and use it in GitHub Desktop.
###
# Execute tests in parallel using multiple processes. Uses DRb to communicate
# between processes over a unix socket.
gem 'minitest', '~> 5.1.0'
require 'minitest'
require 'minitest/spec'
require 'minitest/mock'
require 'drb'
require 'drb/unix'
require 'tempfile'
class AaronTest < Minitest::Test
parallelize_me!
10.times do |i|
define_method("test_#{i}") {
#p "process: #{$$}"
sleep(1); assert true
}
end
end
class ForkingExecutor
class Server
include DRb::DRbUndumped
def initialize
@queue = Queue.new
end
def record reporter, result
reporter.synchronize { reporter.record result }
end
def << o; @queue << o; end
def pop; @queue.pop; end
end
def initialize size
@size = size
@queue = Server.new
file = File.join Dir.tmpdir, Dir::Tmpname.make_tmpname('tests', 'fd')
@url = "drbunix://#{file}"
DRb.start_service @url, @queue
@pool = size.times.map {
fork {
DRb.stop_service
queue = DRbObject.new_with_uri @url
while job = queue.pop
klass = job[0]
method = job[1]
reporter = job[2]
result = Minitest.run_one_method klass, method
queue.record reporter, result
end
}
}
end
def << work; @queue << work; end
def shutdown
@size.times { @queue << nil }
@pool.each { |pid| Process.waitpid pid }
end
end
# Use N processes (N defaults to 4)
Minitest.parallel_executor = ForkingExecutor.new((ENV['N'] || 4).to_i)
Minitest.autorun
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment