phene-parallel_tests 0.6.2

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.
@@ -0,0 +1,212 @@
1
+ require 'spec_helper'
2
+
3
+ describe ParallelTests do
4
+ test_tests_in_groups(ParallelTests, 'test', '_test.rb')
5
+
6
+ describe :parse_rake_args do
7
+ it "should return the count" do
8
+ args = {:count => 2}
9
+ ParallelTests.parse_rake_args(args).should == [2, '', ""]
10
+ end
11
+
12
+ it "should default to the prefix" do
13
+ args = {:count => "models"}
14
+ ParallelTests.parse_rake_args(args).should == [Parallel.processor_count, "models", ""]
15
+ end
16
+
17
+ it "should return the count and pattern" do
18
+ args = {:count => 2, :pattern => "models"}
19
+ ParallelTests.parse_rake_args(args).should == [2, "models", ""]
20
+ end
21
+
22
+ it "should return the count, pattern, and options" do
23
+ args = {:count => 2, :pattern => "plain", :options => "-p default" }
24
+ ParallelTests.parse_rake_args(args).should == [2, "plain", "-p default"]
25
+ end
26
+ end
27
+
28
+ describe :run_tests do
29
+ it "uses TEST_ENV_NUMBER=blank when called for process 0" do
30
+ ParallelTests.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
31
+ ParallelTests.run_tests(['xxx'],0,{})
32
+ end
33
+
34
+ it "uses TEST_ENV_NUMBER=2 when called for process 1" do
35
+ ParallelTests.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
36
+ ParallelTests.run_tests(['xxx'],1,{})
37
+ end
38
+
39
+ it "uses options" do
40
+ ParallelTests.should_receive(:open).with{|x,y| x=~ %r{ruby -Itest .* - -v}}.and_return mocked_process
41
+ ParallelTests.run_tests(['xxx'],1,:test_options => '-v')
42
+ end
43
+
44
+ it "returns the output" do
45
+ io = open('spec/spec_helper.rb')
46
+ ParallelTests.stub!(:print)
47
+ ParallelTests.should_receive(:open).and_return io
48
+ ParallelTests.run_tests(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
49
+ end
50
+ end
51
+
52
+ describe :test_in_groups do
53
+ it "does not sort when passed false do_sort option" do
54
+ ParallelTests.should_not_receive(:smallest_first)
55
+ ParallelTests.tests_in_groups [], 1, :no_sort => true
56
+ end
57
+
58
+ it "does sort when not passed do_sort option" do
59
+ ParallelTests.stub!(:tests_with_runtime).and_return([])
60
+ ParallelTests::Grouper.should_receive(:smallest_first).and_return([])
61
+ ParallelTests.tests_in_groups [], 1
62
+ end
63
+ end
64
+
65
+ describe :find_results do
66
+ it "finds multiple results in test output" do
67
+ output = <<EOF
68
+ Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
69
+ Started
70
+ ..............
71
+ Finished in 0.145069 seconds.
72
+
73
+ 10 tests, 20 assertions, 0 failures, 0 errors
74
+ Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
75
+ Started
76
+ ..............
77
+ Finished in 0.145069 seconds.
78
+
79
+ 14 tests, 20 assertions, 0 failures, 0 errors
80
+
81
+ EOF
82
+
83
+ ParallelTests.find_results(output).should == ['10 tests, 20 assertions, 0 failures, 0 errors','14 tests, 20 assertions, 0 failures, 0 errors']
84
+ end
85
+
86
+ it "is robust against scrambeled output" do
87
+ output = <<EOF
88
+ Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
89
+ Started
90
+ ..............
91
+ Finished in 0.145069 seconds.
92
+
93
+ 10 tests, 20 assertions, 0 failures, 0 errors
94
+ Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
95
+ Started
96
+ ..............
97
+ Finished in 0.145069 seconds.
98
+
99
+ 14 te.dsts, 20 assertions, 0 failures, 0 errors
100
+ EOF
101
+
102
+ ParallelTests.find_results(output).should == ['10 tests, 20 assertions, 0 failures, 0 errors','14 tedsts, 20 assertions, 0 failures, 0 errors']
103
+ end
104
+ end
105
+
106
+ describe :bundler_enabled? do
107
+ before do
108
+ Object.stub!(:const_defined?).with(:Bundler).and_return false
109
+ end
110
+
111
+ it "should return false" do
112
+ use_temporary_directory_for do
113
+ ParallelTests.send(:bundler_enabled?).should == false
114
+ end
115
+ end
116
+
117
+ it "should return true when there is a constant called Bundler" do
118
+ use_temporary_directory_for do
119
+ Object.stub!(:const_defined?).with(:Bundler).and_return true
120
+ ParallelTests.send(:bundler_enabled?).should == true
121
+ end
122
+ end
123
+
124
+ it "should be true when there is a Gemfile" do
125
+ use_temporary_directory_for do
126
+ FileUtils.touch("Gemfile")
127
+ ParallelTests.send(:bundler_enabled?).should == true
128
+ end
129
+ end
130
+
131
+ it "should be true when there is a Gemfile in the parent directory" do
132
+ use_temporary_directory_for do
133
+ FileUtils.touch(File.join("..", "Gemfile"))
134
+ ParallelTests.send(:bundler_enabled?).should == true
135
+ end
136
+ end
137
+ end
138
+
139
+ describe :find_tests do
140
+ it "returns if root is an array" do
141
+ ParallelTests.send(:find_tests, [1]).should == [1]
142
+ end
143
+
144
+ it "finds all test files" do
145
+ begin
146
+ root = "/tmp/test-find_tests-#{rand(999)}"
147
+ `mkdir #{root}`
148
+ `mkdir #{root}/a`
149
+ `mkdir #{root}/b`
150
+ `touch #{root}/x_test.rb`
151
+ `touch #{root}/a/x_test.rb`
152
+ `touch #{root}/a/test.rb`
153
+ `touch #{root}/b/y_test.rb`
154
+ `touch #{root}/b/test.rb`
155
+ `ln -s #{root}/b #{root}/c`
156
+ `ln -s #{root}/b #{root}/a/`
157
+ ParallelTests.send(:find_tests, root).sort.should == [
158
+ "#{root}/a/b/y_test.rb",
159
+ "#{root}/a/x_test.rb",
160
+ "#{root}/b/y_test.rb",
161
+ "#{root}/c/y_test.rb",
162
+ "#{root}/x_test.rb"
163
+ ]
164
+ ensure
165
+ `rm -rf #{root}`
166
+ end
167
+ end
168
+
169
+ it "finds files by pattern" do
170
+ begin
171
+ root = "/tmp/test-find_tests-#{rand(999)}"
172
+ `mkdir #{root}`
173
+ `mkdir #{root}/a`
174
+ `touch #{root}/a/x_test.rb`
175
+ `touch #{root}/a/y_test.rb`
176
+ `touch #{root}/a/z_test.rb`
177
+ ParallelTests.send(:find_tests, root, :pattern => '^a/(y|z)_test').sort.should == [
178
+ "#{root}/a/y_test.rb",
179
+ "#{root}/a/z_test.rb",
180
+ ]
181
+ ensure
182
+ `rm -rf #{root}`
183
+ end
184
+ end
185
+ end
186
+
187
+ describe :summarize_results do
188
+ it "adds results" do
189
+ ParallelTests.summarize_results(['1 foo 3 bar','2 foo 5 bar']).should == '8 bars, 3 foos'
190
+ end
191
+
192
+ it "adds results with braces" do
193
+ ParallelTests.summarize_results(['1 foo(s) 3 bar(s)','2 foo 5 bar']).should == '8 bars, 3 foos'
194
+ end
195
+
196
+ it "adds same results with plurals" do
197
+ ParallelTests.summarize_results(['1 foo 3 bar','2 foos 5 bar']).should == '8 bars, 3 foos'
198
+ end
199
+
200
+ it "adds non-similar results" do
201
+ ParallelTests.summarize_results(['1 xxx 2 yyy','1 xxx 2 zzz']).should == '2 xxxs, 2 yyys, 2 zzzs'
202
+ end
203
+
204
+ it "does not pluralize 1" do
205
+ ParallelTests.summarize_results(['1 xxx 2 yyy']).should == '1 xxx, 2 yyys'
206
+ end
207
+ end
208
+
209
+ it "has a version" do
210
+ ParallelTests::VERSION.should =~ /^\d+\.\d+\.\d+$/
211
+ end
212
+ end
@@ -0,0 +1,115 @@
1
+ # ---- requirements
2
+ $LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
3
+ require 'rubygems'
4
+
5
+ FAKE_RAILS_ROOT = '/tmp/pspecs/fixtures'
6
+
7
+ require 'parallel_specs'
8
+ require 'parallel_cucumber'
9
+
10
+ def mocked_process
11
+ open('|cat /dev/null')
12
+ end
13
+
14
+ def size_of(group)
15
+ group.inject(0) { |sum, test| sum += File.stat(test).size }
16
+ end
17
+
18
+ # Uses /tmp/parallel_tests/application as the cwd so we can create and remove
19
+ # files as we want to. After execution it changes cwd back to the original one.
20
+ def use_temporary_directory_for
21
+ require 'fileutils'
22
+
23
+ dir = File.join("/tmp", "parallel_tests")
24
+ new_dir = File.join(dir, "application")
25
+
26
+ begin
27
+ # just in case the temporary dir already exists
28
+ FileUtils.rm_rf(dir) if File.exists?(dir)
29
+
30
+ # create the temporary directory
31
+ FileUtils.mkdir_p(new_dir)
32
+
33
+ # chdir changes cwd back to the original one after it is done
34
+ Dir.chdir(new_dir) do
35
+ yield
36
+ end
37
+ ensure
38
+ FileUtils.rm_rf(dir) if File.exists?(dir)
39
+ end
40
+ end
41
+
42
+ def test_tests_in_groups(klass, folder, suffix)
43
+ test_root = "#{FAKE_RAILS_ROOT}/#{folder}"
44
+
45
+ describe :tests_in_groups do
46
+ before :all do
47
+ system "rm -rf #{FAKE_RAILS_ROOT}; mkdir -p #{test_root}/temp"
48
+
49
+ @files = [0,1,2,3,4,5,6,7].map do |i|
50
+ size = 99
51
+ file = "#{test_root}/temp/x#{i}#{suffix}"
52
+ File.open(file, 'w') { |f| f.puts 'x' * size }
53
+ file
54
+ end
55
+
56
+ @log = klass.runtime_log
57
+ `mkdir -p #{File.dirname(@log)}`
58
+ `rm -f #{@log}`
59
+ end
60
+
61
+ after :all do
62
+ `rm -f #{klass.runtime_log}`
63
+ end
64
+
65
+ it "groups when given an array of files" do
66
+ list_of_files = Dir["#{test_root}/**/*#{suffix}"]
67
+ found = klass.with_runtime_info(list_of_files)
68
+ found.should =~ list_of_files.map{ |file| [file, File.stat(file).size]}
69
+ end
70
+
71
+ it "finds all tests" do
72
+ found = klass.tests_in_groups(test_root, 1)
73
+ all = [ Dir["#{test_root}/**/*#{suffix}"] ]
74
+ (found.flatten - all.flatten).should == []
75
+ end
76
+
77
+ it "partitions them into groups by equal size" do
78
+ groups = klass.tests_in_groups(test_root, 2)
79
+ groups.map{|g| size_of(g)}.should == [400, 400]
80
+ end
81
+
82
+ it 'should partition correctly with a group size of 4' do
83
+ groups = klass.tests_in_groups(test_root, 4)
84
+ groups.map{|g| size_of(g)}.should == [200, 200, 200, 200]
85
+ end
86
+
87
+ it 'should partition correctly with an uneven group size' do
88
+ groups = klass.tests_in_groups(test_root, 3)
89
+ groups.map{|g| size_of(g)}.should =~ [300, 300, 200]
90
+ end
91
+
92
+ it "partitions by runtime when runtime-data is available" do
93
+ klass.stub!(:puts)
94
+ File.open(@log,'w') do |f|
95
+ @files[1..-1].each{|file| f.puts "#{file}:#{@files.index(file)}"}
96
+ f.puts "#{@files[0]}:10"
97
+ end
98
+
99
+ groups = klass.tests_in_groups(test_root, 2)
100
+ groups.size.should == 2
101
+ # 10 + 5 + 3 + 1 = 19
102
+ groups[0].should == [@files[0],@files[5],@files[3],@files[1]]
103
+ # 7 + 6 + 4 + 2 = 19
104
+ groups[1].should == [@files[7],@files[6],@files[4],@files[2]]
105
+ end
106
+
107
+ it "partitions by round-robin when not sorting" do
108
+ files = ["file1.rb", "file2.rb", "file3.rb", "file4.rb"]
109
+ klass.should_receive(:find_tests).and_return(files)
110
+ groups = klass.tests_in_groups(files, 2, :no_sort => true)
111
+ groups[0].should == ["file1.rb", "file3.rb"]
112
+ groups[1].should == ["file2.rb", "file4.rb"]
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phene-parallel_tests
3
+ version: !ruby/object:Gem::Version
4
+ hash: 3
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 2
10
+ version: 0.6.2
11
+ platform: ruby
12
+ authors:
13
+ - Michael Grosser
14
+ - Geoffrey Hichborn
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-08-14 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: parallel
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description:
36
+ email: grosser.michael@gmail.com
37
+ executables:
38
+ - parallel_cucumber
39
+ - parallel_test
40
+ - parallel_spec
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - Gemfile
47
+ - Gemfile.lock
48
+ - Rakefile
49
+ - Readme.md
50
+ - VERSION
51
+ - bin/parallel_cucumber
52
+ - bin/parallel_spec
53
+ - bin/parallel_test
54
+ - lib/parallel_cucumber.rb
55
+ - lib/parallel_cucumber/runtime_logger.rb
56
+ - lib/parallel_specs.rb
57
+ - lib/parallel_specs/spec_failures_logger.rb
58
+ - lib/parallel_specs/spec_logger_base.rb
59
+ - lib/parallel_specs/spec_runtime_logger.rb
60
+ - lib/parallel_specs/spec_summary_logger.rb
61
+ - lib/parallel_tests.rb
62
+ - lib/parallel_tests/grouper.rb
63
+ - lib/parallel_tests/railtie.rb
64
+ - lib/parallel_tests/tasks.rb
65
+ - lib/tasks/parallel_tests.rake
66
+ - parallel_tests.gemspec
67
+ - spec/integration_spec.rb
68
+ - spec/parallel_cucumber_spec.rb
69
+ - spec/parallel_specs_spec.rb
70
+ - spec/parallel_tests_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: http://github.com/grosser/parallel_tests
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.10
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Run tests / specs / features in parallel
105
+ test_files: []
106
+