Skip to content

Instantly share code, notes, and snippets.

@knewter
Created July 28, 2009 13:02
Show Gist options
  • Save knewter/157251 to your computer and use it in GitHub Desktop.
Save knewter/157251 to your computer and use it in GitHub Desktop.
namespace :spec do
namespace :parallel do
desc "prepare parallel test running by calling db:reset for every test database needed with spec:parallel:"
task :prepare, :count do |t,args|
num_processes = (args[:count] || 2).to_i
num_processes.times do |i|
puts "Preparing database #{i + 1}"
`export TEST_ENV_NUMBER=#{i == 0 ? '' : i + 1} ; export RAILS_ENV=test ; rake db:reset`
end
end
end
desc "run specs in parallel with spec:parallel[count]"
task :parallel, :count do |t,args|
require File.join(File.dirname(__FILE__), '..', 'lib', 'parallel_specs')
start = Time.now
num_processes = (args[:count] || 2).to_i
groups = ParallelSpecs.specs_in_groups(RAILS_ROOT, num_processes)
num_specs = groups.sum { |g| g.size }
puts "#{num_processes} processes for #{num_specs} specs, ~ #{num_specs / num_processes} specs per process"
#run each of the groups
pids = []
read, write = IO.pipe
groups.each_with_index do |files, process_number|
pids << Process.fork do
write.puts ParallelSpecs.run_tests(files, process_number)
end
end
#handle user interrup (Ctrl+c)
Signal.trap 'SIGINT' do
STDERR.puts "Parallel specs interrupted, exiting ..."
pids.each { |pid| Process.kill("KILL", pid) }
exit 1
end
#wait for processes to finish
pids.each { Process.wait }
#parse and print results
write.close
results = ParallelSpecs.find_results(read.read)
read.close
puts ""
puts "Results:"
results.each{|r| puts r}
#report total time taken
puts ""
puts "Took #{Time.now - start} seconds"
#exit with correct status code
exit ParallelSpecs.failed?(results) ? 1 : 0
end
end
namespace :test do
namespace :parallel do
desc "prepare parallel test running by calling db:reset for every test database needed with spec:parallel:"
task :prepare, :count do |t,args|
num_processes = (args[:count] || 2).to_i
num_processes.times do |i|
puts "Preparing database #{i + 1}"
`export TEST_ENV_NUMBER=#{i == 0 ? '' : i + 1} ; export RAILS_ENV=test ; rake db:reset`
end
end
end
desc "run tests in parallel with test:parallel[count, test_type] where test_type can be units, functionals or call_handler"
task :parallel, :count, :test_type do |t,args|
require File.join(File.dirname(__FILE__), '..', 'lib', 'parallel_tests')
start = Time.now
test_type = args[:test_type]
case test_type
when 'units'
root_path = RAILS_ROOT + "/test/unit/**/*_test.rb"
when 'functionals'
root_path = RAILS_ROOT + "/test/functional/**/*_test.rb"
when 'call_handler'
root_path = RAILS_ROOT + "/test/unit/call*_test.rb"
else
root_path = RAILS_ROOT + "/test/**/*_test.rb"
end
num_processes = (args[:count] || 2).to_i
groups = ParallelTests.tests_in_groups(root_path, num_processes)
num_specs = groups.sum { |g| g.size }
puts "#{num_processes} processes for #{num_specs} tests, ~ #{num_specs / num_processes} tests per process"
#run each of the groups
pids = []
read, write = IO.pipe
groups.each_with_index do |files, process_number|
pids << Process.fork do
write.puts ParallelTests.run_tests(files, process_number)
end
end
#handle user interrup (Ctrl+c)
Signal.trap 'SIGINT' do
STDERR.puts "Parallel tests interrupted, exiting ..."
pids.each { |pid| Process.kill("KILL", pid) }
exit 1
end
#wait for processes to finish
pids.each { Process.wait }
#parse and print results
write.close
results = ParallelTests.find_results(read.read)
read.close
puts ""
puts "Results:"
results.each{|r| puts r}
#report total time taken
puts ""
puts "Took #{Time.now - start} seconds"
#exit with correct status code
exit ParallelTests.failed?(results) ? 1 : 0
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment