This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :docker do | |
desc "Run tasks in parallel using docker" | |
task :test do | |
forks = 4 | |
begin | |
# Start docker containers (serially, docker seems to have problems with concurrency) | |
ports = {} | |
forks.times do |i| | |
# Start redis and get the mapped port | |
`docker run -d -p 6379 -name redis#{i} yourdockeruser/redis` | |
ports["redis#{i}"] = `docker port redis#{i} 6379`.split(":").last.to_i | |
# Start solr and get the mapped port | |
`docker run -d -p 8983 -name solr#{i} yourdockeruser/solr` | |
ports["solr#{i}"] = `docker port solr#{i} 8983`.split(":").last.to_i | |
end | |
# Wait for services in the docker container to start | |
sleep(15) | |
# Randomize which forks get which tests | |
test_files = FileList['test/**/test*.rb'].shuffle | |
# Slice the test files to evenly distribute amongst forks | |
test_files_sliced = test_files.each_slice(test_files.length / forks).to_a | |
pids = [] | |
forks.times do |i| | |
pids << fork do | |
begin | |
## | |
# Configure your environment | |
# You'll want to do something here to make the environment | |
# use the redis_port and solr_port variables from above. | |
# This may be calling something like Rails::Initializer.run(). | |
# You can access the ports by using the ports hash: | |
# config.redis_port = ports["redis#{i}"] | |
# If you use a base test class, require that first | |
require_relative "test/test_case" | |
# Require the test files for this particular fork | |
test_files_sliced[i].each {|f| require_relative f} | |
# redirect stdout | |
require 'stringio' | |
sio = StringIO.new | |
$stdout = sio | |
$stderr = sio | |
# Run the tests | |
MiniTest::Unit.runner.run | |
rescue => e | |
sio << "\n#{e.message}\n#{e.backtrace.join("\t\n")}" | |
ensure | |
# reset stdout | |
$stdout = STDOUT | |
sio.rewind | |
# Output the test results | |
puts "Fork #{i} completed, output:" | |
puts "Testing:\n#{test_files_sliced[i].join(", ")}\n" | |
puts sio.read | |
# Force the fork to end without running at_exit bindings | |
Kernel.exit! | |
end | |
end | |
end | |
# Wait for the forks to finish the tests | |
pids.each {|pid| Process.wait(pid)} | |
rescue Exception => e | |
puts e.message | |
puts e.backtrace.join("\n\t") | |
ensure | |
puts "Stopping docker containers" | |
forks.times {|i| `docker kill redis#{i} && docker rm redis#{i}`} | |
forks.times {|i| `docker kill solr#{i} && docker rm solr#{i}`} | |
Kernel.exit! # force the process to quit without minitest's autorun (triggered on at_exit) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment