parallel_tests 0.10.4 → 0.11.0
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.lock +1 -1
- data/lib/parallel_tests/cucumber/runner.rb +1 -2
- data/lib/parallel_tests/rspec/runner.rb +8 -3
- data/lib/parallel_tests/test/runner.rb +46 -18
- data/lib/parallel_tests/version.rb +1 -1
- data/spec/integration_spec.rb +1 -1
- data/spec/parallel_tests/cucumber/runner_spec.rb +12 -30
- data/spec/parallel_tests/rspec/runner_spec.rb +36 -52
- data/spec/parallel_tests/test/runner_spec.rb +167 -40
- data/spec/spec_helper.rb +1 -1
- metadata +46 -37
data/Gemfile.lock
CHANGED
@@ -6,10 +6,9 @@ module ParallelTests
|
|
6
6
|
NAME = 'Cucumber'
|
7
7
|
|
8
8
|
def self.run_tests(test_files, process_number, num_processes, options)
|
9
|
-
|
9
|
+
options = options.merge(:env => {"AUTOTEST" => "1"}) if $stdout.tty? # display color when we are in a terminal
|
10
10
|
runtime_logging = " --format ParallelTests::Cucumber::RuntimeLogger --out #{runtime_log}"
|
11
11
|
cmd = [
|
12
|
-
color,
|
13
12
|
executable,
|
14
13
|
(runtime_logging if File.directory?(File.dirname(runtime_log))),
|
15
14
|
cucumber_opts(options[:test_options]),
|
@@ -8,7 +8,8 @@ module ParallelTests
|
|
8
8
|
def self.run_tests(test_files, process_number, num_processes, options)
|
9
9
|
exe = executable # expensive, so we cache
|
10
10
|
version = (exe =~ /\brspec\b/ ? 2 : 1)
|
11
|
-
cmd =
|
11
|
+
cmd = [exe, options[:test_options], (rspec_2_color if version == 2), spec_opts, *test_files].compact.join(" ")
|
12
|
+
options = options.merge(:env => rspec_1_color) if version == 1
|
12
13
|
execute_command(cmd, process_number, num_processes, options)
|
13
14
|
end
|
14
15
|
|
@@ -44,11 +45,15 @@ module ParallelTests
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def self.rspec_1_color
|
47
|
-
|
48
|
+
if $stdout.tty?
|
49
|
+
{'RSPEC_COLOR' => "1"}
|
50
|
+
else
|
51
|
+
{}
|
52
|
+
end
|
48
53
|
end
|
49
54
|
|
50
55
|
def self.rspec_2_color
|
51
|
-
'--color --tty
|
56
|
+
'--color --tty' if $stdout.tty?
|
52
57
|
end
|
53
58
|
|
54
59
|
def self.spec_opts
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
1
3
|
module ParallelTests
|
2
4
|
module Test
|
3
5
|
class Runner
|
@@ -46,12 +48,35 @@ module ParallelTests
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def self.execute_command(cmd, process_number, num_processes, options)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
env = (options[:env] || {}).merge(
|
52
|
+
"TEST_ENV_NUMBER" => test_env_number(process_number),
|
53
|
+
"PARALLEL_TEST_GROUPS" => num_processes
|
54
|
+
)
|
55
|
+
execute_command_and_capture_output(env, cmd, options[:serialize_stdout])
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.execute_command_and_capture_output(env, cmd, silence)
|
59
|
+
# make processes descriptive / visible in ps -ef
|
60
|
+
exports = env.map do |k,v|
|
61
|
+
"#{k}=#{v};export #{k}"
|
62
|
+
end.join(";")
|
63
|
+
cmd = "#{exports};#{cmd}"
|
64
|
+
|
65
|
+
output, errput, exitstatus = nil
|
66
|
+
if RUBY_VERSION =~ /^1\.8/
|
67
|
+
open("|#{cmd}", "r") do |output|
|
68
|
+
output, errput = capture_output(output, nil, silence)
|
69
|
+
end
|
70
|
+
exitstatus = $?.exitstatus
|
71
|
+
else
|
72
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
|
73
|
+
stdin.close
|
74
|
+
output, errput = capture_output(stdout, stderr, silence)
|
75
|
+
exitstatus = thread.value.exitstatus
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
{:stdout => output, :stderr => errput, :exit_status => exitstatus}
|
55
80
|
end
|
56
81
|
|
57
82
|
def self.find_results(test_output)
|
@@ -84,26 +109,29 @@ module ParallelTests
|
|
84
109
|
def self.sum_up_results(results)
|
85
110
|
results = results.join(' ').gsub(/s\b/,'') # combine and singularize results
|
86
111
|
counts = results.scan(/(\d+) (\w+)/)
|
87
|
-
|
112
|
+
counts.inject(Hash.new(0)) do |sum, (number, word)|
|
88
113
|
sum[word] += number.to_i
|
89
114
|
sum
|
90
115
|
end
|
91
|
-
|
92
|
-
sums
|
93
116
|
end
|
94
117
|
|
95
118
|
# read output of the process and print it in chunks
|
96
|
-
def self.
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
119
|
+
def self.capture_output(out, err, silence)
|
120
|
+
results = ["", ""]
|
121
|
+
loop do
|
122
|
+
[[out, $stdout, 0], [err, $stderr, 1]].each do |input, output, index|
|
123
|
+
next unless input
|
124
|
+
begin
|
125
|
+
read = input.readpartial(1000000) # read whatever chunk we can get
|
126
|
+
results[index] << read
|
127
|
+
output.print read if index == 1 || !silence
|
128
|
+
|
129
|
+
rescue EOFError
|
130
|
+
raise if index == 0 # we only care about the end of stdout
|
131
|
+
end
|
103
132
|
end
|
104
133
|
end rescue EOFError
|
105
|
-
|
106
|
-
all
|
134
|
+
results
|
107
135
|
end
|
108
136
|
|
109
137
|
def self.with_runtime_info(tests)
|
data/spec/integration_spec.rb
CHANGED
@@ -188,7 +188,7 @@ describe 'CLI' do
|
|
188
188
|
end
|
189
189
|
|
190
190
|
it "can wait_for_other_processes_to_finish" do
|
191
|
-
write "test/a_test.rb", "require 'parallel_tests'; ParallelTests.wait_for_other_processes_to_finish; puts 'a'"
|
191
|
+
write "test/a_test.rb", "require 'parallel_tests'; sleep 0.5 ; ParallelTests.wait_for_other_processes_to_finish; puts 'a'"
|
192
192
|
write "test/b_test.rb", "sleep 1; puts 'b'"
|
193
193
|
write "test/c_test.rb", "sleep 1.5; puts 'c'"
|
194
194
|
write "test/d_test.rb", "sleep 2; puts 'd'"
|
@@ -15,54 +15,36 @@ describe ParallelTests::Cucumber do
|
|
15
15
|
ParallelTests::Cucumber::Runner.run_tests(*args)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
ParallelTests::
|
20
|
-
call(['xxx'],0,22,{})
|
21
|
-
end
|
22
|
-
|
23
|
-
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
24
|
-
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
25
|
-
call(['xxx'],1,22,{})
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'sets PARALLEL_TEST_GROUPS so child processes know that they are being run under parallel_tests' do
|
29
|
-
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/PARALLEL_TEST_GROUPS=22/}.and_return mocked_process
|
30
|
-
call(['xxx'],1,22,{})
|
18
|
+
def should_run_with(regex)
|
19
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a =~ regex}
|
31
20
|
end
|
32
21
|
|
33
22
|
it "allows to override runner executable via PARALLEL_TESTS_EXECUTABLE" do
|
34
23
|
ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
|
35
|
-
|
24
|
+
should_run_with /script\/custom_rspec/
|
36
25
|
call(['xxx'],1,22,{})
|
37
26
|
ENV.delete('PARALLEL_TESTS_EXECUTABLE')
|
38
27
|
end
|
39
28
|
|
40
|
-
it "returns the output" do
|
41
|
-
io = open('spec/spec_helper.rb')
|
42
|
-
$stdout.stub!(:print)
|
43
|
-
ParallelTests::Cucumber::Runner.should_receive(:open).and_return io
|
44
|
-
call(['xxx'],1,22,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
45
|
-
end
|
46
|
-
|
47
29
|
it "runs bundle exec cucumber when on bundler 0.9" do
|
48
30
|
ParallelTests.stub!(:bundler_enabled?).and_return true
|
49
|
-
|
31
|
+
should_run_with %r{bundle exec cucumber}
|
50
32
|
call(['xxx'],1,22,{})
|
51
33
|
end
|
52
34
|
|
53
35
|
it "runs script/cucumber when script/cucumber is found" do
|
54
|
-
|
36
|
+
should_run_with %r{script/cucumber}
|
55
37
|
call(['xxx'],1,22,{})
|
56
38
|
end
|
57
39
|
|
58
40
|
it "runs cucumber by default" do
|
59
41
|
File.stub!(:file?).with('script/cucumber').and_return false
|
60
|
-
|
42
|
+
should_run_with %r{^cucumber}
|
61
43
|
call(['xxx'],1,22,{})
|
62
44
|
end
|
63
45
|
|
64
46
|
it "uses options passed in" do
|
65
|
-
|
47
|
+
should_run_with %r{script/cucumber .* -p default}
|
66
48
|
call(['xxx'],1,22,:test_options => '-p default')
|
67
49
|
end
|
68
50
|
|
@@ -74,31 +56,31 @@ describe ParallelTests::Cucumber do
|
|
74
56
|
end
|
75
57
|
|
76
58
|
it "uses parallel profile" do
|
77
|
-
|
59
|
+
should_run_with %r{script/cucumber .* foo bar --profile parallel xxx}
|
78
60
|
call(['xxx'],1,22, :test_options => 'foo bar')
|
79
61
|
end
|
80
62
|
|
81
63
|
it "uses given profile via --profile" do
|
82
|
-
|
64
|
+
should_run_with %r{script/cucumber .* --profile foo xxx$}
|
83
65
|
call(['xxx'],1,22, :test_options => '--profile foo')
|
84
66
|
end
|
85
67
|
|
86
68
|
it "uses given profile via -p" do
|
87
|
-
|
69
|
+
should_run_with %r{script/cucumber .* -p foo xxx$}
|
88
70
|
call(['xxx'],1,22, :test_options => '-p foo')
|
89
71
|
end
|
90
72
|
end
|
91
73
|
|
92
74
|
it "does not use parallel profile if config/cucumber.yml does not contain it" do
|
93
75
|
file_contents = 'blob: -f progress'
|
94
|
-
|
76
|
+
should_run_with %r{script/cucumber .* foo bar}
|
95
77
|
Dir.should_receive(:glob).and_return ['config/cucumber.yml']
|
96
78
|
File.should_receive(:read).with('config/cucumber.yml').and_return file_contents
|
97
79
|
call(['xxx'],1,22,:test_options => 'foo bar')
|
98
80
|
end
|
99
81
|
|
100
82
|
it "does not use the parallel profile if config/cucumber.yml does not exist" do
|
101
|
-
|
83
|
+
should_run_with %r{script/cucumber} # TODO this test looks useless...
|
102
84
|
Dir.should_receive(:glob).and_return []
|
103
85
|
call(['xxx'],1,22,{})
|
104
86
|
end
|
@@ -17,107 +17,93 @@ describe ParallelTests::RSpec::Runner do
|
|
17
17
|
ParallelTests::RSpec::Runner.run_tests(*args)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
ParallelTests::
|
22
|
-
call(['xxx'], 0, 22, {})
|
20
|
+
def should_run_with(regex)
|
21
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a =~ regex}
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
ParallelTests::
|
27
|
-
call(['xxx'],1,22,{})
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'sets PARALLEL_TEST_GROUPS so child processes know that they are being run under parallel_tests' do
|
31
|
-
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/PARALLEL_TEST_GROUPS=22/}.and_return mocked_process
|
32
|
-
call(['xxx'],1,22,{})
|
33
|
-
end
|
34
|
-
|
35
|
-
it "allows to override runner executable via PARALLEL_TESTS_EXECUTABLE" do
|
36
|
-
ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
|
37
|
-
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/script\/custom_rspec/}.and_return mocked_process
|
38
|
-
call(['xxx'],1,22,{})
|
39
|
-
ENV.delete('PARALLEL_TESTS_EXECUTABLE')
|
24
|
+
def should_not_run_with(regex)
|
25
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a !~ regex}
|
40
26
|
end
|
41
27
|
|
42
28
|
it "runs with color when called from cmdline" do
|
43
|
-
|
29
|
+
should_run_with %r{ --tty}
|
44
30
|
$stdout.should_receive(:tty?).and_return true
|
45
|
-
call(
|
31
|
+
call('xxx', 1, 22, {})
|
46
32
|
end
|
47
33
|
|
48
34
|
it "runs without color when not called from cmdline" do
|
49
|
-
|
35
|
+
should_not_run_with %r{ --tty}
|
50
36
|
$stdout.should_receive(:tty?).and_return false
|
51
|
-
call(
|
37
|
+
call('xxx', 1, 22, {})
|
52
38
|
end
|
53
39
|
|
54
40
|
it "runs with color for rspec 1 when called for the cmdline" do
|
55
41
|
File.should_receive(:file?).with('script/spec').and_return true
|
56
|
-
ParallelTests::
|
42
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with { |a, b, c, d| d[:env] == {"RSPEC_COLOR" => "1"} }
|
57
43
|
$stdout.should_receive(:tty?).and_return true
|
58
|
-
call(
|
44
|
+
call('xxx', 1, 22, {})
|
59
45
|
end
|
60
46
|
|
61
47
|
it "runs without color for rspec 1 when not called for the cmdline" do
|
62
48
|
File.should_receive(:file?).with('script/spec').and_return true
|
63
|
-
ParallelTests::
|
49
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with { |a, b, c, d| d[:env] == {} }
|
64
50
|
$stdout.should_receive(:tty?).and_return false
|
65
|
-
call(
|
51
|
+
call('xxx', 1, 22, {})
|
66
52
|
end
|
67
53
|
|
68
54
|
it "run bundle exec spec when on bundler rspec 1" do
|
69
55
|
File.stub!(:file?).with('script/spec').and_return false
|
70
56
|
ParallelTests.stub!(:bundler_enabled?).and_return true
|
71
57
|
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "Could not find gem 'rspec-core' in bundler."
|
72
|
-
|
73
|
-
call(
|
58
|
+
should_run_with %r{bundle exec spec}
|
59
|
+
call('xxx', 1, 22, {})
|
74
60
|
end
|
75
61
|
|
76
62
|
it "run bundle exec rspec when on bundler rspec 2" do
|
77
63
|
File.stub!(:file?).with('script/spec').and_return false
|
78
64
|
ParallelTests.stub!(:bundler_enabled?).and_return true
|
79
65
|
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "/foo/bar/rspec-core-2.0.2"
|
80
|
-
|
81
|
-
call(
|
66
|
+
should_run_with %r{bundle exec rspec}
|
67
|
+
call('xxx', 1, 22, {})
|
82
68
|
end
|
83
69
|
|
84
70
|
it "runs script/spec when script/spec can be found" do
|
85
71
|
File.should_receive(:file?).with('script/spec').and_return true
|
86
|
-
|
87
|
-
call(
|
72
|
+
should_run_with %r{script/spec}
|
73
|
+
call('xxx' ,1, 22, {})
|
88
74
|
end
|
89
75
|
|
90
76
|
it "runs spec when script/spec cannot be found" do
|
91
77
|
File.stub!(:file?).with('script/spec').and_return false
|
92
|
-
|
93
|
-
call(
|
78
|
+
should_not_run_with %r{ script/spec}
|
79
|
+
call('xxx', 1, 22, {})
|
94
80
|
end
|
95
81
|
|
96
82
|
it "uses no -O when no opts where found" do
|
97
83
|
File.stub!(:file?).with('spec/spec.opts').and_return false
|
98
|
-
|
99
|
-
call(
|
84
|
+
should_not_run_with %r{spec/spec.opts}
|
85
|
+
call('xxx', 1, 22, {})
|
100
86
|
end
|
101
87
|
|
102
88
|
it "uses -O spec/spec.opts when found (with script/spec)" do
|
103
89
|
File.stub!(:file?).with('script/spec').and_return true
|
104
90
|
File.stub!(:file?).with('spec/spec.opts').and_return true
|
105
|
-
|
106
|
-
call(
|
91
|
+
should_run_with %r{script/spec\s+-O spec/spec.opts}
|
92
|
+
call('xxx', 1, 22, {})
|
107
93
|
end
|
108
94
|
|
109
95
|
it "uses -O spec/parallel_spec.opts when found (with script/spec)" do
|
110
96
|
File.stub!(:file?).with('script/spec').and_return true
|
111
97
|
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
112
|
-
|
113
|
-
call(
|
98
|
+
should_run_with %r{script/spec\s+-O spec/parallel_spec.opts}
|
99
|
+
call('xxx', 1, 22, {})
|
114
100
|
end
|
115
101
|
|
116
102
|
it "uses -O .rspec_parallel when found (with script/spec)" do
|
117
103
|
File.stub!(:file?).with('script/spec').and_return true
|
118
104
|
File.should_receive(:file?).with('.rspec_parallel').and_return true
|
119
|
-
|
120
|
-
call(
|
105
|
+
should_run_with %r{script/spec\s+-O .rspec_parallel}
|
106
|
+
call('xxx', 1, 22, {})
|
121
107
|
end
|
122
108
|
|
123
109
|
it "uses -O spec/parallel_spec.opts with rspec1" do
|
@@ -126,8 +112,8 @@ describe ParallelTests::RSpec::Runner do
|
|
126
112
|
ParallelTests.stub!(:bundler_enabled?).and_return true
|
127
113
|
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "Could not find gem 'rspec-core'."
|
128
114
|
|
129
|
-
|
130
|
-
call(
|
115
|
+
should_run_with %r{spec\s+-O spec/parallel_spec.opts}
|
116
|
+
call('xxx', 1, 22, {})
|
131
117
|
end
|
132
118
|
|
133
119
|
it "uses -O spec/parallel_spec.opts with rspec2" do
|
@@ -136,20 +122,18 @@ describe ParallelTests::RSpec::Runner do
|
|
136
122
|
ParallelTests.stub!(:bundler_enabled?).and_return true
|
137
123
|
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "/foo/bar/rspec-core-2.4.2"
|
138
124
|
|
139
|
-
|
140
|
-
call(
|
125
|
+
should_run_with %r{rspec\s+--color --tty -O spec/parallel_spec.opts}
|
126
|
+
call('xxx', 1, 22, {})
|
141
127
|
end
|
142
128
|
|
143
129
|
it "uses options passed in" do
|
144
|
-
|
145
|
-
call(
|
130
|
+
should_run_with %r{rspec -f n}
|
131
|
+
call('xxx', 1, 22, :test_options => '-f n')
|
146
132
|
end
|
147
133
|
|
148
134
|
it "returns the output" do
|
149
|
-
|
150
|
-
|
151
|
-
ParallelTests::RSpec::Runner.should_receive(:open).and_return io
|
152
|
-
call(['xxx'],1,22,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
135
|
+
ParallelTests::RSpec::Runner.should_receive(:execute_command).and_return :x => 1
|
136
|
+
call('xxx', 1, 22, {}).should == {:x => 1}
|
153
137
|
end
|
154
138
|
end
|
155
139
|
|
@@ -4,57 +4,33 @@ require "parallel_tests/test/runner"
|
|
4
4
|
describe ParallelTests::Test::Runner do
|
5
5
|
test_tests_in_groups(ParallelTests::Test::Runner, 'test', '_test.rb')
|
6
6
|
|
7
|
-
describe
|
7
|
+
describe ".run_tests" do
|
8
8
|
def call(*args)
|
9
9
|
ParallelTests::Test::Runner.run_tests(*args)
|
10
10
|
end
|
11
11
|
|
12
|
-
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
13
|
-
ParallelTests::Test::Runner.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
14
|
-
call(['xxx'],0,22,{})
|
15
|
-
end
|
16
|
-
|
17
|
-
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
18
|
-
ParallelTests::Test::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
19
|
-
call(['xxx'],1,22,{})
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'sets PARALLEL_TEST_GROUPS so child processes know that they are being run under parallel_tests' do
|
23
|
-
ENV['PARALLEL_TEST_PROCESSORS'] = '22'
|
24
|
-
ParallelTests::Test::Runner.should_receive(:open).with{|x,y| x=~/PARALLEL_TEST_GROUPS=22/}.and_return mocked_process
|
25
|
-
call(['xxx'],1,22,{})
|
26
|
-
ENV.delete('PARALLEL_TEST_PROCESSORS')
|
27
|
-
end
|
28
|
-
|
29
12
|
it "allows to override runner executable via PARALLEL_TESTS_EXECUTABLE" do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
13
|
+
begin
|
14
|
+
ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
|
15
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a.include?("script/custom_rspec") }
|
16
|
+
call(['xxx'], 1, 22, {})
|
17
|
+
ensure
|
18
|
+
ENV.delete('PARALLEL_TESTS_EXECUTABLE')
|
19
|
+
end
|
34
20
|
end
|
35
21
|
|
36
22
|
it "uses options" do
|
37
|
-
ParallelTests::Test::Runner.should_receive(:
|
38
|
-
call(['xxx'],1,22
|
23
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a =~ %r{ruby -Itest .* -- -v}}
|
24
|
+
call(['xxx'], 1, 22, :test_options => '-v')
|
39
25
|
end
|
40
26
|
|
41
27
|
it "returns the output" do
|
42
|
-
|
43
|
-
|
44
|
-
ParallelTests::Test::Runner.should_receive(:open).and_return io
|
45
|
-
call(['xxx'],1,22,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
46
|
-
end
|
47
|
-
|
48
|
-
it "does not output to stdout when serializing output" do
|
49
|
-
io = open('spec/spec_helper.rb')
|
50
|
-
$stdout.should_not_receive(:print)
|
51
|
-
$stdout.should_not_receive(:flush)
|
52
|
-
ParallelTests::Test::Runner.should_receive(:open).and_return io
|
53
|
-
call(['xxx'],1,22,{:serialize_stdout => true})[:stdout]
|
28
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).and_return({:x => 1})
|
29
|
+
call(['xxx'], 1, 22, {}).should == {:x => 1}
|
54
30
|
end
|
55
31
|
end
|
56
32
|
|
57
|
-
describe
|
33
|
+
describe ".test_in_groups" do
|
58
34
|
def call(*args)
|
59
35
|
ParallelTests::Test::Runner.tests_in_groups(*args)
|
60
36
|
end
|
@@ -98,7 +74,7 @@ describe ParallelTests::Test::Runner do
|
|
98
74
|
end
|
99
75
|
end
|
100
76
|
|
101
|
-
describe
|
77
|
+
describe ".find_results" do
|
102
78
|
def call(*args)
|
103
79
|
ParallelTests::Test::Runner.find_results(*args)
|
104
80
|
end
|
@@ -150,7 +126,7 @@ EOF
|
|
150
126
|
end
|
151
127
|
end
|
152
128
|
|
153
|
-
describe
|
129
|
+
describe ".find_tests" do
|
154
130
|
def call(*args)
|
155
131
|
ParallelTests::Test::Runner.send(:find_tests, *args)
|
156
132
|
end
|
@@ -268,7 +244,7 @@ EOF
|
|
268
244
|
end
|
269
245
|
end
|
270
246
|
|
271
|
-
describe
|
247
|
+
describe ".summarize_results" do
|
272
248
|
def call(*args)
|
273
249
|
ParallelTests::Test::Runner.summarize_results(*args)
|
274
250
|
end
|
@@ -293,4 +269,155 @@ EOF
|
|
293
269
|
call(['1 xxx 2 yyy']).should == '1 xxx, 2 yyys'
|
294
270
|
end
|
295
271
|
end
|
272
|
+
|
273
|
+
describe ".execute_command" do
|
274
|
+
def call(*args)
|
275
|
+
ParallelTests::Test::Runner.execute_command(*args)
|
276
|
+
end
|
277
|
+
|
278
|
+
def capture_output
|
279
|
+
$stdout, $stderr = StringIO.new, StringIO.new
|
280
|
+
yield
|
281
|
+
[$stdout.string, $stderr.string]
|
282
|
+
ensure
|
283
|
+
$stdout, $stderr = STDOUT, STDERR
|
284
|
+
end
|
285
|
+
|
286
|
+
def run_with_file(content)
|
287
|
+
capture_output do
|
288
|
+
Tempfile.open("xxx") do |f|
|
289
|
+
f.write(content)
|
290
|
+
f.flush
|
291
|
+
yield f.path
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
it "sets process number to 2 for 1" do
|
297
|
+
run_with_file("puts ENV['TEST_ENV_NUMBER']") do |path|
|
298
|
+
result = call("ruby #{path}", 1, 4, {})
|
299
|
+
result.should == {
|
300
|
+
:stdout => "2\n",
|
301
|
+
:stderr => "",
|
302
|
+
:exit_status => 0
|
303
|
+
}
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
it "sets process number to '' for 0" do
|
308
|
+
run_with_file("puts ENV['TEST_ENV_NUMBER'].inspect") do |path|
|
309
|
+
result = call("ruby #{path}", 0, 4, {})
|
310
|
+
result.should == {
|
311
|
+
:stdout => "\"\"\n",
|
312
|
+
:stderr => "",
|
313
|
+
:exit_status => 0
|
314
|
+
}
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'sets PARALLEL_TEST_GROUPS so child processes know that they are being run under parallel_tests' do
|
319
|
+
run_with_file("puts ENV['PARALLEL_TEST_GROUPS']") do |path|
|
320
|
+
result = call("ruby #{path}", 1, 4, {})
|
321
|
+
result.should == {
|
322
|
+
:stdout => "4\n",
|
323
|
+
:stderr => "",
|
324
|
+
:exit_status => 0
|
325
|
+
}
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
it "skips reads from stdin" do
|
330
|
+
if RUBY_VERSION =~ /^1\.8/
|
331
|
+
pending
|
332
|
+
else
|
333
|
+
run_with_file("$stdin.read; puts 123") do |path|
|
334
|
+
result = call("ruby #{path}", 1, 2, {})
|
335
|
+
result.should == {
|
336
|
+
:stdout => "123\n",
|
337
|
+
:stderr => "",
|
338
|
+
:exit_status => 0
|
339
|
+
}
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
it "waits for process to finish" do
|
345
|
+
run_with_file("sleep 0.5; puts 123; sleep 0.5; puts 345") do |path|
|
346
|
+
result = call("ruby #{path}", 1, 4, {})
|
347
|
+
result.should == {
|
348
|
+
:stdout => "123\n345\n",
|
349
|
+
:stderr => "",
|
350
|
+
:exit_status => 0
|
351
|
+
}
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
it "prints output while running" do
|
356
|
+
run_with_file("$stdout.sync = true; puts 123; sleep 0.1; print 345; sleep 0.1; puts 567") do |path|
|
357
|
+
$stdout.should_receive(:print).with("123\n")
|
358
|
+
if RUBY_VERSION =~ /^1\.8/
|
359
|
+
$stdout.should_receive(:print).with("345")
|
360
|
+
$stdout.should_receive(:print).with("567\n")
|
361
|
+
else
|
362
|
+
$stdout.should_receive(:print).with("345567\n")
|
363
|
+
end
|
364
|
+
result = call("ruby #{path}", 1, 4, {})
|
365
|
+
result.should == {
|
366
|
+
:stdout => "123\n345567\n",
|
367
|
+
:stderr => "",
|
368
|
+
:exit_status => 0
|
369
|
+
}
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
it "works with synced stdout" do
|
374
|
+
run_with_file("$stdout.sync = true; puts 123; sleep 0.1; puts 345") do |path|
|
375
|
+
result = call("ruby #{path}", 1, 4, {})
|
376
|
+
result.should == {
|
377
|
+
:stdout => "123\n345\n",
|
378
|
+
:stderr => "",
|
379
|
+
:exit_status => 0
|
380
|
+
}
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
it "does not print to stdout with :serialize_stdout" do
|
385
|
+
run_with_file("puts 123") do |path|
|
386
|
+
$stdout.should_not_receive(:print)
|
387
|
+
result = call("ruby #{path}", 1, 4, :serialize_stdout => true)
|
388
|
+
result.should == {
|
389
|
+
:stdout => "123\n",
|
390
|
+
:stderr => "",
|
391
|
+
:exit_status => 0
|
392
|
+
}
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
it "returns correct exit status" do
|
397
|
+
run_with_file("puts 123; exit 5") do |path|
|
398
|
+
result = call("ruby #{path}", 1, 4, {})
|
399
|
+
result.should == {
|
400
|
+
:stdout => "123\n",
|
401
|
+
:stderr => "",
|
402
|
+
:exit_status => 5
|
403
|
+
}
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
it "prints each stream to the correct stream" do
|
408
|
+
if RUBY_VERSION =~ /^1\.8/
|
409
|
+
pending
|
410
|
+
else
|
411
|
+
out, err = run_with_file("puts 123 ; $stderr.puts 345 ; exit 5") do |path|
|
412
|
+
result = call("ruby #{path}", 1, 4, {})
|
413
|
+
result.should == {
|
414
|
+
:stdout => "123\n",
|
415
|
+
:stderr => "345\n",
|
416
|
+
:exit_status => 5
|
417
|
+
}
|
418
|
+
end
|
419
|
+
err.should == "345\n"
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
296
423
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,47 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_tests
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 51
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 11
|
9
|
+
- 0
|
10
|
+
version: 0.11.0
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Michael Grosser
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2013-04-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: parallel
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ! '>='
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
22
|
-
type: :runtime
|
23
22
|
prerelease: false
|
24
|
-
|
23
|
+
type: :runtime
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
version_requirements: *id001
|
30
34
|
description:
|
31
35
|
email: michael@grosser.it
|
32
|
-
executables:
|
36
|
+
executables:
|
33
37
|
- parallel_cucumber
|
34
38
|
- parallel_rspec
|
35
39
|
- parallel_test
|
36
40
|
extensions: []
|
41
|
+
|
37
42
|
extra_rdoc_files: []
|
38
|
-
|
43
|
+
|
44
|
+
files:
|
39
45
|
- .gitignore
|
40
46
|
- .rspec
|
41
47
|
- .travis.yml
|
@@ -79,34 +85,37 @@ files:
|
|
79
85
|
- spec/parallel_tests_spec.rb
|
80
86
|
- spec/spec_helper.rb
|
81
87
|
homepage: http://github.com/grosser/parallel_tests
|
82
|
-
licenses:
|
88
|
+
licenses:
|
83
89
|
- MIT
|
84
90
|
post_install_message:
|
85
91
|
rdoc_options: []
|
86
|
-
|
92
|
+
|
93
|
+
require_paths:
|
87
94
|
- lib
|
88
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
96
|
none: false
|
90
|
-
requirements:
|
91
|
-
- -
|
92
|
-
- !ruby/object:Gem::Version
|
93
|
-
|
94
|
-
segments:
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
hash: 3
|
101
|
+
segments:
|
95
102
|
- 0
|
96
|
-
|
97
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
version: "0"
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
105
|
none: false
|
99
|
-
requirements:
|
100
|
-
- -
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
|
103
|
-
segments:
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
hash: 3
|
110
|
+
segments:
|
104
111
|
- 0
|
105
|
-
|
112
|
+
version: "0"
|
106
113
|
requirements: []
|
114
|
+
|
107
115
|
rubyforge_project:
|
108
116
|
rubygems_version: 1.8.25
|
109
117
|
signing_key:
|
110
118
|
specification_version: 3
|
111
119
|
summary: Run Test::Unit / RSpec / Cucumber in parallel
|
112
120
|
test_files: []
|
121
|
+
|