vinted-parallel_tests 0.13.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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +48 -0
- data/Rakefile +6 -0
- data/Readme.md +293 -0
- data/ReadmeRails2.md +48 -0
- data/bin/parallel_cucumber +5 -0
- data/bin/parallel_rspec +5 -0
- data/bin/parallel_test +5 -0
- data/lib/parallel_tests/cli.rb +187 -0
- data/lib/parallel_tests/cucumber/failures_logger.rb +25 -0
- data/lib/parallel_tests/cucumber/gherkin_listener.rb +82 -0
- data/lib/parallel_tests/cucumber/io.rb +41 -0
- data/lib/parallel_tests/cucumber/runner.rb +98 -0
- data/lib/parallel_tests/cucumber/runtime_logger.rb +28 -0
- data/lib/parallel_tests/grouper.rb +56 -0
- data/lib/parallel_tests/railtie.rb +8 -0
- data/lib/parallel_tests/rspec/failures_logger.rb +44 -0
- data/lib/parallel_tests/rspec/logger_base.rb +52 -0
- data/lib/parallel_tests/rspec/runner.rb +72 -0
- data/lib/parallel_tests/rspec/runtime_logger.rb +54 -0
- data/lib/parallel_tests/rspec/summary_logger.rb +19 -0
- data/lib/parallel_tests/tasks.rb +139 -0
- data/lib/parallel_tests/test/runner.rb +168 -0
- data/lib/parallel_tests/test/runtime_logger.rb +97 -0
- data/lib/parallel_tests/version.rb +3 -0
- data/lib/parallel_tests.rb +61 -0
- data/parallel_tests.gemspec +14 -0
- data/spec/integration_spec.rb +285 -0
- data/spec/parallel_tests/cli_spec.rb +71 -0
- data/spec/parallel_tests/cucumber/failure_logger_spec.rb +43 -0
- data/spec/parallel_tests/cucumber/gherkin_listener_spec.rb +97 -0
- data/spec/parallel_tests/cucumber/runner_spec.rb +179 -0
- data/spec/parallel_tests/grouper_spec.rb +52 -0
- data/spec/parallel_tests/rspec/failures_logger_spec.rb +82 -0
- data/spec/parallel_tests/rspec/runner_spec.rb +187 -0
- data/spec/parallel_tests/rspec/runtime_logger_spec.rb +126 -0
- data/spec/parallel_tests/rspec/summary_logger_spec.rb +37 -0
- data/spec/parallel_tests/tasks_spec.rb +151 -0
- data/spec/parallel_tests/test/runner_spec.rb +413 -0
- data/spec/parallel_tests/test/runtime_logger_spec.rb +90 -0
- data/spec/parallel_tests_spec.rb +137 -0
- data/spec/spec_helper.rb +157 -0
- metadata +110 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'parallel_tests/grouper'
|
|
3
|
+
require 'tmpdir'
|
|
4
|
+
|
|
5
|
+
describe ParallelTests::Grouper do
|
|
6
|
+
describe :by_steps do
|
|
7
|
+
def write(file, content)
|
|
8
|
+
File.open(file,'w'){|f| f.write content }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "sorts features by steps" do
|
|
12
|
+
tmpdir = nil
|
|
13
|
+
result = Dir.mktmpdir do |dir|
|
|
14
|
+
tmpdir = dir
|
|
15
|
+
write("#{dir}/a.feature", "Feature: xxx\n Scenario: xxx\n Given something")
|
|
16
|
+
write("#{dir}/b.feature", "Feature: xxx\n Scenario: xxx\n Given something\n Scenario: yyy\n Given something")
|
|
17
|
+
write("#{dir}/c.feature", "Feature: xxx\n Scenario: xxx\n Given something")
|
|
18
|
+
ParallelTests::Grouper.by_steps(["#{dir}/a.feature", "#{dir}/b.feature", "#{dir}/c.feature"], 2, {})
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# testing inside mktmpdir is always green
|
|
22
|
+
result.should =~ [
|
|
23
|
+
["#{tmpdir}/a.feature", "#{tmpdir}/c.feature"],
|
|
24
|
+
["#{tmpdir}/b.feature"]
|
|
25
|
+
]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe :in_even_groups_by_size do
|
|
30
|
+
let(:files_with_size){ {"1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5} }
|
|
31
|
+
|
|
32
|
+
def call(num_groups)
|
|
33
|
+
ParallelTests::Grouper.in_even_groups_by_size(files_with_size, num_groups)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "groups 1 by 1 for same groups as size" do
|
|
37
|
+
call(5).should == [["5"], ["4"], ["3"], ["2"], ["1"]]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "groups into even groups" do
|
|
41
|
+
call(2).should == [["1", "2", "5"], ["3", "4"]]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "groups into a single group" do
|
|
45
|
+
call(1).should == [["1", "2", "3", "4", "5"]]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "adds empty groups if there are more groups than feature files" do
|
|
49
|
+
call(6).should == [["5"], ["4"], ["3"], ["2"], ["1"], []]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ParallelTests::RSpec::FailuresLogger do
|
|
4
|
+
def silence_warnings
|
|
5
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
|
6
|
+
yield
|
|
7
|
+
ensure
|
|
8
|
+
$VERBOSE = old_verbose
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
@output = OutputLogger.new([])
|
|
13
|
+
@example1 = mock( 'example', :location => "#{Dir.pwd}/spec/path/to/example:123", :full_description => 'should do stuff', :description => 'd' )
|
|
14
|
+
@example2 = mock( 'example', :location => "#{Dir.pwd}/spec/path/to/example2:456", :full_description => 'should do other stuff', :description => 'd')
|
|
15
|
+
@exception1 = mock( :to_s => 'exception', :backtrace => [ '/path/to/error/line:33' ] )
|
|
16
|
+
@failure1 = mock( 'example', :location => "#{Dir.pwd}/example:123", :header => 'header', :exception => @exception1 )
|
|
17
|
+
@logger = ParallelTests::RSpec::FailuresLogger.new(@output)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
after do
|
|
21
|
+
silence_warnings{ ParallelTests::RSpec::LoggerBase::RSPEC_1 = false }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clean_output
|
|
25
|
+
@output.output.join("\n").gsub(/\e\[\d+m/,'')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should produce a list of command lines for failing examples" do
|
|
29
|
+
@logger.example_failed @example1
|
|
30
|
+
@logger.example_failed @example2
|
|
31
|
+
|
|
32
|
+
@logger.dump_failures
|
|
33
|
+
@logger.dump_summary(1,2,3,4)
|
|
34
|
+
|
|
35
|
+
clean_output.should =~ /^rspec .*? should do stuff/
|
|
36
|
+
clean_output.should =~ /^rspec .*? should do other stuff/
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should invoke spec for rspec 1" do
|
|
40
|
+
silence_warnings{ ParallelTests::RSpec::LoggerBase::RSPEC_1 = true }
|
|
41
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
42
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "Could not find gem 'rspec-core'."
|
|
43
|
+
@logger.example_failed @example1
|
|
44
|
+
|
|
45
|
+
@logger.dump_failures
|
|
46
|
+
@logger.dump_summary(1,2,3,4)
|
|
47
|
+
|
|
48
|
+
clean_output.should =~ /^bundle exec spec/
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should invoke rspec for rspec 2" do
|
|
52
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
53
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-core-2.0.2"
|
|
54
|
+
@logger.example_failed @example1
|
|
55
|
+
|
|
56
|
+
@logger.dump_failures
|
|
57
|
+
@logger.dump_summary(1,2,3,4)
|
|
58
|
+
|
|
59
|
+
clean_output.should =~ /^rspec/
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should return relative paths" do
|
|
63
|
+
@logger.example_failed @example1
|
|
64
|
+
@logger.example_failed @example2
|
|
65
|
+
|
|
66
|
+
@logger.dump_failures
|
|
67
|
+
@logger.dump_summary(1,2,3,4)
|
|
68
|
+
|
|
69
|
+
clean_output.should =~ %r(\./spec/path/to/example:123)
|
|
70
|
+
clean_output.should =~ %r(\./spec/path/to/example2:456)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# should not longer be a problem since its using native rspec methods
|
|
75
|
+
xit "should not log examples without location" do
|
|
76
|
+
example = mock('example', :location => 'bla', :full_description => 'before :all')
|
|
77
|
+
@logger.example_failed example
|
|
78
|
+
@logger.dump_failures
|
|
79
|
+
@logger.dump_summary(1,2,3,4)
|
|
80
|
+
clean_output.should == ''
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "parallel_tests/rspec/runner"
|
|
3
|
+
|
|
4
|
+
describe ParallelTests::RSpec::Runner do
|
|
5
|
+
test_tests_in_groups(ParallelTests::RSpec::Runner, 'spec', '_spec.rb')
|
|
6
|
+
|
|
7
|
+
describe :run_tests do
|
|
8
|
+
before do
|
|
9
|
+
File.stub!(:file?).with('script/spec').and_return false
|
|
10
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
|
11
|
+
File.stub!(:file?).with('spec/parallel_spec.opts').and_return false
|
|
12
|
+
File.stub!(:file?).with('.rspec_parallel').and_return false
|
|
13
|
+
ParallelTests.stub!(:bundler_enabled?).and_return false
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def call(*args)
|
|
17
|
+
ParallelTests::RSpec::Runner.run_tests(*args)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def should_run_with(regex)
|
|
21
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a =~ regex}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def should_not_run_with(regex)
|
|
25
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with{|a,b,c,d| a !~ regex}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "runs command using nice when specifed" do
|
|
29
|
+
ParallelTests::Test::Runner.should_receive(:execute_command_and_capture_output).with{|a,b,c| b =~ %r{^nice rspec}}
|
|
30
|
+
call('xxx', 1, 22, :nice => true)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "runs with color when called from cmdline" do
|
|
34
|
+
should_run_with %r{ --tty}
|
|
35
|
+
$stdout.should_receive(:tty?).and_return true
|
|
36
|
+
call('xxx', 1, 22, {})
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "runs without color when not called from cmdline" do
|
|
40
|
+
should_not_run_with %r{ --tty}
|
|
41
|
+
$stdout.should_receive(:tty?).and_return false
|
|
42
|
+
call('xxx', 1, 22, {})
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "runs with color for rspec 1 when called for the cmdline" do
|
|
46
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
|
47
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with { |a, b, c, d| d[:env] == {"RSPEC_COLOR" => "1"} }
|
|
48
|
+
$stdout.should_receive(:tty?).and_return true
|
|
49
|
+
call('xxx', 1, 22, {})
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "runs without color for rspec 1 when not called for the cmdline" do
|
|
53
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
|
54
|
+
ParallelTests::Test::Runner.should_receive(:execute_command).with { |a, b, c, d| d[:env] == {} }
|
|
55
|
+
$stdout.should_receive(:tty?).and_return false
|
|
56
|
+
call('xxx', 1, 22, {})
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "run bundle exec spec when on bundler rspec 1" do
|
|
60
|
+
File.stub!(:file?).with('script/spec').and_return false
|
|
61
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
62
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "Could not find gem 'rspec-core' in bundler."
|
|
63
|
+
should_run_with %r{bundle exec spec}
|
|
64
|
+
call('xxx', 1, 22, {})
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "run bundle exec rspec when on bundler rspec 2" do
|
|
68
|
+
File.stub!(:file?).with('script/spec').and_return false
|
|
69
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
70
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "/foo/bar/rspec-core-2.0.2"
|
|
71
|
+
should_run_with %r{bundle exec rspec}
|
|
72
|
+
call('xxx', 1, 22, {})
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "runs script/spec when script/spec can be found" do
|
|
76
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
|
77
|
+
should_run_with %r{script/spec}
|
|
78
|
+
call('xxx' ,1, 22, {})
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "runs spec when script/spec cannot be found" do
|
|
82
|
+
File.stub!(:file?).with('script/spec').and_return false
|
|
83
|
+
should_not_run_with %r{ script/spec}
|
|
84
|
+
call('xxx', 1, 22, {})
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "uses bin/rspec when present" do
|
|
88
|
+
File.stub(:exists?).with('bin/rspec').and_return true
|
|
89
|
+
should_run_with %r{bin/rspec}
|
|
90
|
+
call('xxx', 1, 22, {})
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "uses no -O when no opts where found" do
|
|
94
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
|
95
|
+
should_not_run_with %r{spec/spec.opts}
|
|
96
|
+
call('xxx', 1, 22, {})
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "uses -O spec/spec.opts when found (with script/spec)" do
|
|
100
|
+
File.stub!(:file?).with('script/spec').and_return true
|
|
101
|
+
File.stub!(:file?).with('spec/spec.opts').and_return true
|
|
102
|
+
should_run_with %r{script/spec\s+-O spec/spec.opts}
|
|
103
|
+
call('xxx', 1, 22, {})
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "uses -O spec/parallel_spec.opts when found (with script/spec)" do
|
|
107
|
+
File.stub!(:file?).with('script/spec').and_return true
|
|
108
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
|
109
|
+
should_run_with %r{script/spec\s+-O spec/parallel_spec.opts}
|
|
110
|
+
call('xxx', 1, 22, {})
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "uses -O .rspec_parallel when found (with script/spec)" do
|
|
114
|
+
File.stub!(:file?).with('script/spec').and_return true
|
|
115
|
+
File.should_receive(:file?).with('.rspec_parallel').and_return true
|
|
116
|
+
should_run_with %r{script/spec\s+-O .rspec_parallel}
|
|
117
|
+
call('xxx', 1, 22, {})
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "uses -O spec/parallel_spec.opts with rspec1" do
|
|
121
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
|
122
|
+
|
|
123
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
124
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "Could not find gem 'rspec-core'."
|
|
125
|
+
|
|
126
|
+
should_run_with %r{spec\s+-O spec/parallel_spec.opts}
|
|
127
|
+
call('xxx', 1, 22, {})
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it "uses -O spec/parallel_spec.opts with rspec2" do
|
|
131
|
+
pending if RUBY_PLATFORM == "java" # FIXME not sure why, but fails on travis
|
|
132
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
|
133
|
+
|
|
134
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
|
135
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec-core").and_return "/foo/bar/rspec-core-2.4.2"
|
|
136
|
+
|
|
137
|
+
should_run_with %r{rspec\s+--color --tty -O spec/parallel_spec.opts}
|
|
138
|
+
call('xxx', 1, 22, {})
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "uses options passed in" do
|
|
142
|
+
should_run_with %r{rspec -f n}
|
|
143
|
+
call('xxx', 1, 22, :test_options => '-f n')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "returns the output" do
|
|
147
|
+
ParallelTests::RSpec::Runner.should_receive(:execute_command).and_return :x => 1
|
|
148
|
+
call('xxx', 1, 22, {}).should == {:x => 1}
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe :find_results do
|
|
153
|
+
def call(*args)
|
|
154
|
+
ParallelTests::RSpec::Runner.find_results(*args)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "finds multiple results in spec output" do
|
|
158
|
+
output = "
|
|
159
|
+
....F...
|
|
160
|
+
..
|
|
161
|
+
failute fsddsfsd
|
|
162
|
+
...
|
|
163
|
+
ff.**..
|
|
164
|
+
0 examples, 0 failures, 0 pending
|
|
165
|
+
ff.**..
|
|
166
|
+
1 example, 1 failure, 1 pending
|
|
167
|
+
"
|
|
168
|
+
|
|
169
|
+
call(output).should == ['0 examples, 0 failures, 0 pending','1 example, 1 failure, 1 pending']
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "is robust against scrambeled output" do
|
|
173
|
+
output = "
|
|
174
|
+
....F...
|
|
175
|
+
..
|
|
176
|
+
failute fsddsfsd
|
|
177
|
+
...
|
|
178
|
+
ff.**..
|
|
179
|
+
0 exFampl*es, 0 failures, 0 pend.ing
|
|
180
|
+
ff.**..
|
|
181
|
+
1 exampF.les, 1 failures, 1 pend.ing
|
|
182
|
+
"
|
|
183
|
+
|
|
184
|
+
call(output).should == ['0 examples, 0 failures, 0 pending','1 examples, 1 failures, 1 pending']
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ParallelTests::RSpec::RuntimeLogger do
|
|
4
|
+
before do
|
|
5
|
+
# pretend we run in parallel or the logger will log nothing
|
|
6
|
+
ENV['TEST_ENV_NUMBER'] = ''
|
|
7
|
+
@clean_output = %r{^spec/foo.rb:[-\.e\d]+$}m
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after do
|
|
11
|
+
ENV.delete 'TEST_ENV_NUMBER'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def log_for_a_file(options={})
|
|
15
|
+
Tempfile.open('xxx') do |temp|
|
|
16
|
+
temp.close
|
|
17
|
+
f = File.open(temp.path,'w')
|
|
18
|
+
logger = if block_given?
|
|
19
|
+
yield(f)
|
|
20
|
+
else
|
|
21
|
+
ParallelTests::RSpec::RuntimeLogger.new(f)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
example = (mock(:file_path => "#{Dir.pwd}/spec/foo.rb"))
|
|
25
|
+
logger.example_group_started example
|
|
26
|
+
logger.example_group_finished example
|
|
27
|
+
logger.start_dump
|
|
28
|
+
|
|
29
|
+
#f.close
|
|
30
|
+
return File.read(f.path)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "logs runtime with relative paths" do
|
|
35
|
+
log_for_a_file.should =~ @clean_output
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "does not log if we do not run in parallel" do
|
|
39
|
+
ENV.delete 'TEST_ENV_NUMBER'
|
|
40
|
+
log_for_a_file.should == ""
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "appends to a given file" do
|
|
44
|
+
result = log_for_a_file do |f|
|
|
45
|
+
f.write 'FooBar'
|
|
46
|
+
ParallelTests::RSpec::RuntimeLogger.new(f)
|
|
47
|
+
end
|
|
48
|
+
result.should include('FooBar')
|
|
49
|
+
result.should include('foo.rb')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "overwrites a given path" do
|
|
53
|
+
result = log_for_a_file do |f|
|
|
54
|
+
f.write 'FooBar'
|
|
55
|
+
ParallelTests::RSpec::RuntimeLogger.new(f.path)
|
|
56
|
+
end
|
|
57
|
+
result.should_not include('FooBar')
|
|
58
|
+
result.should include('foo.rb')
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
context "integration" do
|
|
62
|
+
around do |example|
|
|
63
|
+
Dir.mktmpdir do |dir|
|
|
64
|
+
Dir.chdir(dir, &example)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def write(file, content)
|
|
69
|
+
FileUtils.mkdir_p(File.dirname(file))
|
|
70
|
+
File.open(file, 'w') { |f| f.write content }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "logs shared examples into the running files" do
|
|
74
|
+
write "spec/spec_helper.rb", <<-RUBY
|
|
75
|
+
shared_examples "foo" do
|
|
76
|
+
it "is slow" do
|
|
77
|
+
sleep 0.5
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
RUBY
|
|
81
|
+
|
|
82
|
+
["a", "b"].each do |letter|
|
|
83
|
+
write "spec/#{letter}_spec.rb", <<-RUBY
|
|
84
|
+
require 'spec_helper'
|
|
85
|
+
describe 'xxx' do
|
|
86
|
+
it_behaves_like "foo"
|
|
87
|
+
end
|
|
88
|
+
RUBY
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
system("TEST_ENV_NUMBER=1 rspec spec -I #{Bundler.root.join("lib")} --format ParallelTests::RSpec::RuntimeLogger --out runtime.log 2>&1") || raise("nope")
|
|
92
|
+
|
|
93
|
+
result = File.read("runtime.log")
|
|
94
|
+
result.should include "a_spec.rb:0.5"
|
|
95
|
+
result.should include "b_spec.rb:0.5"
|
|
96
|
+
result.should_not include "spec_helper"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "logs multiple describe blocks" do
|
|
100
|
+
write "spec/a_spec.rb", <<-RUBY
|
|
101
|
+
describe "xxx" do
|
|
102
|
+
it "is slow" do
|
|
103
|
+
sleep 0.5
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe "yyy" do
|
|
108
|
+
it "is slow" do
|
|
109
|
+
sleep 0.5
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe "yep" do
|
|
113
|
+
it "is slow" do
|
|
114
|
+
sleep 0.5
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
RUBY
|
|
119
|
+
|
|
120
|
+
system("TEST_ENV_NUMBER=1 rspec spec -I #{Bundler.root.join("lib")} --format ParallelTests::RSpec::RuntimeLogger --out runtime.log 2>&1") || raise("nope")
|
|
121
|
+
|
|
122
|
+
result = File.read("runtime.log")
|
|
123
|
+
result.should include "a_spec.rb:1.5"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ParallelTests::RSpec::SummaryLogger do
|
|
4
|
+
let(:output){ OutputLogger.new([]) }
|
|
5
|
+
let(:logger){ ParallelTests::RSpec::SummaryLogger.new(output) }
|
|
6
|
+
|
|
7
|
+
def decolorize(string)
|
|
8
|
+
string.gsub(/\e\[\d+m/,'')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# TODO somehow generate a real example with an exception to test this
|
|
12
|
+
xit "prints failing examples" do
|
|
13
|
+
logger.example_failed XXX
|
|
14
|
+
logger.example_failed XXX
|
|
15
|
+
logger.dump_failures
|
|
16
|
+
output.output.should == [
|
|
17
|
+
"bundle exec rspec ./spec/path/to/example.rb:123 # should do stuff",
|
|
18
|
+
"bundle exec rspec ./spec/path/to/example.rb:125 # should not do stuff"
|
|
19
|
+
]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "does not print anything for passing examples" do
|
|
23
|
+
logger.example_passed mock(:location => "/my/spec/foo.rb:123")
|
|
24
|
+
logger.dump_failures
|
|
25
|
+
output.output.should == []
|
|
26
|
+
logger.dump_summary(1,2,3,4)
|
|
27
|
+
output.output.map{|o| decolorize(o) }.should == ["\nFinished in 1 second\n", "2 examples, 3 failures, 4 pending"]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "does not print anything for pending examples" do
|
|
31
|
+
logger.example_pending mock(:location => "/my/spec/foo.rb:123")
|
|
32
|
+
logger.dump_failures
|
|
33
|
+
output.output.should == []
|
|
34
|
+
logger.dump_summary(1,2,3,4)
|
|
35
|
+
output.output.map{|o| decolorize(o) }.should == ["\nFinished in 1 second\n", "2 examples, 3 failures, 4 pending"]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'parallel_tests/tasks'
|
|
3
|
+
|
|
4
|
+
describe ParallelTests::Tasks do
|
|
5
|
+
describe ".parse_args" do
|
|
6
|
+
it "should return the count" do
|
|
7
|
+
args = {:count => 2}
|
|
8
|
+
ParallelTests::Tasks.parse_args(args).should == [2, "", ""]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should default to the prefix" do
|
|
12
|
+
args = {:count => "models"}
|
|
13
|
+
ParallelTests::Tasks.parse_args(args).should == [nil, "models", ""]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should return the count and pattern" do
|
|
17
|
+
args = {:count => 2, :pattern => "models"}
|
|
18
|
+
ParallelTests::Tasks.parse_args(args).should == [2, "models", ""]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should return the count, pattern, and options" do
|
|
22
|
+
args = {:count => 2, :pattern => "plain", :options => "-p default"}
|
|
23
|
+
ParallelTests::Tasks.parse_args(args).should == [2, "plain", "-p default"]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe ".rails_env" do
|
|
28
|
+
around do |example|
|
|
29
|
+
begin
|
|
30
|
+
old = ENV["RAILS_ENV"]
|
|
31
|
+
ENV.delete "RAILS_ENV"
|
|
32
|
+
example.call
|
|
33
|
+
ensure
|
|
34
|
+
ENV["RAILS_ENV"] = old
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should be test when nothing was set" do
|
|
39
|
+
ParallelTests::Tasks.rails_env.should == "test"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should be whatever was set" do
|
|
43
|
+
ENV["RAILS_ENV"] = "foo"
|
|
44
|
+
ParallelTests::Tasks.rails_env.should == "foo"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe ".run_in_parallel" do
|
|
49
|
+
let(:full_path){ File.expand_path("../../../bin/parallel_test", __FILE__) }
|
|
50
|
+
|
|
51
|
+
it "should have the executable" do
|
|
52
|
+
File.file?(full_path).should == true
|
|
53
|
+
File.executable?(full_path).should == true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "runs command in parallel" do
|
|
57
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo'").and_return true
|
|
58
|
+
ParallelTests::Tasks.run_in_parallel("echo")
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "runs command with :count option" do
|
|
62
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo' -n 123").and_return true
|
|
63
|
+
ParallelTests::Tasks.run_in_parallel("echo", :count => 123)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "runs command with :non_parallel option" do
|
|
67
|
+
ParallelTests::Tasks.should_receive(:system).with("#{full_path} --exec 'echo' --non-parallel").and_return true
|
|
68
|
+
ParallelTests::Tasks.run_in_parallel("echo", :non_parallel => true)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "runs aborts if the command fails" do
|
|
72
|
+
ParallelTests::Tasks.should_receive(:system).and_return false
|
|
73
|
+
ParallelTests::Tasks.should_receive(:abort).and_return false
|
|
74
|
+
ParallelTests::Tasks.run_in_parallel("echo")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe ".suppress_output" do
|
|
79
|
+
def call(command, grep)
|
|
80
|
+
result = `#{ParallelTests::Tasks.suppress_output(command, grep)}`
|
|
81
|
+
[result, $?.success?]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
context "with pipefail supported" do
|
|
85
|
+
before :all do
|
|
86
|
+
if not system("set -o pipefail 2>/dev/null && test 1")
|
|
87
|
+
pending "pipefail is not supported on your system"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should hide offending lines" do
|
|
92
|
+
call("echo 123", "123").should == ["", true]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "should not hide other lines" do
|
|
96
|
+
call("echo 124", "123").should == ["124\n", true]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should fail if command fails and the pattern matches" do
|
|
100
|
+
call("echo 123 && test", "123").should == ["", false]
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should fail if command fails and the pattern fails" do
|
|
104
|
+
call("echo 124 && test", "123").should == ["124\n", false]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context "without pipefail supported" do
|
|
109
|
+
before do
|
|
110
|
+
ParallelTests::Tasks.should_receive(:system).with("set -o pipefail 2>/dev/null && test 1").and_return false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should not filter and succeed" do
|
|
114
|
+
call("echo 123", "123").should == ["123\n", true]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "should not filter and fail" do
|
|
118
|
+
call("echo 123 && test", "123").should == ["123\n", false]
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
describe ".check_for_pending_migrations" do
|
|
124
|
+
after do
|
|
125
|
+
Rake.application.instance_variable_get('@tasks').delete("db:abort_if_pending_migrations")
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should do nothing if pending migrations is no defined" do
|
|
129
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should run pending migrations is task is defined" do
|
|
133
|
+
foo = 1
|
|
134
|
+
Rake::Task.define_task("db:abort_if_pending_migrations") do
|
|
135
|
+
foo = 2
|
|
136
|
+
end
|
|
137
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
|
138
|
+
foo.should == 2
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "should not execute the task twice" do
|
|
142
|
+
foo = 1
|
|
143
|
+
Rake::Task.define_task("db:abort_if_pending_migrations") do
|
|
144
|
+
foo += 1
|
|
145
|
+
end
|
|
146
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
|
147
|
+
ParallelTests::Tasks.check_for_pending_migrations
|
|
148
|
+
foo.should == 2
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|