parallel-rspec 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.
- checksums.yaml +7 -0
- data/.gitignore +54 -0
- data/.rspec +2 -0
- data/.rubocop.yml +19 -0
- data/.simplecov +3 -0
- data/.yardopts +4 -0
- data/Gemfile +3 -0
- data/README.md +57 -0
- data/Rakefile +9 -0
- data/bin/parallel-rspec +8 -0
- data/lib/parallel-rspec.rb +8 -0
- data/lib/rspec/parallel.rb +21 -0
- data/lib/rspec/parallel/configuration.rb +47 -0
- data/lib/rspec/parallel/errors.rb +7 -0
- data/lib/rspec/parallel/master.rb +80 -0
- data/lib/rspec/parallel/protocol.rb +8 -0
- data/lib/rspec/parallel/railtie.rb +9 -0
- data/lib/rspec/parallel/rake_task.rb +27 -0
- data/lib/rspec/parallel/runner.rb +82 -0
- data/lib/rspec/parallel/socket_builder.rb +33 -0
- data/lib/rspec/parallel/version.rb +5 -0
- data/lib/rspec/parallel/worker.rb +118 -0
- data/parallel-rspec.gemspec +27 -0
- data/wercker.yml +16 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2820fc1f77e7c926911e9697230f45b46028d82d
|
4
|
+
data.tar.gz: 11ad9491f170694b49296ed590c189f964ca736f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cfaeda33e78559f68b2d013883daa58523b71bcc108db0d627385d7e3657152057bb6526fa9f860413c976e7a9d8a8f5ddf4ff036831aab289f7b3d7a19ae9d8
|
7
|
+
data.tar.gz: c9d96690ad7703cd798ea486f7ae18c4c6f3cd5d7d84b5844d2d0dd1c5008438380c5e22911331cb8693c264138d2d2735637fd2a79ceef2a7a3ba07c60b84d3
|
data/.gitignore
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
# Created by https://www.gitignore.io/api/ruby
|
3
|
+
|
4
|
+
### Ruby ###
|
5
|
+
*.gem
|
6
|
+
*.rbc
|
7
|
+
/.config
|
8
|
+
/coverage/
|
9
|
+
/InstalledFiles
|
10
|
+
/pkg/
|
11
|
+
/spec/reports/
|
12
|
+
/spec/examples.txt
|
13
|
+
/test/tmp/
|
14
|
+
/test/version_tmp/
|
15
|
+
/tmp/
|
16
|
+
|
17
|
+
# Used by dotenv library to load environment variables.
|
18
|
+
# .env
|
19
|
+
|
20
|
+
## Specific to RubyMotion:
|
21
|
+
.dat*
|
22
|
+
.repl_history
|
23
|
+
build/
|
24
|
+
*.bridgesupport
|
25
|
+
build-iPhoneOS/
|
26
|
+
build-iPhoneSimulator/
|
27
|
+
|
28
|
+
## Specific to RubyMotion (use of CocoaPods):
|
29
|
+
#
|
30
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
31
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
32
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
33
|
+
#
|
34
|
+
# vendor/Pods/
|
35
|
+
|
36
|
+
## Documentation cache and generated files:
|
37
|
+
/.yardoc/
|
38
|
+
/_yardoc/
|
39
|
+
/doc/
|
40
|
+
/rdoc/
|
41
|
+
|
42
|
+
## Environment normalization:
|
43
|
+
/.bundle/
|
44
|
+
/vendor/bundle
|
45
|
+
/lib/bundler/man/
|
46
|
+
|
47
|
+
# for a library or gem, you might want to ignore these files since the code is
|
48
|
+
# intended to run in multiple environments; otherwise, check them in:
|
49
|
+
Gemfile.lock
|
50
|
+
.ruby-version
|
51
|
+
.ruby-gemset
|
52
|
+
|
53
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
54
|
+
.rvmrc
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Metrics/MethodLength:
|
2
|
+
CountComments: false # count full line comments?
|
3
|
+
Max: 20
|
4
|
+
|
5
|
+
Metrics/LineLength:
|
6
|
+
Max: 125
|
7
|
+
|
8
|
+
Metrics/AbcSize:
|
9
|
+
Max: 30
|
10
|
+
|
11
|
+
Style/FileName:
|
12
|
+
Exclude:
|
13
|
+
- 'lib/parallel-rspec.rb'
|
14
|
+
|
15
|
+
Style/StringLiterals:
|
16
|
+
EnforcedStyle: double_quotes
|
17
|
+
|
18
|
+
Style/Documentation:
|
19
|
+
Enabled: false
|
data/.simplecov
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# RSpec::Parallel
|
2
|
+
|
3
|
+
[](https://app.wercker.com/project/byKey/214cac59fa2938c9d373983bba71623e)
|
4
|
+
|
5
|
+
Parallel spec runner for RSpec 3.
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
```sh
|
10
|
+
$ gem install parallel-rspec
|
11
|
+
```
|
12
|
+
|
13
|
+
## Getting Started / Usage
|
14
|
+
|
15
|
+
Parallel-rspec bundles `parallel-rspec` binary which can be used directly:
|
16
|
+
|
17
|
+
```sh
|
18
|
+
$ parallel-rspec spec
|
19
|
+
```
|
20
|
+
|
21
|
+
If spec/parallel_spec_helper.rb is found, the `parallel-rspec` command loads it before starting the test. Since parallel-rspec uses fork(2) to spawn off workers, you must ensure each worker runs in an isolated environment. Use the `after_fork` hook to reset any global state.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
RSpec::Parallel.configure do |config|
|
25
|
+
config.after_fork do |worker|
|
26
|
+
# Use separate database.
|
27
|
+
ActiveRecord::Base.configurations["test"]["database"] << worker.number.to_s
|
28
|
+
ActiveRecord::Base.establish_connection(:test)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
```
|
32
|
+
|
33
|
+
In this case, your workers assume sequence of databases exist and has right schema already. Rspec-parallel ships with `db:test:prepare_sequential` rake task to prepare them for your Rails application:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
$ rake db:test:prepare_sequential
|
37
|
+
```
|
38
|
+
|
39
|
+
### Controll concurrency
|
40
|
+
|
41
|
+
The number of workers spawned by parallel-rspec is the number of available CPU cores by default. To controll the concurrency, use `concurrency` configuration option:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
RSpec::Parallel.configure do |config|
|
45
|
+
config.concurrency = 4
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
`db:test:prepare_sequential` task takes concurrency as an argument.
|
50
|
+
|
51
|
+
```sh
|
52
|
+
$ rake "db:test:prepare_sequential[4]"
|
53
|
+
```
|
54
|
+
|
55
|
+
## License
|
56
|
+
|
57
|
+
[MIT](https://github.com/yuku-t/parallel-rspec/blob/master/LICENSE) © [Yuku TAKAHASHI](https://github.com/yuku-t)
|
data/Rakefile
ADDED
data/bin/parallel-rspec
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require "rspec/parallel"
|
2
|
+
require "rspec/parallel/configuration"
|
3
|
+
require "rspec/parallel/master"
|
4
|
+
require "rspec/parallel/railtie" if defined? Rails::Railtie
|
5
|
+
require "rspec/parallel/runner"
|
6
|
+
require "rspec/parallel/socket_builder"
|
7
|
+
require "rspec/parallel/version"
|
8
|
+
require "rspec/parallel/worker"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rspec/parallel/configuration"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Parallel
|
5
|
+
# @return [RSpec::Parallel::Configuration]
|
6
|
+
def self.configuration
|
7
|
+
@configuration ||= RSpec::Parallel::Configuration.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# Yields the global configuration to a block.
|
11
|
+
#
|
12
|
+
# @yield [RSpec::Parallel::Configuration]
|
13
|
+
# @example
|
14
|
+
# RSpec::Parallel.configure do |config|
|
15
|
+
# config.bind = "0.0.0.0:8000"
|
16
|
+
# end
|
17
|
+
def self.configure
|
18
|
+
yield configuration if block_given?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "logger"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Parallel
|
5
|
+
# Stores runtime configuration information.
|
6
|
+
#
|
7
|
+
# @!attribute concurrency
|
8
|
+
# @return [Integer]
|
9
|
+
class Configuration
|
10
|
+
DEFULT_AFTER_FORK = ->(_worker) {}
|
11
|
+
|
12
|
+
def after_fork(&block)
|
13
|
+
@after_fork_block = block_given? ? block : DEFULT_AFTER_FORK
|
14
|
+
end
|
15
|
+
|
16
|
+
def after_fork_block
|
17
|
+
@after_fork_block ||= DEFULT_AFTER_FORK
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Integer]
|
21
|
+
def concurrency
|
22
|
+
@concurrency ||=
|
23
|
+
if File.exist?("/proc/cpuinfo")
|
24
|
+
File.read("/proc/cpuinfo").split("\n").grep(/processor/).size
|
25
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
26
|
+
`/usr/sbin/sysctl -n hw.activecpu`.to_i
|
27
|
+
else
|
28
|
+
2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Logger]
|
33
|
+
def logger
|
34
|
+
@logger ||= Logger.new(STDERR).tap do |logger|
|
35
|
+
logger.level = log_level
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Integer]
|
40
|
+
def log_level
|
41
|
+
@log_level ||= Logger::WARN
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_writer :concurrency, :logger, :log_level
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "English"
|
2
|
+
require "fileutils"
|
3
|
+
require "rspec/core"
|
4
|
+
require "socket"
|
5
|
+
|
6
|
+
require_relative "errors"
|
7
|
+
require_relative "protocol"
|
8
|
+
require_relative "socket_builder"
|
9
|
+
|
10
|
+
module RSpec
|
11
|
+
module Parallel
|
12
|
+
class Master
|
13
|
+
# @param args [Array<String>]
|
14
|
+
attr_reader :args
|
15
|
+
|
16
|
+
# @note RSpec must be configured ahead
|
17
|
+
# @param args [Array<String>] command line arguments
|
18
|
+
def initialize(args)
|
19
|
+
@args = args
|
20
|
+
@path = "/tmp/parallel-rspec-#{$PID}.sock"
|
21
|
+
@files_to_run = ::RSpec.configuration.files_to_run.uniq
|
22
|
+
@server = ::UNIXServer.new(@path)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [void]
|
26
|
+
def close
|
27
|
+
server.close
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [void]
|
31
|
+
def run
|
32
|
+
until files_to_run.empty?
|
33
|
+
rs, _ws, _es = IO.select([server])
|
34
|
+
rs.each do |s|
|
35
|
+
socket = s.accept
|
36
|
+
method, _data = socket.gets.strip.split("\t", 2)
|
37
|
+
case method
|
38
|
+
when Protocol::POP
|
39
|
+
path = files_to_run.pop
|
40
|
+
RSpec::Parallel.configuration.logger.info("Deliver #{path}")
|
41
|
+
socket.write(path)
|
42
|
+
when Protocol::PING
|
43
|
+
socket.write("ok")
|
44
|
+
end
|
45
|
+
socket.close
|
46
|
+
end
|
47
|
+
end
|
48
|
+
close
|
49
|
+
remove_socket_file
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a socket builder which builds a socket to
|
53
|
+
# connect with the master process.
|
54
|
+
#
|
55
|
+
# @return [RSpec::Parallel::SocketBuilder]
|
56
|
+
def socket_builder
|
57
|
+
SocketBuilder.new(path)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# @return [String, nil] path to unix domain socket
|
63
|
+
attr_reader :path
|
64
|
+
|
65
|
+
# @example
|
66
|
+
# files_to_run
|
67
|
+
# #=> ["spec/rspec/parallel_spec.rb", "spec/rspec/parallel/configuration_spec.rb"]
|
68
|
+
# @return [Array<String>]
|
69
|
+
attr_reader :files_to_run
|
70
|
+
|
71
|
+
# @return [UNIXServer]
|
72
|
+
attr_reader :server
|
73
|
+
|
74
|
+
# @return [void]
|
75
|
+
def remove_socket_file
|
76
|
+
FileUtils.rm(path, force: true)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "rspec/parallel"
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
namespace :test do
|
5
|
+
desc "Prepare sequence of databases for parallel-rspec"
|
6
|
+
task :prepare_sequential, ["concurrency"] => :environment do |_, args|
|
7
|
+
require "active_record/tasks/database_tasks"
|
8
|
+
concurrency = Integer(args[:concurrency] || RSpec::Parallel.configuration.concurrency)
|
9
|
+
|
10
|
+
concurrency.times do |i|
|
11
|
+
database = ActiveRecord::Base.configurations["test"]["database"] + i.to_s
|
12
|
+
configuration = ActiveRecord::Base.configurations["test"].merge("database" => database)
|
13
|
+
|
14
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(configuration) unless ENV["CI"]
|
15
|
+
puts "Create and load schema to #{database}"
|
16
|
+
ActiveRecord::Tasks::DatabaseTasks.create(configuration)
|
17
|
+
stdout = $stdout
|
18
|
+
begin
|
19
|
+
$stdout = File.open(File::NULL, "w")
|
20
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_for(configuration)
|
21
|
+
ensure
|
22
|
+
$stdout = stdout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "English"
|
2
|
+
|
3
|
+
require_relative "master"
|
4
|
+
require_relative "worker"
|
5
|
+
|
6
|
+
module RSpec
|
7
|
+
module Parallel
|
8
|
+
class Runner
|
9
|
+
# @return [Array<Integer>] array of pids of spawned worker processes
|
10
|
+
attr_reader :pids
|
11
|
+
|
12
|
+
# @param args [Array<String>] command line arguments
|
13
|
+
def initialize(args)
|
14
|
+
@args = args
|
15
|
+
@pids = []
|
16
|
+
|
17
|
+
# Configure RSpec core before initialize master instance and spawning
|
18
|
+
# worker processes to share its configuration.
|
19
|
+
configure_rspec
|
20
|
+
@master = Master.new(args)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [void]
|
24
|
+
def start
|
25
|
+
RSpec::Parallel.configuration.concurrency.times do
|
26
|
+
spawn_worker
|
27
|
+
end
|
28
|
+
master.run
|
29
|
+
Process.waitall
|
30
|
+
ensure
|
31
|
+
pids.each.with_index do |pid, index|
|
32
|
+
puts "----> output from worker[#{index}]"
|
33
|
+
File.open(output_file_path(pid)) do |file|
|
34
|
+
puts file.read
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [Array<String>]
|
42
|
+
attr_reader :args
|
43
|
+
|
44
|
+
# @return [RSpec::Parallel::Master]
|
45
|
+
attr_reader :master
|
46
|
+
|
47
|
+
# @param master [RSpec::Parallel::Master]
|
48
|
+
def spawn_worker
|
49
|
+
pid = Kernel.fork do
|
50
|
+
master.close
|
51
|
+
|
52
|
+
File.open(output_file_path($PID), "w") do |file|
|
53
|
+
# Redirect stdout and stderr to temp file
|
54
|
+
STDOUT.reopen(file)
|
55
|
+
STDERR.reopen(STDOUT)
|
56
|
+
STDOUT.sync = STDERR.sync = true
|
57
|
+
|
58
|
+
worker = Worker.new(master, pids.size)
|
59
|
+
$0 = "parallel-rspec worker [#{worker.number}]"
|
60
|
+
RSpec::Parallel.configuration.after_fork_block.call(worker)
|
61
|
+
worker.run
|
62
|
+
end
|
63
|
+
|
64
|
+
Kernel.exit! # avoid running any `at_exit` functions.
|
65
|
+
end
|
66
|
+
pids << pid
|
67
|
+
Process.detach(pid)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param pid [Integer]
|
71
|
+
# @return [String]
|
72
|
+
def output_file_path(pid)
|
73
|
+
"/tmp/parallel-rspec-worker-#{pid}"
|
74
|
+
end
|
75
|
+
|
76
|
+
def configure_rspec
|
77
|
+
options = ::RSpec::Core::ConfigurationOptions.new(args)
|
78
|
+
options.configure(::RSpec.configuration)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Parallel
|
5
|
+
class SocketBuilder
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [BasicSocket, nil]
|
11
|
+
def run(retry_counter = 3)
|
12
|
+
build
|
13
|
+
rescue
|
14
|
+
retry_counter -= 1
|
15
|
+
if retry_counter > 0
|
16
|
+
sleep rand
|
17
|
+
retry
|
18
|
+
end
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# @return [UNIXSocket]
|
25
|
+
def build
|
26
|
+
::UNIXSocket.new(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String]
|
30
|
+
attr_reader :path
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require_relative "protocol"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Parallel
|
5
|
+
class Worker
|
6
|
+
# @return [Integer]
|
7
|
+
attr_reader :number
|
8
|
+
|
9
|
+
# @param master [RSpec::Parallel::Master]
|
10
|
+
# @param number [Integer]
|
11
|
+
def initialize(master, number)
|
12
|
+
RSpec::Parallel.configuration.logger.info("Initialize Iterator")
|
13
|
+
@iterator = Iterator.new(master.socket_builder)
|
14
|
+
@number = number
|
15
|
+
RSpec::Parallel.configuration.logger.info("Initialize SpecRunner")
|
16
|
+
@spec_runner = SpecRunner.new(master.args)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [void]
|
20
|
+
def run
|
21
|
+
iterator.ping
|
22
|
+
spec_runner.run_specs(iterator).to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :iterator, :spec_runner
|
28
|
+
|
29
|
+
class Iterator
|
30
|
+
include Enumerable
|
31
|
+
|
32
|
+
# @param socket_builder [RSpec::Parallel::SocketBuilder]
|
33
|
+
def initialize(socket_builder)
|
34
|
+
@socket_builder = socket_builder
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [void]
|
38
|
+
def ping
|
39
|
+
loop do
|
40
|
+
socket = connect_to_distributor
|
41
|
+
if socket.nil?
|
42
|
+
RSpec::Parallel.configuration.logger.info("Sleep a little to wait master process")
|
43
|
+
sleep 0.5
|
44
|
+
next
|
45
|
+
end
|
46
|
+
RSpec::Parallel.configuration.logger.info("Send PING request")
|
47
|
+
socket.puts(Protocol::PING)
|
48
|
+
# TODO: handle socket error and check pong message
|
49
|
+
IO.select([socket])
|
50
|
+
socket.read(65_536)
|
51
|
+
socket.close
|
52
|
+
break
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @yield [RSpec::Core::ExampleGroup]
|
57
|
+
def each
|
58
|
+
loop do
|
59
|
+
socket = connect_to_distributor
|
60
|
+
break if socket.nil?
|
61
|
+
RSpec::Parallel.configuration.logger.info("Send POP request")
|
62
|
+
socket.puts(Protocol::POP)
|
63
|
+
_, _, es = IO.select([socket], nil, [socket])
|
64
|
+
unless es.empty?
|
65
|
+
RSpec::Parallel.configuration.logger.error("Socket error occurs")
|
66
|
+
break
|
67
|
+
end
|
68
|
+
path = socket.read(65_536)
|
69
|
+
socket.close
|
70
|
+
RSpec.world.example_groups.clear
|
71
|
+
RSpec::Parallel.configuration.logger.info("Load #{path}")
|
72
|
+
Kernel.load path
|
73
|
+
RSpec.world.example_groups.each do |example_group|
|
74
|
+
yield example_group
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# @return [RSpec::Parallel::SocketBuilder]
|
82
|
+
attr_reader :socket_builder
|
83
|
+
|
84
|
+
# @return [BasicSocket, nil]
|
85
|
+
def connect_to_distributor
|
86
|
+
socket_builder.run
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class SpecRunner < RSpec::Core::Runner
|
91
|
+
# @param args [Array<String>]
|
92
|
+
def initialize(args)
|
93
|
+
options = RSpec::Core::ConfigurationOptions.new(args)
|
94
|
+
super(options)
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param example_groups [Array<RSpec::Core::ExampleGroup>]
|
98
|
+
# @return [Integer] exit status code
|
99
|
+
def run_specs(example_groups)
|
100
|
+
# Reset filter manager to run all specs. Just for simplicity
|
101
|
+
# TODO: Support config.run_all_when_everything_filtered = true
|
102
|
+
@configuration.filter_manager = RSpec::Core::FilterManager.new
|
103
|
+
|
104
|
+
success = @configuration.reporter.report(0) do |reporter|
|
105
|
+
@configuration.with_suite_hooks do
|
106
|
+
example_groups.map do |g|
|
107
|
+
RSpec::Parallel.configuration.logger.info("Run #{g.inspect}")
|
108
|
+
g.run(reporter)
|
109
|
+
end.all?
|
110
|
+
end
|
111
|
+
end && !@world.non_example_failure
|
112
|
+
|
113
|
+
success ? 0 : @configuration.failure_exit_code
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require "rspec/parallel/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "parallel-rspec"
|
8
|
+
spec.authors = ["Yuku Takahashi"]
|
9
|
+
spec.email = ["taka84u9@gmail.com"]
|
10
|
+
spec.version = RSpec::Parallel::VERSION
|
11
|
+
spec.summary = "Parallel spec runner for RSpec 3"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = ">= 2.0"
|
14
|
+
spec.homepage = "https://github.com/yuku-t/parallel-rspec"
|
15
|
+
|
16
|
+
spec.executables = ["parallel-rspec"]
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
|
18
|
+
|
19
|
+
spec.add_dependency "rspec-core", "~> 3.0"
|
20
|
+
|
21
|
+
spec.add_development_dependency "rake", "~> 11.3"
|
22
|
+
spec.add_development_dependency "redcarpet", "~> 3.3.4"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.5.0"
|
24
|
+
spec.add_development_dependency "rubocop", "~> 0.45.0"
|
25
|
+
spec.add_development_dependency "simplecov", "~> 0.12.0"
|
26
|
+
spec.add_development_dependency "yard", "~> 0.9.5"
|
27
|
+
end
|
data/wercker.yml
ADDED
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: parallel-rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yuku Takahashi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-12-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '11.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '11.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: redcarpet
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.3.4
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.3.4
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 3.5.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.5.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.45.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.45.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.12.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.12.0
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.9.5
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.9.5
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
- taka84u9@gmail.com
|
114
|
+
executables:
|
115
|
+
- parallel-rspec
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rspec"
|
121
|
+
- ".rubocop.yml"
|
122
|
+
- ".simplecov"
|
123
|
+
- ".yardopts"
|
124
|
+
- Gemfile
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- bin/parallel-rspec
|
128
|
+
- lib/parallel-rspec.rb
|
129
|
+
- lib/rspec/parallel.rb
|
130
|
+
- lib/rspec/parallel/configuration.rb
|
131
|
+
- lib/rspec/parallel/errors.rb
|
132
|
+
- lib/rspec/parallel/master.rb
|
133
|
+
- lib/rspec/parallel/protocol.rb
|
134
|
+
- lib/rspec/parallel/railtie.rb
|
135
|
+
- lib/rspec/parallel/rake_task.rb
|
136
|
+
- lib/rspec/parallel/runner.rb
|
137
|
+
- lib/rspec/parallel/socket_builder.rb
|
138
|
+
- lib/rspec/parallel/version.rb
|
139
|
+
- lib/rspec/parallel/worker.rb
|
140
|
+
- parallel-rspec.gemspec
|
141
|
+
- wercker.yml
|
142
|
+
homepage: https://github.com/yuku-t/parallel-rspec
|
143
|
+
licenses:
|
144
|
+
- MIT
|
145
|
+
metadata: {}
|
146
|
+
post_install_message:
|
147
|
+
rdoc_options: []
|
148
|
+
require_paths:
|
149
|
+
- lib
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ">="
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '2.0'
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
requirements: []
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 2.5.1
|
163
|
+
signing_key:
|
164
|
+
specification_version: 4
|
165
|
+
summary: Parallel spec runner for RSpec 3
|
166
|
+
test_files: []
|