Skip to content

Commit 50d3a4b

Browse files
committed
move tasks to bin
1 parent 4405ebf commit 50d3a4b

File tree

5 files changed

+89
-50
lines changed

5 files changed

+89
-50
lines changed

Rakefile

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
11
task :default => :spec
22
require 'spec/rake/spectask'
3-
Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color']}
3+
Spec::Rake::SpecTask.new {|t| t.spec_opts = ['--color']}
4+
5+
begin
6+
require 'jeweler'
7+
project_name = 'parallel_tests'
8+
Jeweler::Tasks.new do |gem|
9+
gem.name = project_name
10+
gem.summary = "Run tests / specs / features in parallel"
11+
gem.email = "[email protected]"
12+
gem.homepage = "http://github.com/grosser/#{project_name}"
13+
gem.authors = ["Michael Grosser"]
14+
end
15+
16+
Jeweler::GemcutterTasks.new
17+
rescue LoadError
18+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
19+
end

bin/parallel_test

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env ruby
2+
require 'rubygems'
3+
require 'active_support' # TODO remove this later...
4+
5+
options = {}
6+
OptionParser.new do |opts|
7+
opts.banner = <<BANNER
8+
Run tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
9+
10+
Options are:
11+
BANNER
12+
opts.on("-t", "--type [TYPE]", "which type of tests to run? test, spec or features"){|type| options[:type] = type }
13+
opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs"){|n| options[:count] = n }
14+
opts.on("-p", '--path [PATH]', "run tests inside this path only"){|path| options[:path_prefix] = path }
15+
opts.on("-r", '--root [PATH]', "execute test commands from this path"){|path| options[:root] = path }
16+
opts.on('-v', '--version', 'Show Version'){ puts ParallelTests::VERSION; exit}
17+
opts.on("-h", "--help", "Show this.") { puts opts; exit }
18+
end.parse!
19+
20+
lib, name, task = {
21+
'test' => ["tests", "test", "test"],
22+
'spec' => ["specs", "spec", "spec"],
23+
'features' => ["cucumber", "feature", "features"]
24+
}[options[:type]||'test']
25+
26+
require File.join(File.dirname(__FILE__), '..', 'lib', "parallel_#{lib}")
27+
klass = eval("Parallel#{lib.capitalize}")
28+
29+
start = Time.now
30+
31+
num_processes = options[:count] || Parallel.processor_count
32+
tests_folder = File.join(task, options[:path_prefix].to_s)
33+
tests_folder = File.join(options[:root], tests_folder) if options[:root]
34+
35+
groups = klass.tests_in_groups(tests_folder, num_processes)
36+
37+
#adjust processes to groups
38+
abort "no #{name}s found!" if groups.size == 0
39+
40+
num_tests = groups.sum{|g| g.size }
41+
puts "#{groups.size} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
42+
43+
output = Parallel.map(groups) do |group|
44+
klass.run_tests(group, groups.index(group))
45+
end
46+
47+
#parse and print results
48+
results = klass.find_results(output*"")
49+
puts ""
50+
puts "Results:"
51+
results.each{|r| puts r}
52+
53+
#report total time taken
54+
puts ""
55+
puts "Took #{Time.now - start} seconds"
56+
57+
#exit with correct status code
58+
# - rake parallel:test && echo 123 ==> 123 should not show up when test failed
59+
# - rake parallel:test db:reset ==> works when tests succeed
60+
abort "#{name.capitalize}s Failed" if klass.failed?(results)

lib/parallel_tests.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class ParallelTests
44
# parallel:spec[2,controller] <-> parallel:spec[controller]
5-
def self.parse_test_args(args)
5+
def self.parse_rake_args (args)
66
num_processes = Parallel.processor_count
77
options = ""
88
if args[:count].to_s =~ /^\d*$/ # number or empty

spec/parallel_tests_spec.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33
describe ParallelTests do
44
test_tests_in_groups(ParallelTests, 'test', '_test.rb')
55

