parallel_tests 0.10.2 → 0.10.3

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,8 +1,8 @@
1
- source 'https://rubygems.org'
1
+ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  gem 'bump'
5
- gem 'test-unit', :platform => :ruby_19
5
+ gem 'test-unit'
6
6
  gem 'rspec', '>=2.4'
7
7
  gem 'cucumber'
8
8
  gem 'rake'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parallel_tests (0.10.2)
4
+ parallel_tests (0.10.3)
5
5
  parallel
6
6
 
7
7
  GEM
@@ -19,7 +19,7 @@ GEM
19
19
  gherkin (2.7.6)
20
20
  json (>= 1.4.6)
21
21
  json (1.7.5)
22
- parallel (0.6.2)
22
+ parallel (0.6.3)
23
23
  rake (10.0.3)
24
24
  rspec (2.12.0)
25
25
  rspec-core (~> 2.12.0)
data/Readme.md CHANGED
@@ -165,6 +165,7 @@ Options are:
165
165
  -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUM']
166
166
  -o, --test-options '[OPTIONS]' execute test commands with those options
167
167
  -t, --type [TYPE] test(default) / rspec / cucumber
168
+ --serialize-stdout Serialize stdout output, nothing will be written until everything is done
168
169
  --non-parallel execute same commands but do not in parallel, needs --exec
169
170
  --no-symlinks Do not traverse symbolic links to find test files
170
171
  --ignore-tags [PATTERN] When counting steps ignore scenarios with tags that match this pattern
