parallel_split_test 0.2.1 → 0.3.0
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.
- data/Gemfile.lock +1 -1
- data/Readme.md +30 -30
- data/bin/parallel_split_test +11 -16
- data/lib/parallel_split_test/command_line.rb +46 -4
- data/lib/parallel_split_test/runner.rb +4 -12
- data/lib/parallel_split_test/version.rb +1 -1
- data/spec/parallel_split_test_spec.rb +31 -2
- metadata +3 -3
data/Gemfile.lock
CHANGED
data/Readme.md
CHANGED
@@ -10,9 +10,10 @@ Usage
|
|
10
10
|
### 1: prepare your databases
|
11
11
|
To use 1 database per test-process, add this to your `config/database.yml`<br/>
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
```Yaml
|
14
|
+
test:
|
15
|
+
database: yourproject_test<%= ENV['TEST_ENV_NUMBER'] %>
|
16
|
+
```
|
16
17
|
|
17
18
|
- `TEST_ENV_NUMBER` is '' for the first process and 2 for the 2nd, it reuses your normal test database
|
18
19
|
- Optionally install [parallel_tests](https://github.com/grosser/parallel_tests) to get database helper tasks like `rake parallel:prepare`
|
@@ -20,44 +21,43 @@ To use 1 database per test-process, add this to your `config/database.yml`<br/>
|
|
20
21
|
|
21
22
|
### 2: find a slow/big test file
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
```Ruby
|
25
|
+
# spec/xxx_spec.rb
|
26
|
+
require "spec_helper"
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
describe "X" do
|
29
|
+
it {sleep 5}
|
30
|
+
it {sleep 5}
|
31
|
+
it {sleep 5}
|
32
|
+
end
|
33
|
+
```
|
31
34
|
|
32
35
|
### 3: run
|
33
|
-
|
36
|
+
```Bash
|
37
|
+
parallel_split_test spec/xxx_spec.rb [regular test options]
|
38
|
+
```
|
34
39
|
|
35
40
|
Output
|
36
41
|
======
|
37
42
|
|
38
|
-
|
39
|
-
|
40
|
-
Running examples in 2 processes
|
41
|
-
.
|
42
|
-
|
43
|
-
Finished in 5 seconds
|
44
|
-
1 example, 0 failures
|
45
|
-
..
|
43
|
+
```Bash
|
44
|
+
parallel_split_test spec/xx_spec.rb
|
46
45
|
|
47
|
-
|
48
|
-
|
46
|
+
Running examples in 2 processes
|
47
|
+
.
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
Took 10.06 seconds with 2 processes
|
49
|
+
Finished in 5 seconds
|
50
|
+
1 example, 0 failures
|
51
|
+
..
|
54
52
|
|
53
|
+
Finished in 1 seconds
|
54
|
+
2 examples, 0 failures
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
56
|
+
Summary:
|
57
|
+
1 example, 0 failures
|
58
|
+
2 examples, 0 failures
|
59
|
+
Took 10.06 seconds with 2 processes
|
60
|
+
```
|
61
61
|
|
62
62
|
TIPS
|
63
63
|
====
|
data/bin/parallel_split_test
CHANGED
@@ -2,27 +2,22 @@
|
|
2
2
|
require "optparse"
|
3
3
|
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
if ARGV.include?("-v") or ARGV.include?("--version")
|
6
|
+
require 'parallel_split_test/version'
|
7
|
+
puts ParallelSplitTest::VERSION; exit
|
8
|
+
elsif ARGV.include?("-h") or ARGV.include?("--help") or ARGV.empty?
|
9
|
+
puts <<-TEXT
|
10
|
+
Split a big test file into multiple chunks and run them in parallel, giving ENV['TEST_ENV_NUMBER'] as '', '2', '3', ...
|
9
11
|
|
10
12
|
Usage:
|
11
|
-
parallel_split_test test/baz/xxx_text.rb
|
13
|
+
parallel_split_test test/baz/xxx_text.rb [other rspec options]
|
12
14
|
|
13
15
|
Options are:
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
opts.on("-o", "--test-options STRING", "Run tests with these options") { |test_options| options[:test_options] = test_options }
|
18
|
-
end
|
19
|
-
|
20
|
-
parser.parse!
|
21
|
-
|
22
|
-
if ARGV.empty?
|
23
|
-
puts parser
|
16
|
+
-v, --version Display the program version.
|
17
|
+
-h, --help Display this help message.
|
18
|
+
TEXT
|
24
19
|
exit
|
25
20
|
end
|
26
21
|
|
27
22
|
require 'parallel_split_test/runner'
|
28
|
-
exit ParallelSplitTest::Runner.run(ARGV,
|
23
|
+
exit ParallelSplitTest::Runner.run(ARGV, $stderr, $stdout)
|
@@ -6,24 +6,66 @@ require 'parallel_split_test/core_ext/rspec_example'
|
|
6
6
|
|
7
7
|
module ParallelSplitTest
|
8
8
|
class CommandLine < RSpec::Core::CommandLine
|
9
|
+
def initialize(args)
|
10
|
+
@args = args
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
9
14
|
def run(err, out)
|
10
|
-
|
11
|
-
|
12
|
-
out = OutputRecorder.new(out)
|
13
|
-
setup_copied_from_rspec(err, out)
|
15
|
+
processes = ParallelSplitTest.choose_number_of_processes
|
16
|
+
out.puts "Running examples in #{processes} processes"
|
14
17
|
|
18
|
+
results = Parallel.in_processes(processes) do |process_number|
|
15
19
|
ParallelSplitTest.example_counter = 0
|
16
20
|
ParallelSplitTest.process_number = process_number
|
21
|
+
set_test_env_number(process_number)
|
22
|
+
modify_out_file_in_args(process_number) if out_file
|
17
23
|
|
24
|
+
out = OutputRecorder.new(out)
|
25
|
+
setup_copied_from_rspec(err, out)
|
18
26
|
[run_group_of_tests, out.recorded]
|
19
27
|
end
|
20
28
|
|
29
|
+
combine_out_files if out_file
|
30
|
+
|
21
31
|
reprint_result_lines(out, results.map(&:last))
|
22
32
|
results.map(&:first).max # combine exit status
|
23
33
|
end
|
24
34
|
|
25
35
|
private
|
26
36
|
|
37
|
+
# modify + reparse args to unify output
|
38
|
+
def modify_out_file_in_args(process_number)
|
39
|
+
@args[out_file_position] = "#{out_file}.#{process_number}"
|
40
|
+
@options = RSpec::Core::ConfigurationOptions.new(@args)
|
41
|
+
@options.parse_options
|
42
|
+
end
|
43
|
+
|
44
|
+
def set_test_env_number(process_number)
|
45
|
+
ENV['TEST_ENV_NUMBER'] = (process_number == 0 ? '' : (process_number + 1).to_s)
|
46
|
+
end
|
47
|
+
|
48
|
+
def out_file
|
49
|
+
@out_file ||= @args[out_file_position] if out_file_position
|
50
|
+
end
|
51
|
+
|
52
|
+
def out_file_position
|
53
|
+
@out_file_position ||= begin
|
54
|
+
if out_position = @args.index { |i| ["-o", "--out"].include?(i) }
|
55
|
+
out_position + 1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def combine_out_files
|
61
|
+
File.open(out_file, "w") do |f|
|
62
|
+
Dir["#{out_file}.*"].each do |file|
|
63
|
+
f.write File.read(file)
|
64
|
+
File.delete(file)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
27
69
|
def reprint_result_lines(out, printed_outputs)
|
28
70
|
out.puts
|
29
71
|
out.puts "Summary:"
|
@@ -4,21 +4,13 @@ require 'shellwords'
|
|
4
4
|
# a cleaned up version of the RSpec runner, e.g. no drb support
|
5
5
|
module ParallelSplitTest
|
6
6
|
class Runner < RSpec::Core::Runner
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# @overwrite
|
8
|
+
# stripped down version of run without --drb support / option parsing
|
9
|
+
def self.run(args, err=$stderr, out=$stdout)
|
10
10
|
trap_interrupt
|
11
11
|
|
12
|
-
args += Shellwords.shellwords(options[:test_options]) if options[:test_options] # TODO smarter parsing ...
|
13
|
-
|
14
|
-
options = RSpec::Core::ConfigurationOptions.new(args)
|
15
|
-
options.parse_options
|
16
|
-
|
17
|
-
ParallelSplitTest.choose_number_of_processes
|
18
|
-
out.puts "Running examples in #{ParallelSplitTest.processes} processes"
|
19
|
-
|
20
12
|
report_execution_time(out) do
|
21
|
-
ParallelSplitTest::CommandLine.new(
|
13
|
+
ParallelSplitTest::CommandLine.new(args).run(err, out)
|
22
14
|
end
|
23
15
|
ensure
|
24
16
|
RSpec.reset
|
@@ -223,7 +223,7 @@ describe ParallelSplitTest do
|
|
223
223
|
result.should include("1 example, 0 failures\n1 example, 0 failures")
|
224
224
|
end
|
225
225
|
|
226
|
-
it "can use
|
226
|
+
it "can use rspec options" do
|
227
227
|
write "xxx_spec.rb", <<-RUBY
|
228
228
|
describe "xxx" do
|
229
229
|
it "yyy" do
|
@@ -231,9 +231,38 @@ describe ParallelSplitTest do
|
|
231
231
|
end
|
232
232
|
RUBY
|
233
233
|
|
234
|
-
result = parallel_split_test "xxx_spec.rb --
|
234
|
+
result = parallel_split_test "xxx_spec.rb --format html"
|
235
235
|
result.should include "</body>"
|
236
236
|
end
|
237
|
+
|
238
|
+
it "writes a unified --out" do
|
239
|
+
write "xxx_spec.rb", <<-RUBY
|
240
|
+
describe "xxx" do
|
241
|
+
it "yyy" do
|
242
|
+
end
|
243
|
+
|
244
|
+
it "zzz" do
|
245
|
+
end
|
246
|
+
end
|
247
|
+
RUBY
|
248
|
+
|
249
|
+
result = parallel_split_test "xxx_spec.rb --format d --out xxx"
|
250
|
+
|
251
|
+
# output does not show up in stdout
|
252
|
+
result.should_not include "xxx"
|
253
|
+
result.should_not include "yyy"
|
254
|
+
|
255
|
+
# basic output is still there
|
256
|
+
result.should include "Running examples in"
|
257
|
+
|
258
|
+
# recorded output is combination of both
|
259
|
+
out = File.read("xxx")
|
260
|
+
out.should include "yyy"
|
261
|
+
out.should include "zzz"
|
262
|
+
|
263
|
+
# parts are cleaned up
|
264
|
+
Dir["xxx.*"].should == []
|
265
|
+
end
|
237
266
|
end
|
238
267
|
end
|
239
268
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_split_test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -83,7 +83,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
83
|
version: '0'
|
84
84
|
segments:
|
85
85
|
- 0
|
86
|
-
hash:
|
86
|
+
hash: 4514306617232661236
|
87
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
88
|
none: false
|
89
89
|
requirements:
|
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
92
|
version: '0'
|
93
93
|
segments:
|
94
94
|
- 0
|
95
|
-
hash:
|
95
|
+
hash: 4514306617232661236
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
98
|
rubygems_version: 1.8.25
|