6-
describe :parse_test_args do
6+
describe :parse_rake_args do
77
it "should return the count" do
88
args = {:count => 2}
9-
ParallelTests.parse_test_args(args).should == [2, '', ""]
9+
ParallelTests.parse_rake_args(args).should == [2, '', ""]
1010
end
1111

1212
it "should default to the prefix" do
1313
args = {:count => "models"}
14-
ParallelTests.parse_test_args(args).should == [2, "models", ""]
14+
ParallelTests.parse_rake_args(args).should == [2, "models", ""]
1515
end
1616

1717
it "should return the count and prefix" do
1818
args = {:count => 2, :path_prefix => "models"}
19-
ParallelTests.parse_test_args(args).should == [2, "models", ""]
19+
ParallelTests.parse_rake_args(args).should == [2, "models", ""]
2020
end
2121

2222
it "should return the count, prefix, and options" do
2323
args = {:count => 2, :path_prefix => "plain", :options => "-p default" }
24-
ParallelTests.parse_test_args(args).should == [2, "plain", "-p default"]
24+
ParallelTests.parse_rake_args(args).should == [2, "plain", "-p default"]
2525
end
2626
end
2727

tasks/parallel_specs.rake

+6-43
Original file line numberDiff line numberDiff line change
@@ -20,53 +20,16 @@ namespace :parallel do
2020
end
2121
end
2222

23-
[
24-
["tests", "test", "test"],
25-
["specs", "spec", "spec"],
26-
["cucumber", "feature", "features"]
27-
].each do |lib, name, task|
28-
desc "run #{name}s in parallel with parallel:#{task}[num_cpus]"
29-
task task, :count, :path_prefix, :options do |t,args|
30-
require File.join(File.dirname(__FILE__), '..', 'lib', "parallel_#{lib}")
31-
klass = eval("Parallel#{lib.capitalize}")
32-
33-
start = Time.now
34-
35-
num_processes, prefix, options = ParallelTests.parse_test_args(args)
36-
tests_folder = File.join(RAILS_ROOT, task, prefix)
37-
groups = klass.tests_in_groups(tests_folder, num_processes)
38-
39-
#adjust processes to groups
40-
num_processes = [groups.size, num_processes].min
41-
abort "no #{name}s found!" if num_processes == 0
42-
43-
num_tests = groups.sum { |g| g.size }
44-
45-
puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / num_processes} #{name}s per process"
46-
47-
output = Parallel.in_processes(num_processes) do |process_number|
48-
klass.run_tests(groups[process_number], process_number, options)
49-
end
50-
51-
#parse and print results
52-
results = klass.find_results(output*"")
53-
puts ""
54-
puts "Results:"
55-
results.each{|r| puts r}
56-
57-
#report total time taken
58-
puts ""
59-
puts "Took #{Time.now - start} seconds"
60-
61-
#exit with correct status code
62-
# - rake parallel:test && echo 123 ==> 123 should not show up when test failed
63-
# - rake parallel:test db:reset ==> works when tests succeed
64-
abort "#{name.capitalize}s Failed" if klass.failed?(results)
23+
['test', 'spec', 'features'].each do |type|
24+
desc "run #{type} in parallel with parallel:#{type}[num_cpus]"
25+
task type, :count, :path_prefix, :options do |t,args|
26+
require File.join(File.dirname(__FILE__), '..', 'lib', "parallel_tests")
27+
count, prefix, options = ParallelTests.parse_rake_args(args)
28+
sh "#{File.join(File.dirname(__FILE__), '..', 'bin', 'parallel_test')} --type #{type} -n #{count} -p #{prefix} -r #{RAILS_ROOT} -o #{options} -e"
6529
end
6630
end
6731
end
6832

69-
7033
#backwards compatability
7134
#spec:parallel:prepare
7235
#spec:parallel

0 commit comments

Comments
 (0)