parallel_tests 0.10.2 → 0.10.3

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 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