parallel-rspec 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +19 -0
- data/LICENSE +21 -0
- data/bin/parallel-rspec +2 -1
- data/lib/rspec/parallel/configuration.rb +1 -1
- data/lib/rspec/parallel/master.rb +8 -2
- data/lib/rspec/parallel/runner.rb +7 -5
- data/lib/rspec/parallel/version.rb +1 -1
- data/lib/rspec/parallel/worker.rb +19 -10
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8b1cbb0a88df18c96b32c13c67195692a7618c0db805e900a3ae05e750701299
|
4
|
+
data.tar.gz: 930f387786a51fd24b6a3d4705a1afc424c84f9e4eb42527576cb2a4d81d60c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf874688c79e8a413254cc7c0718d57a5fbac581f67498916797bb447235c9c70767ac9931300fa4de5f95c1f4064cacbffdc03c180e67b9852b9e42458be634
|
7
|
+
data.tar.gz: 785b1509878689e253125edbe18245f6433180a7dda49b612a7f3ac75b941cc87d1db268a7dc582a81fb4b86a7f54ff5c2000c29dcabcddcf3517b2ff00bd1ad
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [0.1.1] - 2019-02-19
|
10
|
+
### Fixed
|
11
|
+
- Handle exit code
|
12
|
+
|
13
|
+
## 0.1.0 - 2016-12-31
|
14
|
+
### Added
|
15
|
+
- Basic implementation
|
16
|
+
- README now contains "Getting Started / Usage" and "Controll concurrency"
|
17
|
+
|
18
|
+
[Unreleased]: https://github.com/yuku/parallel-rspec/compare/v0.1.1...HEAD
|
19
|
+
[0.1.1]: https://github.com/yuku/parallel-rspec/compare/v0.1.0...v0.1.1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Yuku TAKAHASHI
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/bin/parallel-rspec
CHANGED
@@ -5,4 +5,5 @@ require "parallel-rspec"
|
|
5
5
|
helper_path = ENV.fetch("RSPEC_PARALLEL_HELPER", "spec/parallel_spec_helper.rb")
|
6
6
|
Kernel.load(helper_path) if File.readable?(helper_path)
|
7
7
|
|
8
|
-
RSpec::Parallel::Runner.new(ARGV).start
|
8
|
+
exit_code = RSpec::Parallel::Runner.new(ARGV).start
|
9
|
+
Kernel.exit(exit_code)
|
@@ -19,6 +19,7 @@ module RSpec
|
|
19
19
|
@args = args
|
20
20
|
@path = "/tmp/parallel-rspec-#{$PID}.sock"
|
21
21
|
@files_to_run = ::RSpec.configuration.files_to_run.uniq
|
22
|
+
@total = @files_to_run.size
|
22
23
|
@server = ::UNIXServer.new(@path)
|
23
24
|
end
|
24
25
|
|
@@ -29,15 +30,17 @@ module RSpec
|
|
29
30
|
|
30
31
|
# @return [void]
|
31
32
|
def run
|
33
|
+
count = 1
|
32
34
|
until files_to_run.empty?
|
33
35
|
rs, _ws, _es = IO.select([server])
|
34
36
|
rs.each do |s|
|
35
37
|
socket = s.accept
|
36
|
-
method,
|
38
|
+
method, data = socket.gets.strip.split(" ", 2)
|
37
39
|
case method
|
38
40
|
when Protocol::POP
|
39
41
|
path = files_to_run.pop
|
40
|
-
RSpec::Parallel.configuration.logger.info("Deliver #{path}")
|
42
|
+
RSpec::Parallel.configuration.logger.info("[#{count} / #{total}] Deliver #{path} to worker[#{data}]")
|
43
|
+
count += 1
|
41
44
|
socket.write(path)
|
42
45
|
when Protocol::PING
|
43
46
|
socket.write("ok")
|
@@ -71,6 +74,9 @@ module RSpec
|
|
71
74
|
# @return [UNIXServer]
|
72
75
|
attr_reader :server
|
73
76
|
|
77
|
+
# @return [Integer]
|
78
|
+
attr_reader :total
|
79
|
+
|
74
80
|
# @return [void]
|
75
81
|
def remove_socket_file
|
76
82
|
FileUtils.rm(path, force: true)
|
@@ -20,13 +20,15 @@ module RSpec
|
|
20
20
|
@master = Master.new(args)
|
21
21
|
end
|
22
22
|
|
23
|
-
# @return [
|
23
|
+
# @return [Integer] exit status code
|
24
24
|
def start
|
25
|
+
waiters = []
|
25
26
|
RSpec::Parallel.configuration.concurrency.times do
|
26
|
-
spawn_worker
|
27
|
+
waiters << spawn_worker
|
27
28
|
end
|
28
29
|
master.run
|
29
|
-
|
30
|
+
statuses = waiters.map {|waiter| waiter.value }
|
31
|
+
statuses.all? {|status| status.success? } ? 0 : 1
|
30
32
|
ensure
|
31
33
|
pids.each.with_index do |pid, index|
|
32
34
|
puts "----> output from worker[#{index}]"
|
@@ -49,7 +51,7 @@ module RSpec
|
|
49
51
|
pid = Kernel.fork do
|
50
52
|
master.close
|
51
53
|
|
52
|
-
File.open(output_file_path($PID), "w") do |file|
|
54
|
+
exit_code = File.open(output_file_path($PID), "w") do |file|
|
53
55
|
# Redirect stdout and stderr to temp file
|
54
56
|
STDOUT.reopen(file)
|
55
57
|
STDERR.reopen(STDOUT)
|
@@ -61,7 +63,7 @@ module RSpec
|
|
61
63
|
worker.run
|
62
64
|
end
|
63
65
|
|
64
|
-
Kernel.exit! # avoid running any `at_exit` functions.
|
66
|
+
Kernel.exit!(exit_code == 0) # avoid running any `at_exit` functions.
|
65
67
|
end
|
66
68
|
pids << pid
|
67
69
|
Process.detach(pid)
|
@@ -9,10 +9,10 @@ module RSpec
|
|
9
9
|
# @param master [RSpec::Parallel::Master]
|
10
10
|
# @param number [Integer]
|
11
11
|
def initialize(master, number)
|
12
|
-
RSpec::Parallel.configuration.logger.
|
13
|
-
@iterator = Iterator.new(master.socket_builder)
|
12
|
+
RSpec::Parallel.configuration.logger.debug("Initialize Iterator")
|
13
|
+
@iterator = Iterator.new(self, master.socket_builder)
|
14
14
|
@number = number
|
15
|
-
RSpec::Parallel.configuration.logger.
|
15
|
+
RSpec::Parallel.configuration.logger.debug("Initialize SpecRunner")
|
16
16
|
@spec_runner = SpecRunner.new(master.args)
|
17
17
|
end
|
18
18
|
|
@@ -29,8 +29,10 @@ module RSpec
|
|
29
29
|
class Iterator
|
30
30
|
include Enumerable
|
31
31
|
|
32
|
+
# @param worker [RSpec::Parallel::Worker]
|
32
33
|
# @param socket_builder [RSpec::Parallel::SocketBuilder]
|
33
|
-
def initialize(socket_builder)
|
34
|
+
def initialize(worker, socket_builder)
|
35
|
+
@worker = worker
|
34
36
|
@socket_builder = socket_builder
|
35
37
|
end
|
36
38
|
|
@@ -39,11 +41,11 @@ module RSpec
|
|
39
41
|
loop do
|
40
42
|
socket = connect_to_distributor
|
41
43
|
if socket.nil?
|
42
|
-
RSpec::Parallel.configuration.logger.
|
44
|
+
RSpec::Parallel.configuration.logger.debug("Sleep a little to wait master process")
|
43
45
|
sleep 0.5
|
44
46
|
next
|
45
47
|
end
|
46
|
-
RSpec::Parallel.configuration.logger.
|
48
|
+
RSpec::Parallel.configuration.logger.debug("Send PING request")
|
47
49
|
socket.puts(Protocol::PING)
|
48
50
|
# TODO: handle socket error and check pong message
|
49
51
|
IO.select([socket])
|
@@ -58,8 +60,8 @@ module RSpec
|
|
58
60
|
loop do
|
59
61
|
socket = connect_to_distributor
|
60
62
|
break if socket.nil?
|
61
|
-
RSpec::Parallel.configuration.logger.
|
62
|
-
socket.puts(Protocol::POP)
|
63
|
+
RSpec::Parallel.configuration.logger.debug("Send POP request")
|
64
|
+
socket.puts("#{Protocol::POP} #{worker.number}") # TODO: Rescue `Broken pipe (Errno::EPIPE)` error
|
63
65
|
_, _, es = IO.select([socket], nil, [socket])
|
64
66
|
unless es.empty?
|
65
67
|
RSpec::Parallel.configuration.logger.error("Socket error occurs")
|
@@ -68,7 +70,7 @@ module RSpec
|
|
68
70
|
path = socket.read(65_536)
|
69
71
|
socket.close
|
70
72
|
RSpec.world.example_groups.clear
|
71
|
-
RSpec::Parallel.configuration.logger.
|
73
|
+
RSpec::Parallel.configuration.logger.debug("Load #{path}")
|
72
74
|
Kernel.load path
|
73
75
|
RSpec.world.example_groups.each do |example_group|
|
74
76
|
yield example_group
|
@@ -81,6 +83,9 @@ module RSpec
|
|
81
83
|
# @return [RSpec::Parallel::SocketBuilder]
|
82
84
|
attr_reader :socket_builder
|
83
85
|
|
86
|
+
# @return [RSpec::Parallel::Worker]
|
87
|
+
attr_reader :worker
|
88
|
+
|
84
89
|
# @return [BasicSocket, nil]
|
85
90
|
def connect_to_distributor
|
86
91
|
socket_builder.run
|
@@ -102,9 +107,13 @@ module RSpec
|
|
102
107
|
@configuration.filter_manager = RSpec::Core::FilterManager.new
|
103
108
|
|
104
109
|
success = @configuration.reporter.report(0) do |reporter|
|
110
|
+
# In genaral, ExampleGroup is configured by evaluating `describe`
|
111
|
+
# before `with_suite_hooks`
|
112
|
+
RSpec::Core::ExampleGroup.ensure_example_groups_are_configured
|
113
|
+
|
105
114
|
@configuration.with_suite_hooks do
|
106
115
|
example_groups.map do |g|
|
107
|
-
RSpec::Parallel.configuration.logger.
|
116
|
+
RSpec::Parallel.configuration.logger.debug("Run #{g.inspect}")
|
108
117
|
g.run(reporter)
|
109
118
|
end.all?
|
110
119
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel-rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuku Takahashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-core
|
@@ -121,7 +121,9 @@ files:
|
|
121
121
|
- ".rubocop.yml"
|
122
122
|
- ".simplecov"
|
123
123
|
- ".yardopts"
|
124
|
+
- CHANGELOG.md
|
124
125
|
- Gemfile
|
126
|
+
- LICENSE
|
125
127
|
- README.md
|
126
128
|
- Rakefile
|
127
129
|
- bin/parallel-rspec
|
@@ -158,8 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
160
|
- !ruby/object:Gem::Version
|
159
161
|
version: '0'
|
160
162
|
requirements: []
|
161
|
-
|
162
|
-
rubygems_version: 2.5.1
|
163
|
+
rubygems_version: 3.0.1
|
163
164
|
signing_key:
|
164
165
|
specification_version: 4
|
165
166
|
summary: Parallel spec runner for RSpec 3
|