parallelized_specs 0.0.8 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +10 -0
- data/Gemfile.lock +0 -23
- data/Rakefile +1 -1
- data/Readme.md +1 -32
- data/VERSION +1 -1
- data/lib/parallelized_specs/grouper.rb +1 -2
- data/lib/parallelized_specs/tasks.rb +13 -32
- data/lib/parallelized_specs.rb +64 -4
- data/parallelized_specs.gemspec +5 -4
- metadata +22 -10
- data/bin/parallelized_spec +0 -95
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,30 +1,7 @@
|
|
1
1
|
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
2
|
specs:
|
4
|
-
diff-lcs (1.1.2)
|
5
|
-
git (1.2.5)
|
6
|
-
jeweler (1.6.3)
|
7
|
-
bundler (~> 1.0)
|
8
|
-
git (>= 1.2.5)
|
9
|
-
rake
|
10
|
-
parallel (0.5.1)
|
11
|
-
rake (0.8.7)
|
12
|
-
rspec (2.6.0)
|
13
|
-
rspec-core (~> 2.6.0)
|
14
|
-
rspec-expectations (~> 2.6.0)
|
15
|
-
rspec-mocks (~> 2.6.0)
|
16
|
-
rspec-core (2.6.4)
|
17
|
-
rspec-expectations (2.6.0)
|
18
|
-
diff-lcs (~> 1.1.2)
|
19
|
-
rspec-mocks (2.6.0)
|
20
|
-
test-unit (2.4.4)
|
21
3
|
|
22
4
|
PLATFORMS
|
23
5
|
ruby
|
24
6
|
|
25
7
|
DEPENDENCIES
|
26
|
-
jeweler
|
27
|
-
parallel
|
28
|
-
rake
|
29
|
-
rspec (>= 2.4)
|
30
|
-
test-unit
|
data/Rakefile
CHANGED
data/Readme.md
CHANGED
@@ -56,9 +56,7 @@ ParallelizedSpecs uses 1 database per test-process, 2 processes will use `*_test
|
|
56
56
|
rake parallel:prepare
|
57
57
|
|
58
58
|
### 4: Run!
|
59
|
-
rake parallel:test # Test::Unit
|
60
59
|
rake parallel:spec # RSpec
|
61
|
-
rake parallel:features # Cucumber
|
62
60
|
|
63
61
|
rake parallel:test[1] --> force 1 CPU --> 86 seconds
|
64
62
|
rake parallel:test --> got 2 CPUs? --> 47 seconds
|
@@ -67,7 +65,7 @@ ParallelizedSpecs uses 1 database per test-process, 2 processes will use `*_test
|
|
67
65
|
|
68
66
|
Test by pattern (e.g. use one integration server per subfolder / see if you broke any 'user'-related tests)
|
69
67
|
|
70
|
-
rake parallel:test[^unit] # everything in test/
|
68
|
+
rake parallel:test[^unit] # everything in test/spec folder (every test file matching /^spec/)
|
71
69
|
rake parallel:test[user] # run users_controller + user_helper + user tests
|
72
70
|
rake parallel:test['user|product'] # run user and product related tests
|
73
71
|
|
@@ -151,35 +149,6 @@ Setup for non-rails
|
|
151
149
|
|
152
150
|
parallelized_specs test/bar test/baz/xxx_text_spec.rb
|
153
151
|
|
154
|
-
Options are:
|
155
|
-
|
156
|
-
-n [PROCESSES] How many processes to use, default: available CPUs
|
157
|
-
-p, --path [PATH] run tests inside this path only
|
158
|
-
--no-sort do not sort files before running them
|
159
|
-
-m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
|
160
|
-
-r, --root [PATH] execute test commands from this path
|
161
|
-
-e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUM']
|
162
|
-
-o, --test-options '[OPTIONS]' execute test commands with those options
|
163
|
-
-t, --type [TYPE] which type of tests to run? test, spec or features
|
164
|
-
--non-parallel execute same commands but do not in parallel, needs --exec
|
165
|
-
-v, --version Show Version
|
166
|
-
-h, --help Show this.
|
167
|
-
|
168
|
-
You can run any kind of code with -e / --execute
|
169
|
-
|
170
|
-
parallel_test -n 5 -e 'ruby -e "puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]"'
|
171
|
-
hello from process "2"
|
172
|
-
hello from process ""
|
173
|
-
hello from process "3"
|
174
|
-
hello from process "5"
|
175
|
-
hello from process "4"
|
176
|
-
|
177
|
-
<table>
|
178
|
-
<tr><td></td><td>1 Process</td><td>2 Processes</td><td>4 Processes</td></tr>
|
179
|
-
<tr><td>RSpec spec-suite</td><td>18s</td><td>14s</td><td>10s</td></tr>
|
180
|
-
<tr><td>Rails-ActionPack</td><td>88s</td><td>53s</td><td>44s</td></tr>
|
181
|
-
</table>
|
182
|
-
|
183
152
|
TIPS
|
184
153
|
====
|
185
154
|
- [RSpec] add a `spec/parallel_spec.opts` to use different options, e.g. no --drb (default: `spec/spec.opts`)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.1.6
|
@@ -12,9 +12,8 @@ class ParallelizedSpecs
|
|
12
12
|
groups.map!(&:sort!)
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.in_even_groups_by_size(items_with_sizes, num_groups, options
|
15
|
+
def self.in_even_groups_by_size(items_with_sizes, num_groups, options)
|
16
16
|
groups = Array.new(num_groups){{:items => [], :size => 0}}
|
17
|
-
|
18
17
|
# add all files that should run in a single process to one group
|
19
18
|
(options[:single_process]||[]).each do |pattern|
|
20
19
|
matched, items_with_sizes = items_with_sizes.partition{|item, size| item =~ pattern }
|
@@ -1,19 +1,19 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
2
|
+
require "parallelized_specs"
|
3
|
+
|
1
4
|
namespace :parallel do
|
2
|
-
def
|
3
|
-
|
4
|
-
executable = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'parallelized_spec')
|
5
|
-
command = "#{executable} --exec '#{cmd}' -n #{count} #{'--non-parallel' if options[:non_parallel]}"
|
6
|
-
abort unless system(command)
|
5
|
+
def run_db_in_parallel(cmd, options={})
|
6
|
+
ParallelizedSpecs.execute_parallel_db(cmd, options)
|
7
7
|
end
|
8
8
|
|
9
9
|
desc "create test databases via db:create --> parallel:create[num_cpus]"
|
10
10
|
task :create, :count do |t, args|
|
11
|
-
|
11
|
+
run_db_in_parallel('rake db:create RAILS_ENV=test', args)
|
12
12
|
end
|
13
13
|
|
14
14
|
desc "drop test databases via db:drop --> parallel:drop[num_cpus]"
|
15
15
|
task :drop, :count do |t, args|
|
16
|
-
|
16
|
+
run_db_in_parallel('rake db:drop RAILS_ENV=test', args)
|
17
17
|
end
|
18
18
|
|
19
19
|
desc "update test databases by dumping and loading --> parallel:prepare[num_cpus]"
|
@@ -25,46 +25,27 @@ namespace :parallel do
|
|
25
25
|
else
|
26
26
|
# there is no separate dump / load for schema_format :sql -> do it safe and slow
|
27
27
|
args = args.to_hash.merge(:non_parallel => true) # normal merge returns nil
|
28
|
-
|
28
|
+
run_db_in_parallel('rake db:test:prepare --trace', args)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
# when dumping/resetting takes too long
|
33
33
|
desc "update test databases via db:migrate --> parallel:migrate[num_cpus]"
|
34
34
|
task :migrate, :count do |t, args|
|
35
|
-
|
35
|
+
run_db_in_parallel('rake db:migrate RAILS_ENV=test', args)
|
36
36
|
end
|
37
37
|
|
38
38
|
# just load the schema (good for integration server <-> no development db)
|
39
39
|
desc "load dumped schema for test databases via db:schema:load --> parallel:load_schema[num_cpus]"
|
40
40
|
task :load_schema, :count do |t, args|
|
41
|
-
|
41
|
+
run_db_in_parallel('rake db:test:load', args)
|
42
42
|
end
|
43
43
|
|
44
44
|
desc "run spec in parallel with parallel:spec[num_cpus]"
|
45
45
|
task 'spec', :count, :pattern, :options, :arguments do |t, args|
|
46
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
47
|
-
require "parallelized_specs"
|
48
46
|
count, pattern, options = ParallelizedSpecs.parse_rake_args(args)
|
49
|
-
|
50
|
-
|
51
|
-
|
47
|
+
#command = "-n #{count} -p '#{pattern}' -r '#{Rails.root}' -o '#{options}' #{args[:arguments]}"
|
48
|
+
opts = Hash[:count => count, :pattern => pattern, :options => options, :root => Rails.root, :files => args[:arguments]]
|
49
|
+
ParallelizedSpecs.execute_parallel_specs(opts)
|
52
50
|
end
|
53
51
|
end
|
54
|
-
|
55
|
-
#backwards compatability
|
56
|
-
#spec:parallel:prepare
|
57
|
-
#spec:parallel
|
58
|
-
namespace :spec do
|
59
|
-
namespace :parallel do
|
60
|
-
task :prepare, :count do |t, args|
|
61
|
-
$stderr.puts "WARNING -- Deprecated! use parallel:prepare"
|
62
|
-
Rake::Task['parallel:prepare'].invoke(args[:count])
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
task :parallel, :count, :pattern do |t, args|
|
67
|
-
$stderr.puts "WARNING -- Deprecated! use parallel:spec"
|
68
|
-
Rake::Task['parallel:spec'].invoke(args[:count], args[:pattern])
|
69
|
-
end
|
70
|
-
end
|
data/lib/parallelized_specs.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'parallel'
|
2
|
+
raise "please ' gem install parallel '" if Gem::Version.new(Parallel::VERSION) < Gem::Version.new('0.4.2')
|
3
|
+
require 'optparse'
|
2
4
|
require 'parallelized_specs/grouper'
|
3
5
|
require 'parallelized_specs/railtie'
|
4
6
|
require 'parallelized_specs/spec_error_logger'
|
@@ -51,6 +53,64 @@ class ParallelizedSpecs
|
|
51
53
|
"_spec.rb"
|
52
54
|
end
|
53
55
|
|
56
|
+
def self.execute_parallel_db(cmd, options={})
|
57
|
+
count = options[:count].to_i
|
58
|
+
count = Parallel.processor_count if count == 0
|
59
|
+
runs = (0...count).to_a
|
60
|
+
results = if options[:non_parallel]
|
61
|
+
runs.map do |i|
|
62
|
+
execute_command(cmd, i, options)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
Parallel.map(runs, :in_processes => count) do |i|
|
66
|
+
execute_command(cmd, i, options)
|
67
|
+
end
|
68
|
+
end.flatten
|
69
|
+
abort if results.any? { |r| r[:exit_status] != 0 }
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.execute_parallel_specs(options)
|
73
|
+
num_processes = options[:count] || Parallel.processor_count
|
74
|
+
lib, name, task = {
|
75
|
+
'spec' => %w(specs spec spec),
|
76
|
+
}[options[:type]||'spec']
|
77
|
+
|
78
|
+
start = Time.now
|
79
|
+
|
80
|
+
tests_folder = task
|
81
|
+
tests_folder = File.join(options[:root], tests_folder) unless options[:root].to_s.empty?
|
82
|
+
if options[:files].is_a?(Array)
|
83
|
+
groups = tests_in_groups(options[:files] || tests_folder, num_processes, options)
|
84
|
+
else
|
85
|
+
files_array = options[:files].split(/ /)
|
86
|
+
groups = tests_in_groups(files_array || tests_folder, num_processes, options)
|
87
|
+
end
|
88
|
+
num_processes = groups.size
|
89
|
+
|
90
|
+
#adjust processes to groups
|
91
|
+
abort "no #{name}s found!" if groups.size == 0
|
92
|
+
|
93
|
+
num_tests = groups.inject(0) { |sum, item| sum + item.size }
|
94
|
+
puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
|
95
|
+
|
96
|
+
test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
|
97
|
+
run_tests(group, groups.index(group), options)
|
98
|
+
end
|
99
|
+
|
100
|
+
#parse and print results
|
101
|
+
results = find_results(test_results.map { |result| result[:stdout] }*"")
|
102
|
+
puts ""
|
103
|
+
puts summarize_results(results)
|
104
|
+
|
105
|
+
#report total time taken
|
106
|
+
puts ""
|
107
|
+
puts "Took #{Time.now - start} seconds"
|
108
|
+
|
109
|
+
#exit with correct status code so rake parallel:test && echo 123 works
|
110
|
+
failed = test_results.any? { |result| result[:exit_status] != 0 }
|
111
|
+
abort "#{name.capitalize}s Failed" if failed
|
112
|
+
end
|
113
|
+
|
54
114
|
# parallel:spec[:count, :pattern, :options]
|
55
115
|
def self.parse_rake_args(args)
|
56
116
|
# order as given by user
|
@@ -71,7 +131,7 @@ class ParallelizedSpecs
|
|
71
131
|
end
|
72
132
|
|
73
133
|
# finds all tests and partitions them into groups
|
74
|
-
def self.tests_in_groups(root, num_groups, options
|
134
|
+
def self.tests_in_groups(root, num_groups, options)
|
75
135
|
tests = find_tests(root, options)
|
76
136
|
if options[:no_sort]
|
77
137
|
Grouper.in_groups(tests, num_groups)
|
@@ -184,15 +244,15 @@ class ParallelizedSpecs
|
|
184
244
|
end
|
185
245
|
end
|
186
246
|
|
187
|
-
def self.find_tests(root, options
|
247
|
+
def self.find_tests(root, options)
|
188
248
|
if root.is_a?(Array)
|
189
249
|
root
|
190
250
|
else
|
191
251
|
# follow one symlink and direct children
|
192
252
|
# http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
|
193
|
-
files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
|
253
|
+
files = Dir["#{Rails.root}/**{,/*/**}/*#{test_suffix}"].uniq
|
194
254
|
files = files.map { |f| f.sub(root+'/', '') }
|
195
|
-
files = files.grep(/#{options[
|
255
|
+
files = files.grep(/#{options['pattern']}/)
|
196
256
|
files.map { |f| "#{root}/#{f}" }
|
197
257
|
end
|
198
258
|
end
|
data/parallelized_specs.gemspec
CHANGED
@@ -5,20 +5,18 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "parallelized_specs"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.1.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jake Sorce, Bryan Madsen"]
|
12
|
-
s.date = "2012-04-
|
12
|
+
s.date = "2012-04-27"
|
13
13
|
s.email = "jake@instructure.com"
|
14
|
-
s.executables = ["parallelized_spec"]
|
15
14
|
s.files = [
|
16
15
|
"Gemfile",
|
17
16
|
"Gemfile.lock",
|
18
17
|
"Rakefile",
|
19
18
|
"Readme.md",
|
20
19
|
"VERSION",
|
21
|
-
"bin/parallelized_spec",
|
22
20
|
"lib/parallelized_specs.rb",
|
23
21
|
"lib/parallelized_specs/grouper.rb",
|
24
22
|
"lib/parallelized_specs/railtie.rb",
|
@@ -48,9 +46,12 @@ Gem::Specification.new do |s|
|
|
48
46
|
s.specification_version = 3
|
49
47
|
|
50
48
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<parallel>, [">= 0"])
|
51
50
|
else
|
51
|
+
s.add_dependency(%q<parallel>, [">= 0"])
|
52
52
|
end
|
53
53
|
else
|
54
|
+
s.add_dependency(%q<parallel>, [">= 0"])
|
54
55
|
end
|
55
56
|
end
|
56
57
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallelized_specs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 1
|
9
|
+
- 6
|
10
|
+
version: 0.1.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jake Sorce, Bryan Madsen
|
@@ -15,13 +15,26 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-04-
|
19
|
-
dependencies:
|
20
|
-
|
18
|
+
date: 2012-04-27 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: parallel
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
21
34
|
description:
|
22
35
|
email: jake@instructure.com
|
23
|
-
executables:
|
24
|
-
|
36
|
+
executables: []
|
37
|
+
|
25
38
|
extensions: []
|
26
39
|
|
27
40
|
extra_rdoc_files: []
|
@@ -32,7 +45,6 @@ files:
|
|
32
45
|
- Rakefile
|
33
46
|
- Readme.md
|
34
47
|
- VERSION
|
35
|
-
- bin/parallelized_spec
|
36
48
|
- lib/parallelized_specs.rb
|
37
49
|
- lib/parallelized_specs/grouper.rb
|
38
50
|
- lib/parallelized_specs/railtie.rb
|
data/bin/parallelized_spec
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'rubygems'
|
3
|
-
require 'optparse'
|
4
|
-
require 'parallel'
|
5
|
-
raise "please ' gem install parallel '" if Gem::Version.new(Parallel::VERSION) < Gem::Version.new('0.4.2')
|
6
|
-
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
7
|
-
require "parallelized_specs"
|
8
|
-
|
9
|
-
options = {}
|
10
|
-
OptionParser.new do |opts|
|
11
|
-
opts.banner = <<BANNER
|
12
|
-
Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
|
13
|
-
|
14
|
-
[optional] Only run selected files & folders:
|
15
|
-
parallelized_spec test/bar test/baz/xxx_text_spec.rb
|
16
|
-
|
17
|
-
Options are:
|
18
|
-
BANNER
|
19
|
-
opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs"){|n| options[:count] = n }
|
20
|
-
opts.on("-p", '--pattern [PATTERN]', "run tests matching this pattern"){|pattern| options[:pattern] = pattern }
|
21
|
-
opts.on("--no-sort", "do not sort files before running them"){ |no_sort| options[:no_sort] = no_sort }
|
22
|
-
opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run"){ |multiply| options[:multiply] = multiply }
|
23
|
-
opts.on("-r", '--root [PATH]', "execute test commands from this path"){|path| options[:root] = path }
|
24
|
-
opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in only one process") do |pattern|
|
25
|
-
options[:single_process] ||= []
|
26
|
-
options[:single_process] << /#{pattern}/
|
27
|
-
end
|
28
|
-
opts.on("-e", '--exec [COMMAND]', "execute this code parallel and with ENV['TEST_ENV_NUM']"){|path| options[:execute] = path }
|
29
|
-
opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options"){|arg| options[:test_options] = arg }
|
30
|
-
opts.on("-t", "--type [TYPE]", "which type of tests to run? test, spec or features"){|type| options[:type] = type }
|
31
|
-
opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec"){ options[:non_parallel] = true }
|
32
|
-
opts.on("--chunk-timeout [TIMEOUT]", "timeout before re-printing the output of a child-process"){|timeout| options[:chunk_timeout] = timeout.to_f }
|
33
|
-
opts.on('-v', '--version', 'Show Version'){ puts ParallelizedSpecs::VERSION; exit}
|
34
|
-
opts.on("-h", "--help", "Show this.") { puts opts; exit }
|
35
|
-
end.parse!
|
36
|
-
|
37
|
-
raise "--no-sort and --single-process are not supported" if options[:no_sort] and options[:single_process]
|
38
|
-
|
39
|
-
# get files to run from arguments
|
40
|
-
options[:files] = ARGV if ARGV.size > 0
|
41
|
-
|
42
|
-
num_processes = options[:count] || Parallel.processor_count
|
43
|
-
num_processes = num_processes * (options[:multiply] || 1)
|
44
|
-
|
45
|
-
if options[:execute]
|
46
|
-
runs = (0...num_processes).to_a
|
47
|
-
results = if options[:non_parallel]
|
48
|
-
runs.map do |i|
|
49
|
-
ParallelizedSpecs.execute_command(options[:execute], i, options)
|
50
|
-
end
|
51
|
-
else
|
52
|
-
Parallel.map(runs, :in_processes => num_processes) do |i|
|
53
|
-
ParallelizedSpecs.execute_command(options[:execute], i, options)
|
54
|
-
end
|
55
|
-
end.flatten
|
56
|
-
abort if results.any?{|r| r[:exit_status] != 0 }
|
57
|
-
else
|
58
|
-
lib, name, task = {
|
59
|
-
'spec' => %w(specs spec spec),
|
60
|
-
}[options[:type]||'spec']
|
61
|
-
|
62
|
-
require "parallelized_#{lib}"
|
63
|
-
klass = eval("Parallelized#{lib.capitalize}")
|
64
|
-
|
65
|
-
start = Time.now
|
66
|
-
|
67
|
-
tests_folder = task
|
68
|
-
tests_folder = File.join(options[:root], tests_folder) unless options[:root].to_s.empty?
|
69
|
-
|
70
|
-
groups = klass.tests_in_groups(options[:files] || tests_folder, num_processes, options)
|
71
|
-
num_processes = groups.size
|
72
|
-
|
73
|
-
#adjust processes to groups
|
74
|
-
abort "no #{name}s found!" if groups.size == 0
|
75
|
-
|
76
|
-
num_tests = groups.inject(0){|sum,item| sum + item.size }
|
77
|
-
puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
|
78
|
-
|
79
|
-
test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
|
80
|
-
klass.run_tests(group, groups.index(group), options)
|
81
|
-
end
|
82
|
-
|
83
|
-
#parse and print results
|
84
|
-
results = klass.find_results(test_results.map{|result| result[:stdout] }*"")
|
85
|
-
puts ""
|
86
|
-
puts klass.summarize_results(results)
|
87
|
-
|
88
|
-
#report total time taken
|
89
|
-
puts ""
|
90
|
-
puts "Took #{Time.now - start} seconds"
|
91
|
-
|
92
|
-
#exit with correct status code so rake parallel:test && echo 123 works
|
93
|
-
failed = test_results.any?{|result| result[:exit_status] != 0 }
|
94
|
-
abort "#{name.capitalize}s Failed" if failed
|
95
|
-
end
|