@@ -259,6 +260,7 @@ inspired by [pivotal labs](http://pivotallabs.com/users/miked/blog/articles/849-
259
260
  - [Joseph Shraibman](https://github.com/jshraibman-mdsol)
260
261
  - [David Davis](https://github.com/daviddavis)
261
262
  - [Ari Pollak](https://github.com/aripollak)
263
+ - [Aaron Jensen](https://github.com/aaronjensen)
262
264
 
263
265
  [Michael Grosser](http://grosser.it)<br/>
264
266
  michael@grosser.it<br/>
@@ -1,4 +1,5 @@
1
1
  require 'optparse'
2
+ require 'tempfile'
2
3
 
3
4
  module ParallelTests
4
5
  class CLI
@@ -17,6 +18,16 @@ module ParallelTests
17
18
 
18
19
  private
19
20
 
21
+ def execute_in_parallel(items, num_processes, options)
22
+ Tempfile.open 'parallel_tests-lock' do |lock|
23
+ return Parallel.map(items, :in_processes => num_processes) do |item|
24
+ result = yield(item)
25
+ report_output(result, lock) if options[:serialize_stdout]
26
+ result
27
+ end
28
+ end
29
+ end
30
+
20
31
  def run_tests_in_parallel(num_processes, options)
21
32
  test_results = nil
22
33
 
@@ -24,7 +35,7 @@ module ParallelTests
24
35
  groups = @runner.tests_in_groups(options[:files], num_processes, options)
25
36
  report_number_of_tests(groups)
26
37
 
27
- test_results = Parallel.map(groups, :in_processes => groups.size) do |group|
38
+ test_results = execute_in_parallel(groups, groups.size, options) do |group|
28
39
  run_tests(group, groups.index(group), num_processes, options)
29
40
  end
30
41
 
@@ -42,6 +53,14 @@ module ParallelTests
42
53
  end
43
54
  end
44
55
 
56
+ def report_output(result, lock)
57
+ lock.flock File::LOCK_EX
58
+ $stdout.puts result[:stdout]
59
+ $stdout.flush
60
+ ensure
61
+ lock.flock File::LOCK_UN
62
+ end
63
+
45
64
  def report_results(test_results)
46
65
  results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
47
66
  puts ""
@@ -105,6 +124,7 @@ TEXT
105
124
  abort
106
125
  end
107
126
  end
127
+ opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
108
128
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
109
129
  opts.on("--no-symlinks", "Do not traverse symbolic links to find test files") { options[:symlinks] = false }
110
130
  opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
@@ -133,11 +153,11 @@ TEXT
133
153
  runs = (0...num_processes).to_a
134
154
  results = if options[:non_parallel]
135
155
  runs.map do |i|
136
- ParallelTests::Test::Runner.execute_command(command, i, num_processes)
156
+ ParallelTests::Test::Runner.execute_command(command, i, num_processes, options)
137
157
  end
138
158
  else
139
- Parallel.map(runs, :in_processes => num_processes) do |i|
140
- ParallelTests::Test::Runner.execute_command(command, i, num_processes)
159
+ execute_in_parallel(runs, num_processes, options) do |i|
160
+ ParallelTests::Test::Runner.execute_command(command, i, num_processes, options)
141
161
  end
142
162
  end.flatten
143
163
 
@@ -15,7 +15,7 @@ module ParallelTests
15
15
  cucumber_opts(options[:test_options]),
16
16
  *test_files
17
17
  ].compact.join(" ")
18
- execute_command(cmd, process_number, num_processes)
18
+ execute_command(cmd, process_number, num_processes, options)
19
19
  end
20
20
 
21
21
  def self.executable
@@ -9,7 +9,7 @@ module ParallelTests
9
9
  exe = executable # expensive, so we cache
10
10
  version = (exe =~ /\brspec\b/ ? 2 : 1)
11
11
  cmd = "#{rspec_1_color if version == 1}#{exe} #{options[:test_options]} #{rspec_2_color if version == 2}#{spec_opts} #{test_files*' '}"
12
- execute_command(cmd, process_number, num_processes)
12
+ execute_command(cmd, process_number, num_processes, options)
13
13
  end
14
14
 
15
15
  def self.executable
@@ -24,7 +24,7 @@ module ParallelTests
24
24
  def self.run_tests(test_files, process_number, num_processes, options)
25
25
  require_list = test_files.map { |filename| %{"#{File.expand_path filename}"} }.join(",")
26
26
  cmd = "ruby -Itest -e '[#{require_list}].each {|f| require f }' -- #{options[:test_options]}"
27
- execute_command(cmd, process_number, num_processes)
27
+ execute_command(cmd, process_number, num_processes, options)
28
28
  end
29
29
 
30
30
  def self.line_is_result?(line)
@@ -45,11 +45,11 @@ module ParallelTests
45
45
  Grouper.in_even_groups_by_size(tests, num_groups, options)
46
46
  end
47
47
 
48
- def self.execute_command(cmd, process_number, num_processes)
48
+ def self.execute_command(cmd, process_number, num_processes, options)
49
49
  prefix = "PARALLEL_TEST_GROUPS=#{ num_processes } ; export PARALLEL_TEST_GROUPS;"
50
50
  cmd = "#{prefix} TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
51
51
  f = open("|#{cmd}", 'r')
52
- output = fetch_output(f)
52
+ output = fetch_output(f, options)
53
53
  f.close
54
54
  {:stdout => output, :exit_status => $?.exitstatus}
55
55
  end
@@ -85,12 +85,14 @@ module ParallelTests
85
85
  end
86
86
 
87
87
  # read output of the process and print it in chunks
88
- def self.fetch_output(process)
88
+ def self.fetch_output(process, options)
89
89
  all = ''
90
90
  while buffer = process.readpartial(1000000)
91
91
  all << buffer
92
- $stdout.print buffer
93
- $stdout.flush
92
+ unless options[:serialize_stdout]
93
+ $stdout.print buffer
94
+ $stdout.flush
95
+ end
94
96
  end rescue EOFError
95
97
 
96
98
  all
@@ -1,3 +1,3 @@
1
1
  module ParallelTests
2
- VERSION = Version = '0.10.2'
2
+ VERSION = Version = '0.10.3'
3
3
  end
@@ -78,6 +78,15 @@ describe 'CLI' do
78
78
  result.scan('2 examples, 1 failure').size.should == 1
79
79
  end
80
80
 
81
+ it "can serialize stdout" do
82
+ write 'spec/xxx_spec.rb', '5.times{describe("it"){it("should"){sleep 0.01; puts "TEST1"}}}'
83
+ write 'spec/xxx2_spec.rb', 'sleep 0.01; 5.times{describe("it"){it("should"){sleep 0.01; puts "TEST2"}}}'
84
+ result = run_tests "spec", :type => 'rspec', :add => "--serialize-stdout"
85
+
86
+ result.should_not =~ /TEST1.*TEST2.*TEST1/m
87
+ result.should_not =~ /TEST2.*TEST1.*TEST2/m
88
+ end
89
+
81
90
  context "with given commands" do
82
91
  it "can exec given commands with ENV['TEST_ENV_NUM']" do
83
92
  result = `#{executable} -e 'ruby -e "print ENV[:TEST_ENV_NUMBER.to_s].to_i"' -n 4`
@@ -89,6 +98,12 @@ describe 'CLI' do
89
98
  result.split("\n").should == %w["" "2" "3" "4"]
90
99
  end
91
100
 
101
+ it "can serialize stdout" do
102
+ result = `#{executable} -e 'ruby -e "5.times{sleep 0.01;puts ENV[:TEST_ENV_NUMBER.to_s].to_i;STDOUT.flush}"' -n 2 --serialize-stdout`
103
+ result.should_not =~ /0.*2.*0/m
104
+ result.should_not =~ /2.*0.*2/m
105
+ end
106
+
92
107
  it "exists with success if all sub-processes returned success" do
93
108
  system("#{executable} -e 'cat /dev/null' -n 4").should == true
94
109
  end
@@ -37,6 +37,14 @@ describe ParallelTests::Test::Runner do
37
37
  ParallelTests::Test::Runner.should_receive(:open).and_return io
38
38
  call(['xxx'],1,22,{})[:stdout].should =~ /\$LOAD_PATH << File/
39
39
  end
40
+
41
+ it "does not output to stdout when serializing output" do
42
+ io = open('spec/spec_helper.rb')
43
+ $stdout.should_not_receive(:print)
44
+ $stdout.should_not_receive(:flush)
45
+ ParallelTests::Test::Runner.should_receive(:open).and_return io
46
+ call(['xxx'],1,22,{:serialize_stdout => true})[:stdout]
47
+ end
40
48
  end
41
49
 
42
50
  describe :test_in_groups do
@@ -18,6 +18,9 @@ OutputLogger = Struct.new(:output) do
18
18
  end
19
19
 
20
20
  RSpec.configure do |config|
21
+ config.filter_run :focus => true
22
+ config.run_all_when_everything_filtered = true
23
+
21
24
  config.after do
22
25
  ENV.delete("TEST_ENV_NUMBER")
23
26
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallel_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.2
4
+ version: 0.10.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-19 00:00:00.000000000 Z
12
+ date: 2013-03-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parallel
@@ -93,7 +93,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
93
  version: '0'
94
94
  segments:
95
95
  - 0
96
- hash: 2796849733728312962
96
+ hash: -3820588893429922123
97
97
  required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  none: false
99
99
  requirements:
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  version: '0'
103
103
  segments:
104
104
  - 0
105
- hash: 2796849733728312962
105
+ hash: -3820588893429922123
106
106
  requirements: []
107
107
  rubyforge_project:
108
108
  rubygems_version: 1.8.25