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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parallel_tests (0.10.4)
4
+ parallel_tests (0.11.0)
5
5
  parallel
6
6
 
7
7
  GEM
@@ -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
- color = ($stdout.tty? ? 'AUTOTEST=1 ; export AUTOTEST ;' : '')#display color when we are in a terminal
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 = "#{rspec_1_color if version == 1}#{exe} #{options[:test_options]} #{rspec_2_color if version == 2}#{spec_opts} #{test_files*' '}"
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
- 'RSPEC_COLOR=1 ; export RSPEC_COLOR ;' if $stdout.tty?
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 ' if $stdout.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
- prefix = "PARALLEL_TEST_GROUPS=#{ num_processes } ; export PARALLEL_TEST_GROUPS;"
50
- cmd = "#{prefix} TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
51
- f = open("|#{cmd}", 'r')
52
- output = fetch_output(f, options)
53
- f.close
54
- {:stdout => output, :exit_status => $?.exitstatus}
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
- sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
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.fetch_output(process, options)
97
- all = ''
98
- while buffer = process.readpartial(1000000)
99
- all << buffer
100
- unless options[:serialize_stdout]
101
- $stdout.print buffer
102
- $stdout.flush
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)
@@ -1,3 +1,3 @@
1
1
  module ParallelTests
2
- VERSION = Version = '0.10.4'
2
+ VERSION = Version = '0.11.0'
3
3
  end
@@ -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
- it "uses TEST_ENV_NUMBER=blank when called for process 0" do
19
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/script\/custom_rspec/}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec cucumber}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x !~ %r{(script/cucumber)|(bundle exec cucumber)}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* -p default}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* foo bar --profile parallel xxx}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* --profile foo xxx$}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* -p foo xxx$}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* foo bar}}.and_return mocked_process
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
- ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .*}}.and_return mocked_process
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
- it "uses TEST_ENV_NUMBER=blank when called for process 0" do
21
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
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
- it "uses TEST_ENV_NUMBER=2 when called for process 1" do
26
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/ --tty /}.and_return mocked_process
29
+ should_run_with %r{ --tty}
44
30
  $stdout.should_receive(:tty?).and_return true
45
- call(['xxx'],1,22,{})
31
+ call('xxx', 1, 22, {})
46
32
  end
47
33
 
48
34
  it "runs without color when not called from cmdline" do
49
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ / --tty /}.and_return mocked_process
35
+ should_not_run_with %r{ --tty}
50
36
  $stdout.should_receive(:tty?).and_return false
51
- call(['xxx'],1,22,{})
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::RSpec::Runner.should_receive(:open).with{|x,y| x=~/ RSPEC_COLOR=1 /}.and_return mocked_process
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(['xxx'],1,22,{})
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::RSpec::Runner.should_receive(:open).with{|x,y| x !~ / RSPEC_COLOR=1 /}.and_return mocked_process
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(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec spec}}.and_return mocked_process
73
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec rspec}}.and_return mocked_process
81
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec}}.and_return mocked_process
87
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ %r{script/spec}}.and_return mocked_process
93
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ %r{spec/spec.opts}}.and_return mocked_process
99
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/spec.opts}}.and_return mocked_process
106
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
113
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O .rspec_parallel}}.and_return mocked_process
120
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
130
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{rspec\s+ --color --tty -O spec/parallel_spec.opts}}.and_return mocked_process
140
- call(['xxx'],1,22,{})
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
- ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{rspec -f n}}.and_return mocked_process
145
- call(['xxx'],1,22, :test_options => '-f n')
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
- io = open('spec/spec_helper.rb')
150
- $stdout.stub!(:print)
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 :run_tests do
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
- ENV['PARALLEL_TESTS_EXECUTABLE'] = 'script/custom_rspec'
31
- ParallelTests::Test::Runner.should_receive(:open).with{|x,y| x=~/script\/custom_rspec/}.and_return mocked_process
32
- call(['xxx'],1,22,{})
33
- ENV.delete('PARALLEL_TESTS_EXECUTABLE')
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(:open).with{|x,y| x=~ %r{ruby -Itest .* -- -v}}.and_return mocked_process
38
- call(['xxx'],1,22,:test_options => '-v')
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
- io = open('spec/spec_helper.rb')
43
- $stdout.stub!(:print)
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 :test_in_groups do
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 :find_results do
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 :find_tests do
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 :summarize_results do
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
@@ -27,7 +27,7 @@ RSpec.configure do |config|
27
27
  end
28
28
 
29
29
  def mocked_process
30
- open('|cat /dev/null')
30
+ StringIO.new
31
31
  end
32
32
 
33
33
  def size_of(group)
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
- version: 0.10.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
- date: 2013-03-25 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
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
- version_requirements: !ruby/object:Gem::Requirement
23
+ type: :runtime
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
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
- files:
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
- require_paths:
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
- version: '0'
94
- segments:
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ hash: 3
101
+ segments:
95
102
  - 0
96
- hash: -3747523208207304867
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
- version: '0'
103
- segments:
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
104
111
  - 0
105
- hash: -3747523208207304867
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
+