vinted-parallel_tests 0.13.3 → 1.7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Readme.md +86 -47
  3. data/bin/parallel_cucumber +5 -1
  4. data/bin/parallel_rspec +5 -1
  5. data/bin/parallel_spinach +9 -0
  6. data/bin/parallel_test +5 -1
  7. data/lib/parallel_tests.rb +15 -2
  8. data/lib/parallel_tests/cli.rb +115 -35
  9. data/lib/parallel_tests/cucumber/failures_logger.rb +9 -7
  10. data/lib/parallel_tests/cucumber/runner.rb +16 -77
  11. data/lib/parallel_tests/cucumber/scenario_line_logger.rb +52 -0
  12. data/lib/parallel_tests/cucumber/scenarios.rb +34 -0
  13. data/lib/parallel_tests/{cucumber → gherkin}/io.rb +1 -1
  14. data/lib/parallel_tests/{cucumber/gherkin_listener.rb → gherkin/listener.rb} +11 -6
  15. data/lib/parallel_tests/gherkin/runner.rb +116 -0
  16. data/lib/parallel_tests/{cucumber → gherkin}/runtime_logger.rb +2 -2
  17. data/lib/parallel_tests/grouper.rb +34 -17
  18. data/lib/parallel_tests/rspec/failures_logger.rb +22 -14
  19. data/lib/parallel_tests/rspec/logger_base.rb +5 -1
  20. data/lib/parallel_tests/rspec/runner.rb +5 -4
  21. data/lib/parallel_tests/rspec/runtime_logger.rb +10 -5
  22. data/lib/parallel_tests/rspec/summary_logger.rb +11 -11
  23. data/lib/parallel_tests/spinach/runner.rb +19 -0
  24. data/lib/parallel_tests/tasks.rb +41 -18
  25. data/lib/parallel_tests/test/runner.rb +80 -28
  26. data/lib/parallel_tests/test/runtime_logger.rb +86 -55
  27. data/lib/parallel_tests/version.rb +1 -1
  28. metadata +18 -35
  29. data/.gitignore +0 -2
  30. data/.rspec +0 -2
  31. data/.travis.yml +0 -6
  32. data/Gemfile +0 -8
  33. data/Gemfile.lock +0 -48
  34. data/Rakefile +0 -6
  35. data/ReadmeRails2.md +0 -48
  36. data/parallel_tests.gemspec +0 -14
  37. data/spec/integration_spec.rb +0 -285
  38. data/spec/parallel_tests/cli_spec.rb +0 -71
  39. data/spec/parallel_tests/cucumber/failure_logger_spec.rb +0 -43
  40. data/spec/parallel_tests/cucumber/gherkin_listener_spec.rb +0 -97
  41. data/spec/parallel_tests/cucumber/runner_spec.rb +0 -179
  42. data/spec/parallel_tests/grouper_spec.rb +0 -52
  43. data/spec/parallel_tests/rspec/failures_logger_spec.rb +0 -82
  44. data/spec/parallel_tests/rspec/runner_spec.rb +0 -187
  45. data/spec/parallel_tests/rspec/runtime_logger_spec.rb +0 -126
  46. data/spec/parallel_tests/rspec/summary_logger_spec.rb +0 -37
  47. data/spec/parallel_tests/tasks_spec.rb +0 -151
  48. data/spec/parallel_tests/test/runner_spec.rb +0 -413
  49. data/spec/parallel_tests/test/runtime_logger_spec.rb +0 -90
  50. data/spec/parallel_tests_spec.rb +0 -137
  51. data/spec/spec_helper.rb +0 -157
