vinted-parallel_tests 0.13.3 → 1.7.0.1
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.
- checksums.yaml +4 -4
- data/Readme.md +86 -47
- data/bin/parallel_cucumber +5 -1
- data/bin/parallel_rspec +5 -1
- data/bin/parallel_spinach +9 -0
- data/bin/parallel_test +5 -1
- data/lib/parallel_tests.rb +15 -2
- data/lib/parallel_tests/cli.rb +115 -35
- data/lib/parallel_tests/cucumber/failures_logger.rb +9 -7
- data/lib/parallel_tests/cucumber/runner.rb +16 -77
- data/lib/parallel_tests/cucumber/scenario_line_logger.rb +52 -0
- data/lib/parallel_tests/cucumber/scenarios.rb +34 -0
- data/lib/parallel_tests/{cucumber → gherkin}/io.rb +1 -1
- data/lib/parallel_tests/{cucumber/gherkin_listener.rb → gherkin/listener.rb} +11 -6
- data/lib/parallel_tests/gherkin/runner.rb +116 -0
- data/lib/parallel_tests/{cucumber → gherkin}/runtime_logger.rb +2 -2
- data/lib/parallel_tests/grouper.rb +34 -17
- data/lib/parallel_tests/rspec/failures_logger.rb +22 -14
- data/lib/parallel_tests/rspec/logger_base.rb +5 -1
- data/lib/parallel_tests/rspec/runner.rb +5 -4
- data/lib/parallel_tests/rspec/runtime_logger.rb +10 -5
- data/lib/parallel_tests/rspec/summary_logger.rb +11 -11
- data/lib/parallel_tests/spinach/runner.rb +19 -0
- data/lib/parallel_tests/tasks.rb +41 -18
- data/lib/parallel_tests/test/runner.rb +80 -28
- data/lib/parallel_tests/test/runtime_logger.rb +86 -55
- data/lib/parallel_tests/version.rb +1 -1
- metadata +18 -35
- data/.gitignore +0 -2
- data/.rspec +0 -2
- data/.travis.yml +0 -6
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -48
- data/Rakefile +0 -6
- data/ReadmeRails2.md +0 -48
- data/parallel_tests.gemspec +0 -14
- data/spec/integration_spec.rb +0 -285
- data/spec/parallel_tests/cli_spec.rb +0 -71
- data/spec/parallel_tests/cucumber/failure_logger_spec.rb +0 -43
- data/spec/parallel_tests/cucumber/gherkin_listener_spec.rb +0 -97
- data/spec/parallel_tests/cucumber/runner_spec.rb +0 -179
- data/spec/parallel_tests/grouper_spec.rb +0 -52
- data/spec/parallel_tests/rspec/failures_logger_spec.rb +0 -82
- data/spec/parallel_tests/rspec/runner_spec.rb +0 -187
- data/spec/parallel_tests/rspec/runtime_logger_spec.rb +0 -126
- data/spec/parallel_tests/rspec/summary_logger_spec.rb +0 -37
- data/spec/parallel_tests/tasks_spec.rb +0 -151
- data/spec/parallel_tests/test/runner_spec.rb +0 -413
- data/spec/parallel_tests/test/runtime_logger_spec.rb +0 -90
- data/spec/parallel_tests_spec.rb +0 -137
- 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
|
data/spec/parallel_tests_spec.rb
DELETED
@@ -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
|