parallel_tests 1.0.9 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +7 -3
- data/bin/parallel_cucumber +5 -1
- data/bin/parallel_rspec +5 -1
- data/bin/parallel_spinach +5 -1
- data/bin/parallel_test +5 -2
- data/lib/parallel_tests.rb +0 -1
- metadata +3 -51
- data/.gitignore +0 -4
- data/.rspec +0 -2
- data/.travis.yml +0 -10
- data/Gemfile +0 -9
- data/Gemfile.lock +0 -53
- data/Rakefile +0 -10
- data/ReadmeRails2.md +0 -48
- data/lib/parallel_tests/cli.rb +0 -206
- data/lib/parallel_tests/cucumber/failures_logger.rb +0 -25
- data/lib/parallel_tests/cucumber/runner.rb +0 -37
- data/lib/parallel_tests/cucumber/scenario_line_logger.rb +0 -51
- data/lib/parallel_tests/cucumber/scenarios.rb +0 -34
- data/lib/parallel_tests/gherkin/io.rb +0 -41
- data/lib/parallel_tests/gherkin/listener.rb +0 -87
- data/lib/parallel_tests/gherkin/runner.rb +0 -116
- data/lib/parallel_tests/gherkin/runtime_logger.rb +0 -28
- data/lib/parallel_tests/grouper.rb +0 -73
- data/lib/parallel_tests/railtie.rb +0 -8
- data/lib/parallel_tests/rspec/failures_logger.rb +0 -54
- data/lib/parallel_tests/rspec/logger_base.rb +0 -55
- data/lib/parallel_tests/rspec/runner.rb +0 -73
- data/lib/parallel_tests/rspec/runtime_logger.rb +0 -59
- data/lib/parallel_tests/rspec/summary_logger.rb +0 -19
- data/lib/parallel_tests/spinach/runner.rb +0 -19
- data/lib/parallel_tests/tasks.rb +0 -157
- data/lib/parallel_tests/test/runner.rb +0 -186
- data/lib/parallel_tests/test/runtime_logger.rb +0 -98
- data/lib/parallel_tests/version.rb +0 -3
- data/parallel_tests.gemspec +0 -14
- data/spec/integration_spec.rb +0 -437
- data/spec/parallel_tests/cli_spec.rb +0 -149
- data/spec/parallel_tests/cucumber/failure_logger_spec.rb +0 -43
- data/spec/parallel_tests/cucumber/runner_spec.rb +0 -25
- data/spec/parallel_tests/cucumber/scenarios_spec.rb +0 -69
- data/spec/parallel_tests/gherkin/listener_spec.rb +0 -96
- data/spec/parallel_tests/gherkin/runner_behaviour.rb +0 -216
- data/spec/parallel_tests/grouper_spec.rb +0 -61
- data/spec/parallel_tests/rspec/failures_logger_spec.rb +0 -82
- data/spec/parallel_tests/rspec/logger_base_spec.rb +0 -35
- data/spec/parallel_tests/rspec/runner_spec.rb +0 -201
- data/spec/parallel_tests/rspec/runtime_logger_spec.rb +0 -131
- data/spec/parallel_tests/rspec/summary_logger_spec.rb +0 -37
- data/spec/parallel_tests/spinach/runner_spec.rb +0 -12
- data/spec/parallel_tests/tasks_spec.rb +0 -178
- data/spec/parallel_tests/test/runner_spec.rb +0 -407
- data/spec/parallel_tests/test/runtime_logger_spec.rb +0 -112
- data/spec/parallel_tests_spec.rb +0 -137
- data/spec/spec_helper.rb +0 -182
@@ -1,112 +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
|
-
|
91
|
-
describe '::Test::Unit::TestSuite' do
|
92
|
-
it 'passes correct parameters to log' do
|
93
|
-
require 'test/unit'
|
94
|
-
require 'test/unit/ui/xml/testrunner'
|
95
|
-
|
96
|
-
class FakeUnitTest < Test::Unit::TestCase
|
97
|
-
def test_fake
|
98
|
-
assert true
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
ParallelTests::Test::RuntimeLogger.
|
103
|
-
should_receive(:log).
|
104
|
-
with(kind_of(FakeUnitTest), kind_of(Time), kind_of(Time))
|
105
|
-
|
106
|
-
my_tests = Test::Unit::TestSuite.new
|
107
|
-
my_tests << FakeUnitTest.new('test_fake')
|
108
|
-
output = StringIO.new
|
109
|
-
Test::Unit::UI::XML::TestRunner.run(my_tests, :output => output)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
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.6) do
|
98
|
-
ParallelTests.wait_for_other_processes_to_finish
|
99
|
-
end
|
100
|
-
counter.should >= 2
|
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,182 +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.filter_run_excluding :encoding => (RUBY_VERSION < "1.9")
|
23
|
-
config.run_all_when_everything_filtered = true
|
24
|
-
|
25
|
-
config.after do
|
26
|
-
ENV.delete("TEST_ENV_NUMBER")
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def mocked_process
|
31
|
-
StringIO.new
|
32
|
-
end
|
33
|
-
|
34
|
-
def size_of(group)
|
35
|
-
group.inject(0) { |sum, test| sum += File.stat(test).size }
|
36
|
-
end
|
37
|
-
|
38
|
-
# Uses /tmp/parallel_tests/application as the cwd so we can create and remove
|
39
|
-
# files as we want to. After execution it changes cwd back to the original one.
|
40
|
-
def use_temporary_directory_for
|
41
|
-
require 'fileutils'
|
42
|
-
|
43
|
-
dir = File.join("/tmp", "parallel_tests")
|
44
|
-
new_dir = File.join(dir, "application")
|
45
|
-
|
46
|
-
begin
|
47
|
-
# just in case the temporary dir already exists
|
48
|
-
FileUtils.rm_rf(dir) if File.exists?(dir)
|
49
|
-
|
50
|
-
# create the temporary directory
|
51
|
-
FileUtils.mkdir_p(new_dir)
|
52
|
-
|
53
|
-
# chdir changes cwd back to the original one after it is done
|
54
|
-
Dir.chdir(new_dir) do
|
55
|
-
yield
|
56
|
-
end
|
57
|
-
ensure
|
58
|
-
FileUtils.rm_rf(dir) if File.exists?(dir)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_tests_in_groups(klass, folder, suffix)
|
63
|
-
test_root = "#{FAKE_RAILS_ROOT}/#{folder}"
|
64
|
-
|
65
|
-
describe :tests_in_groups do
|
66
|
-
before do
|
67
|
-
system "rm -rf #{FAKE_RAILS_ROOT}; mkdir -p #{test_root}/temp"
|
68
|
-
|
69
|
-
@files = [0,1,2,3,4,5,6,7].map do |i|
|
70
|
-
size = 99
|
71
|
-
file = "#{test_root}/temp/x#{i}#{suffix}"
|
72
|
-
File.open(file, 'w') { |f| f.puts 'x' * size }
|
73
|
-
file
|
74
|
-
end
|
75
|
-
|
76
|
-
@log = klass.runtime_log
|
77
|
-
`mkdir -p #{File.dirname(@log)}`
|
78
|
-
`rm -f #{@log}`
|
79
|
-
end
|
80
|
-
|
81
|
-
after do
|
82
|
-
`rm -f #{@log}`
|
83
|
-
end
|
84
|
-
|
85
|
-
def setup_runtime_log
|
86
|
-
File.open(@log,'w') do |f|
|
87
|
-
@files[1..-1].each{|file| f.puts "#{file}:#{@files.index(file)}"}
|
88
|
-
f.puts "#{@files[0]}:10"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
it "groups when given an array of files" do
|
93
|
-
list_of_files = Dir["#{test_root}/**/*#{suffix}"]
|
94
|
-
found = klass.send(:with_runtime_info, list_of_files)
|
95
|
-
found.should =~ list_of_files.map{ |file| [file, File.stat(file).size]}
|
96
|
-
end
|
97
|
-
|
98
|
-
it "finds all tests" do
|
99
|
-
found = klass.tests_in_groups([test_root], 1)
|
100
|
-
all = [ Dir["#{test_root}/**/*#{suffix}"] ]
|
101
|
-
(found.flatten - all.flatten).should == []
|
102
|
-
end
|
103
|
-
|
104
|
-
it "partitions them into groups by equal size" do
|
105
|
-
groups = klass.tests_in_groups([test_root], 2)
|
106
|
-
groups.map{|g| size_of(g)}.should == [400, 400]
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'should partition correctly with a group size of 4' do
|
110
|
-
groups = klass.tests_in_groups([test_root], 4)
|
111
|
-
groups.map{|g| size_of(g)}.should == [200, 200, 200, 200]
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'should partition correctly with an uneven group size' do
|
115
|
-
groups = klass.tests_in_groups([test_root], 3)
|
116
|
-
groups.map{|g| size_of(g)}.should =~ [300, 300, 200]
|
117
|
-
end
|
118
|
-
|
119
|
-
it "partitions by runtime when runtime-data is available" do
|
120
|
-
klass.stub!(:puts)
|
121
|
-
setup_runtime_log
|
122
|
-
|
123
|
-
groups = klass.tests_in_groups([test_root], 2)
|
124
|
-
groups.size.should == 2
|
125
|
-
# 10 + 1 + 3 + 5 = 19
|
126
|
-
groups[0].should == [@files[0],@files[1],@files[3],@files[5]]
|
127
|
-
# 2 + 4 + 6 + 7 = 19
|
128
|
-
groups[1].should == [@files[2],@files[4],@files[6],@files[7]]
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'partitions from custom runtime-data location' do
|
132
|
-
klass.stub!(:puts)
|
133
|
-
@log = 'tmp/custom_runtime.log'
|
134
|
-
setup_runtime_log
|
135
|
-
|
136
|
-
groups = klass.tests_in_groups([test_root], 2, :runtime_log => @log)
|
137
|
-
groups.size.should == 2
|
138
|
-
# 10 + 1 + 3 + 5 = 19
|
139
|
-
groups[0].should == [@files[0],@files[1],@files[3],@files[5]]
|
140
|
-
# 2 + 4 + 6 + 7 = 19
|
141
|
-
groups[1].should == [@files[2],@files[4],@files[6],@files[7]]
|
142
|
-
end
|
143
|
-
|
144
|
-
it "alpha-sorts partitions when runtime-data is available" do
|
145
|
-
klass.stub!(:puts)
|
146
|
-
setup_runtime_log
|
147
|
-
|
148
|
-
groups = klass.tests_in_groups([test_root], 2)
|
149
|
-
groups.size.should == 2
|
150
|
-
|
151
|
-
groups[0].should == groups[0].sort
|
152
|
-
groups[1].should == groups[1].sort
|
153
|
-
end
|
154
|
-
|
155
|
-
it "partitions by round-robin when not sorting" do
|
156
|
-
files = ["file1.rb", "file2.rb", "file3.rb", "file4.rb"]
|
157
|
-
klass.should_receive(:find_tests).and_return(files)
|
158
|
-
groups = klass.tests_in_groups(files, 2, :group_by => :found).sort
|
159
|
-
groups[0].should == ["file1.rb", "file3.rb"]
|
160
|
-
groups[1].should == ["file2.rb", "file4.rb"]
|
161
|
-
end
|
162
|
-
|
163
|
-
it "alpha-sorts partitions when not sorting by runtime" do
|
164
|
-
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]
|
165
|
-
klass.should_receive(:find_tests).and_return(files)
|
166
|
-
groups = klass.tests_in_groups(files, 2, :group_by => :found).sort
|
167
|
-
groups[0].should == groups[0].sort
|
168
|
-
groups[1].should == groups[1].sort
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def with_files(files)
|
174
|
-
Dir.mktmpdir do |root|
|
175
|
-
files.each do |file|
|
176
|
-
parent = "#{root}/#{File.dirname(file)}"
|
177
|
-
`mkdir -p #{parent}` unless File.exist?(parent)
|
178
|
-
`touch #{root}/#{file}`
|
179
|
-
end
|
180
|
-
yield root
|
181
|
-
end
|
182
|
-
end
|