@@ -1,90 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ParallelTests::Test::RuntimeLogger do
4
- describe :writing do
5
- around do |example|
6
- use_temporary_directory_for do
7
- FileUtils.mkdir_p(File.dirname(log))
8
- example.call
9
- end
10
- end
11
-
12
- let(:log) { ParallelTests::Test::Runner.runtime_log }
13
-
14
- it "overwrites the runtime_log file on first log invocation" do
15
- class FakeTest
16
- end
17
- test = FakeTest.new
18
- time = Time.now
19
- File.open(log, 'w'){ |f| f.puts("FooBar") }
20
- ParallelTests::Test::RuntimeLogger.send(:class_variable_set,:@@has_started, false)
21
- ParallelTests::Test::RuntimeLogger.log(test, time, Time.at(time.to_f+2.00))
22
- result = File.read(log)
23
- result.should_not include('FooBar')
24
- result.should include('test/fake_test.rb:2.00')
25
- end
26
-
27
- it "appends to the runtime_log file after first log invocation" do
28
- class FakeTest
29
- end
30
- test = FakeTest.new
31
- class OtherFakeTest
32
- end
33
- other_test = OtherFakeTest.new
34
-
35
- time = Time.now
36
- File.open(log, 'w'){ |f| f.puts("FooBar") }
37
- ParallelTests::Test::RuntimeLogger.send(:class_variable_set,:@@has_started, false)
38
- ParallelTests::Test::RuntimeLogger.log(test, time, Time.at(time.to_f+2.00))
39
- ParallelTests::Test::RuntimeLogger.log(other_test, time, Time.at(time.to_f+2.00))
40
- result = File.read(log)
41
- result.should_not include('FooBar')
42
- result.should include('test/fake_test.rb:2.00')
43
- result.should include('test/other_fake_test.rb:2.00')
44
- end
45
- end
46
-
47
- describe "formatting" do
48
- def with_rails_defined
49
- Object.const_set(:Rails, Module.new)
50
- yield
51
- Object.send(:remove_const, :Rails)
52
- end
53
-
54
- def call(*args)
55
- ParallelTests::Test::RuntimeLogger.send(:message, *args)
56
- end
57
-
58
- it "formats results for simple test names" do
59
- class FakeTest
60
- end
61
- test = FakeTest.new
62
- time = Time.now
63
- call(test, time, Time.at(time.to_f+2.00)).should == 'test/fake_test.rb:2.00'
64
- end
65
-
66
- it "formats results for complex test names" do
67
- class AVeryComplex
68
- class FakeTest
69
- end
70
- end
71
- test = AVeryComplex::FakeTest.new
72
- time = Time.now
73
- call(test, time, Time.at(time.to_f+2.00)).should == 'test/a_very_complex/fake_test.rb:2.00'
74
- end
75
-
76
- it "guesses subdirectory structure for rails test classes" do
77
- with_rails_defined do
78
- class ActionController
79
- class TestCase
80
- end
81
- end
82
- class FakeControllerTest < ActionController::TestCase
83
- end
84
- test = FakeControllerTest.new
85
- time = Time.now
86
- call(test, time, Time.at(time.to_f+2.00)).should == 'test/functional/fake_controller_test.rb:2.00'
87
- end
88
- end
89
- end
90
- end
@@ -1,137 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ParallelTests do
4
- describe ".determine_number_of_processes" do
5
- before do
6
- ENV.delete('PARALLEL_TEST_PROCESSORS')
7
- Parallel.stub(:processor_count).and_return 20
8
- end
9
-
10
- def call(count)
11
- ParallelTests.determine_number_of_processes(count)
12
- end
13
-
14
- it "uses the given count if set" do
15
- call('5').should == 5
16
- end
17
-
18
- it "uses the processor count from Parallel" do
19
- call(nil).should == 20
20
- end
21
-
22
- it "uses the processor count from ENV before Parallel" do
23
- ENV['PARALLEL_TEST_PROCESSORS'] = '22'
24
- call(nil).should == 22
25
- end
26
-
27
- it "does not use blank count" do
28
- call(' ').should == 20
29
- end
30
-
31
- it "does not use blank env" do
32
- ENV['PARALLEL_TEST_PROCESSORS'] = ' '
33
- call(nil).should == 20
34
- end
35
- end
36
-
37
- describe ".bundler_enabled?" do
38
- before do
39
- Object.stub!(:const_defined?).with(:Bundler).and_return false
40
- end
41
-
42
- it "should return false" do
43
- use_temporary_directory_for do
44
- ParallelTests.send(:bundler_enabled?).should == false
45
- end
46
- end
47
-
48
- it "should return true when there is a constant called Bundler" do
49
- use_temporary_directory_for do
50
- Object.stub!(:const_defined?).with(:Bundler).and_return true
51
- ParallelTests.send(:bundler_enabled?).should == true
52
- end
53
- end
54
-
55
- it "should be true when there is a Gemfile" do
56
- use_temporary_directory_for do
57
- FileUtils.touch("Gemfile")
58
- ParallelTests.send(:bundler_enabled?).should == true
59
- end
60
- end
61
-
62
- it "should be true when there is a Gemfile in the parent directory" do
63
- use_temporary_directory_for do
64
- FileUtils.touch(File.join("..", "Gemfile"))
65
- ParallelTests.send(:bundler_enabled?).should == true
66
- end
67
- end
68
- end
69
-
70
- describe ".wait_for_other_processes_to_finish" do
71
- def with_running_processes(count, wait=0.2)
72
- count.times { Thread.new{ `TEST_ENV_NUMBER=1; sleep #{wait}` } }
73
- sleep 0.1
74
- yield
75
- ensure
76
- sleep wait # make sure the threads have finished
77
- end
78
-
79
- it "does not wait if not run in parallel" do
80
- ParallelTests.should_not_receive(:sleep)
81
- ParallelTests.wait_for_other_processes_to_finish
82
- end
83
-
84
- it "stops if only itself is running" do
85
- ENV["TEST_ENV_NUMBER"] = "2"
86
- ParallelTests.should_not_receive(:sleep)
87
- with_running_processes(1) do
88
- ParallelTests.wait_for_other_processes_to_finish
89
- end
90
- end
91
-
92
- it "waits for other processes to finish" do
93
- pending if RUBY_PLATFORM == "java"
94
- ENV["TEST_ENV_NUMBER"] = "2"
95
- counter = 0
96
- ParallelTests.stub(:sleep).with{ sleep 0.1; counter += 1 }
97
- with_running_processes(2, 0.4) do
98
- ParallelTests.wait_for_other_processes_to_finish
99
- end
100
- counter.should == 3
101
- end
102
- end
103
-
104
- describe ".number_of_running_processes" do
105
- it "is 0 for nothing" do
106
- ParallelTests.number_of_running_processes.should == 0
107
- end
108
-
109
- it "is 2 when 2 are running" do
110
- wait = 0.2
111
- 2.times { Thread.new { `TEST_ENV_NUMBER=1; sleep #{wait}` } }
112
- sleep wait / 2
113
- ParallelTests.number_of_running_processes.should == 2
114
- sleep wait
115
- end
116
- end
117
-
118
- describe ".first_process?" do
119
- it "is first if no env is set" do
120
- ParallelTests.first_process?.should == true
121
- end
122
-
123
- it "is first if env is set to blank" do
124
- ENV["TEST_ENV_NUMBER"] = ""
125
- ParallelTests.first_process?.should == true
126
- end
127
-
128
- it "is not first if env is set to something" do
129
- ENV["TEST_ENV_NUMBER"] = "2"
130
- ParallelTests.first_process?.should == false
131
- end
132
- end
133
-
134
- it "has a version" do
135
- ParallelTests::VERSION.should =~ /^\d+\.\d+\.\d+/
136
- end
137
- end
data/spec/spec_helper.rb DELETED
@@ -1,157 +0,0 @@
1
- $LOAD_PATH << File.expand_path("../lib", File.dirname(__FILE__))
2
-
3
- FAKE_RAILS_ROOT = './tmp/pspecs/fixtures'
4
-
5
- require 'tempfile'
6
-
7
- require 'parallel_tests'
8
- require 'parallel_tests/test/runtime_logger'
9
- require 'parallel_tests/rspec/runtime_logger'
10
- require 'parallel_tests/rspec/summary_logger'
11
-
12
-
13
- OutputLogger = Struct.new(:output) do
14
- attr_reader :flock, :flush
15
- def puts(s=nil)
16
- self.output << s.to_s
17
- end
18
- end
19
-
20
- RSpec.configure do |config|
21
- config.filter_run :focus => true
22
- config.run_all_when_everything_filtered = true
23
-
24
- config.after do
25
- ENV.delete("TEST_ENV_NUMBER")
26
- end
27
- end
28
-
29
- def mocked_process
30
- StringIO.new
31
- end
32
-
33
- def size_of(group)
34
- group.inject(0) { |sum, test| sum += File.stat(test).size }
35
- end
36
-
37
- # Uses /tmp/parallel_tests/application as the cwd so we can create and remove
38
- # files as we want to. After execution it changes cwd back to the original one.
39
- def use_temporary_directory_for
40
- require 'fileutils'
41
-
42
- dir = File.join("/tmp", "parallel_tests")
43
- new_dir = File.join(dir, "application")
44
-
45
- begin
46
- # just in case the temporary dir already exists
47
- FileUtils.rm_rf(dir) if File.exists?(dir)
48
-
49
- # create the temporary directory
50
- FileUtils.mkdir_p(new_dir)
51
-
52
- # chdir changes cwd back to the original one after it is done
53
- Dir.chdir(new_dir) do
54
- yield
55
- end
56
- ensure
57
- FileUtils.rm_rf(dir) if File.exists?(dir)
58
- end
59
- end
60
-
61
- def test_tests_in_groups(klass, folder, suffix)
62
- test_root = "#{FAKE_RAILS_ROOT}/#{folder}"
63
-
64
- describe :tests_in_groups do
65
- before do
66
- system "rm -rf #{FAKE_RAILS_ROOT}; mkdir -p #{test_root}/temp"
67
-
68
- @files = [0,1,2,3,4,5,6,7].map do |i|
69
- size = 99
70
- file = "#{test_root}/temp/x#{i}#{suffix}"
71
- File.open(file, 'w') { |f| f.puts 'x' * size }
72
- file
73
- end
74
-
75
- @log = klass.runtime_log
76
- `mkdir -p #{File.dirname(@log)}`
77
- `rm -f #{@log}`
78
- end
79
-
80
- after do
81
- `rm -f #{@log}`
82
- end
83
-
84
- def setup_runtime_log
85
- File.open(@log,'w') do |f|
86
- @files[1..-1].each{|file| f.puts "#{file}:#{@files.index(file)}"}
87
- f.puts "#{@files[0]}:10"
88
- end
89
- end
90
-
91
- it "groups when given an array of files" do
92
- list_of_files = Dir["#{test_root}/**/*#{suffix}"]
93
- found = klass.send(:with_runtime_info, list_of_files)
94
- found.should =~ list_of_files.map{ |file| [file, File.stat(file).size]}
95
- end
96
-
97
- it "finds all tests" do
98
- found = klass.tests_in_groups([test_root], 1)
99
- all = [ Dir["#{test_root}/**/*#{suffix}"] ]
100
- (found.flatten - all.flatten).should == []
101
- end
102
-
103
- it "partitions them into groups by equal size" do
104
- groups = klass.tests_in_groups([test_root], 2)
105
- groups.map{|g| size_of(g)}.should == [400, 400]
106
- end
107
-
108
- it 'should partition correctly with a group size of 4' do
109
- groups = klass.tests_in_groups([test_root], 4)
110
- groups.map{|g| size_of(g)}.should == [200, 200, 200, 200]
111
- end
112
-
113
- it 'should partition correctly with an uneven group size' do
114
- groups = klass.tests_in_groups([test_root], 3)
115
- groups.map{|g| size_of(g)}.should =~ [300, 300, 200]
116
- end
117
-
118
- it "partitions by runtime when runtime-data is available" do
119
- klass.stub!(:puts)
120
- setup_runtime_log
121
-
122
- groups = klass.tests_in_groups([test_root], 2)
123
- groups.size.should == 2
124
- # 10 + 1 + 3 + 5 = 19
125
- groups[0].should == [@files[0],@files[1],@files[3],@files[5]]
126
- # 2 + 4 + 6 + 7 = 19
127
- groups[1].should == [@files[2],@files[4],@files[6],@files[7]]
128
- end
129
-
130
- it "alpha-sorts partitions when runtime-data is available" do
131
- klass.stub!(:puts)
132
- setup_runtime_log
133
-
134
- groups = klass.tests_in_groups([test_root], 2)
135
- groups.size.should == 2
136
-
137
- groups[0].should == groups[0].sort
138
- groups[1].should == groups[1].sort
139
- end
140
-
141
- it "partitions by round-robin when not sorting" do
142
- files = ["file1.rb", "file2.rb", "file3.rb", "file4.rb"]
143
- klass.should_receive(:find_tests).and_return(files)
144
- groups = klass.tests_in_groups(files, 2, :group_by => :found).sort
145
- groups[0].should == ["file1.rb", "file3.rb"]
146
- groups[1].should == ["file2.rb", "file4.rb"]
147
- end
148
-
149
- it "alpha-sorts partitions when not sorting by runtime" do
150
- files = %w[q w e r t y u i o p a s d f g h j k l z x c v b n m]
151
- klass.should_receive(:find_tests).and_return(files)
152
- groups = klass.tests_in_groups(files, 2, :group_by => :found).sort
153
- groups[0].should == groups[0].sort
154
- groups[1].should == groups[1].sort
155
- end
156
- end
157
- end