parallel_split_test 0.1.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/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ script: "bundle exec rake"
2
+ rvm:
3
+ - ree
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+ gemspec
3
+
4
+ group :development do
5
+ gem 'rake'
6
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ parallel_split_test (0.1.0)
5
+ parallel (>= 0.5.12)
6
+ rspec (>= 2)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.1.3)
12
+ parallel (0.5.12)
13
+ rake (0.9.2)
14
+ rspec (2.8.0)
15
+ rspec-core (~> 2.8.0)
16
+ rspec-expectations (~> 2.8.0)
17
+ rspec-mocks (~> 2.8.0)
18
+ rspec-core (2.8.0)
19
+ rspec-expectations (2.8.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.8.0)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ parallel_split_test!
28
+ rake
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ task :default do
4
+ sh "rspec spec/"
5
+ end
6
+
7
+ rule /^version:bump:.*/ do |t|
8
+ file = 'lib/parallel_split_test/version.rb'
9
+ sh "git status | grep 'nothing to commit'" # ensure we are not dirty
10
+ index = ['major', 'minor','patch'].index(t.name.split(':').last)
11
+ version_file = File.read(file)
12
+ old_version, *version_parts = version_file.match(/(\d+)\.(\d+)\.(\d+)/).to_a
13
+ version_parts[index] = version_parts[index].to_i + 1
14
+ new_version = version_parts * '.'
15
+ File.open(file,'w'){|f| f.write(version_file.sub(old_version, new_version)) }
16
+
17
+ sh "bundle && git add #{file} Gemfile.lock && git commit -m 'bump version to #{new_version}'"
18
+ end
data/Readme.md ADDED
@@ -0,0 +1,41 @@
1
+ Split a big test file into multiple chunks and run them in parallel
2
+
3
+ Install
4
+ =======
5
+ sudo gem install parallel_split_test
6
+ Or
7
+
8
+ rails plugin install git://github.com/grosser/parallel_split_test.git
9
+
10
+ Usage
11
+ =====
12
+ # spec/xxx_spec.rb
13
+ require "spec_helper"
14
+
15
+ describe "X" do
16
+ it {sleep 5}
17
+ end
18
+
19
+ describe "Y" do
20
+ it {sleep 5}
21
+ end
22
+
23
+ describe "Z" do
24
+ it {sleep 5}
25
+ end
26
+
27
+ time parallel_split_test spec/xxx_spec.rb [regular rspec options]
28
+
29
+ TODO
30
+ ====
31
+ - combine exit status (1 + 0 == 1)
32
+ - support a single group with multiple sub-groups
33
+ - Test::Unit support
34
+ - Cucumber support
35
+
36
+ Author
37
+ ======
38
+ [Michael Grosser](http://grosser.it)<br/>
39
+ michael@grosser.it<br/>
40
+ License: MIT<br/>
41
+ [![Build Status](https://secure.travis-ci.org/grosser/parallel_split_test.png)](http://travis-ci.org/grosser/parallel_split_test)
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ require "optparse"
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require "parallel_split_test"
5
+
6
+ parser = OptionParser.new do |opts|
7
+ opts.banner = <<BANNER
8
+ Split a big test file into multiple chunks and run them in parallel, giving ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
9
+
10
+ Usage:
11
+ parallel_split_test test/baz/xxx_text.rb
12
+
13
+ Options are:
14
+ BANNER
15
+ opts.on("-v", "--version", "Show Version"){ require 'parallel_split_test/version'; puts ParallelSplitTest::VERSION; exit}
16
+ opts.on("-h", "--help", "Show this.") { puts opts; exit }
17
+ end
18
+
19
+ parser.parse!
20
+
21
+ if ARGV.empty?
22
+ puts parser
23
+ exit
24
+ end
25
+
26
+ require "rspec"
27
+ require "parallel"
28
+
29
+ require 'parallel_split_test/runner'
30
+ ParallelSplitTest::Runner.run(ARGV)
@@ -0,0 +1,2 @@
1
+ module ParallelSplitTest
2
+ end
@@ -0,0 +1,53 @@
1
+ require 'parallel'
2
+ require 'rspec/core/command_line'
3
+
4
+ module ParallelSplitTest
5
+ class CommandLine < RSpec::Core::CommandLine
6
+ def run(err, out)
7
+ setup_copied_from_rspec(err, out)
8
+
9
+ processes = Parallel.processor_count
10
+
11
+ Parallel.in_processes(processes) do |process_number|
12
+ ENV['TEST_ENV_NUMBER'] = (process_number == 0 ? '' : (process_number + 1).to_s)
13
+ run_group_of_tests(processes, process_number)
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def run_group_of_tests(processes, process_number)
20
+ example_count = @world.example_count / processes
21
+
22
+ @configuration.reporter.report(example_count, seed) do |reporter|
23
+ begin
24
+ @configuration.run_hook(:before, :suite)
25
+ groups = groups_for_this_process(@world.example_groups.ordered, process_number, processes)
26
+ groups.map {|g| g.run(reporter)}.all? ? 0 : @configuration.failure_exit_code
27
+ ensure
28
+ @configuration.run_hook(:after, :suite)
29
+ end
30
+ end
31
+ end
32
+
33
+ def seed
34
+ @configuration.randomize? ? @configuration.seed : nil
35
+ end
36
+
37
+ def groups_for_this_process(groups, number, count)
38
+ selected = []
39
+ groups.each_with_index do |group, i|
40
+ selected << group if i % count == number
41
+ end
42
+ selected
43
+ end
44
+
45
+ def setup_copied_from_rspec(err, out)
46
+ @configuration.error_stream = err
47
+ @configuration.output_stream ||= out
48
+ @options.configure(@configuration)
49
+ @configuration.load_spec_files
50
+ @world.announce_filters
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,17 @@
1
+ require 'rspec/core/runner'
2
+ require 'rspec/core/configuration_options'
3
+ require 'parallel_split_test/command_line'
4
+
5
+ # a cleaned up version of the RSpec runner, e.g. no drb support
6
+ module ParallelSplitTest
7
+ class Runner < RSpec::Core::Runner
8
+ def self.run(args, err=$stderr, out=$stdout)
9
+ trap_interrupt
10
+ options = RSpec::Core::ConfigurationOptions.new(args)
11
+ options.parse_options
12
+ ParallelSplitTest::CommandLine.new(options).run(err, out)
13
+ ensure
14
+ RSpec.reset
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module ParallelSplitTest
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,15 @@
1
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
+ name = "parallel_split_test"
3
+ require "#{name}/version"
4
+
5
+ Gem::Specification.new name, ParallelSplitTest::VERSION do |s|
6
+ s.summary = "Split a big test file into multiple chunks and run them in parallel"
7
+ s.authors = ["Michael Grosser"]
8
+ s.email = "michael@grosser.it"
9
+ s.homepage = "http://github.com/grosser/#{name}"
10
+ s.files = `git ls-files`.split("\n")
11
+ s.executables = ["parallel_split_test"]
12
+ s.add_dependency "rspec", ">=2"
13
+ s.add_dependency "parallel", ">=0.5.12"
14
+ s.license = "MIT"
15
+ end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper'
2
+
3
+ describe ParallelSplitTest do
4
+ it "has a VERSION" do
5
+ ParallelSplitTest::VERSION.should =~ /^[\.\da-z]+$/
6
+ end
7
+
8
+ describe "cli" do
9
+ def run(command, options={})
10
+ result = `#{command} 2>&1`
11
+ message = (options[:fail] ? "SUCCESS BUT SHOULD FAIL" : "FAIL")
12
+ raise "[#{message}] #{result} [#{command}]" if $?.success? == !!options[:fail]
13
+ result
14
+ end
15
+
16
+ def write(path, content)
17
+ run "mkdir -p #{File.dirname(path)}" unless File.exist?(File.dirname(path))
18
+ File.open(path, 'w'){|f| f.write content }
19
+ path
20
+ end
21
+
22
+ def parallel_split_test(x)
23
+ run "../../bin/parallel_split_test #{x}"
24
+ end
25
+
26
+ def time
27
+ start = Time.now.to_f
28
+ yield
29
+ Time.now.to_f - start
30
+ end
31
+
32
+ let(:root) { File.expand_path('../../', __FILE__) }
33
+
34
+ before do
35
+ run "rm -rf spec/tmp ; mkdir spec/tmp"
36
+ Dir.chdir "spec/tmp"
37
+ end
38
+
39
+ after do
40
+ Dir.chdir root
41
+ end
42
+
43
+ describe "printing version" do
44
+ it "prints version on -v" do
45
+ parallel_split_test("-v").strip.should =~ /^[\.\da-z]+$/
46
+ end
47
+
48
+ it "prints version on --version" do
49
+ parallel_split_test("--version").strip.should =~ /^[\.\da-z]+$/
50
+ end
51
+ end
52
+
53
+ describe "printing help" do
54
+ it "prints help on -h" do
55
+ parallel_split_test("-h").should include("Usage")
56
+ end
57
+
58
+ it "prints help on --help" do
59
+ parallel_split_test("-h").should include("Usage")
60
+ end
61
+
62
+ it "prints help on no arguments" do
63
+ parallel_split_test("").should include("Usage")
64
+ end
65
+ end
66
+
67
+ describe "running tests" do
68
+ it "runs in different processes" do
69
+ write "xxx_spec.rb", <<-RUBY
70
+ describe "X" do
71
+ it "a" do
72
+ puts "it-ran-a-in-\#{ENV['TEST_ENV_NUMBER'].to_i}-"
73
+ end
74
+ end
75
+
76
+ describe "Y" do
77
+ it "b" do
78
+ puts "it-ran-b-in-\#{ENV['TEST_ENV_NUMBER'].to_i}-"
79
+ end
80
+ end
81
+ RUBY
82
+ result = parallel_split_test "xxx_spec.rb"
83
+
84
+ processes = ["a","b"].map do |process|
85
+ rex = /it-ran-#{process}-in-(\d)-/
86
+ result.should =~ rex
87
+ result.match(rex)[1]
88
+ end
89
+
90
+ processes.should == ['0','2']
91
+ end
92
+
93
+ it "runs faster" do
94
+ write "xxx_spec.rb", <<-RUBY
95
+ describe "X" do
96
+ it { sleep 1 }
97
+ end
98
+
99
+ describe "Y" do
100
+ it { sleep 1 }
101
+ end
102
+ RUBY
103
+
104
+ time{ parallel_split_test "xxx_spec.rb" }.should < 2
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift 'lib'
2
+ require 'parallel_split_test'
3
+ require 'parallel_split_test/version'
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parallel_split_test
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Grosser
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &84152290 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *84152290
25
+ - !ruby/object:Gem::Dependency
26
+ name: parallel
27
+ requirement: &84152040 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.5.12
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *84152040
36
+ description:
37
+ email: michael@grosser.it
38
+ executables:
39
+ - parallel_split_test
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .travis.yml
44
+ - Gemfile
45
+ - Gemfile.lock
46
+ - Rakefile
47
+ - Readme.md
48
+ - bin/parallel_split_test
49
+ - lib/parallel_split_test.rb
50
+ - lib/parallel_split_test/command_line.rb
51
+ - lib/parallel_split_test/runner.rb
52
+ - lib/parallel_split_test/version.rb
53
+ - parallel_split_test.gemspec
54
+ - spec/parallel_split_test_spec.rb
55
+ - spec/spec_helper.rb
56
+ homepage: http://github.com/grosser/parallel_split_test
57
+ licenses:
58
+ - MIT
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ segments:
70
+ - 0
71
+ hash: -266472017
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ segments:
79
+ - 0
80
+ hash: -266472017
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 1.8.10
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: Split a big test file into multiple chunks and run them in parallel
87
+ test_files: []