rspec-multiprocess_runner 1.2.0 → 1.2.1
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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +6 -0
- data/exe/multirspec +2 -1
- data/lib/rspec/multiprocess_runner/command_line_options.rb +6 -1
- data/lib/rspec/multiprocess_runner/coordinator.rb +3 -3
- data/lib/rspec/multiprocess_runner/file_coordinator.rb +28 -12
- data/lib/rspec/multiprocess_runner/rake_task.rb +6 -0
- data/lib/rspec/multiprocess_runner/version.rb +1 -1
- data/lib/rspec/multiprocess_runner/worker.rb +14 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7232c081ac1d6c3946e41139e61f7eabd655fac
|
4
|
+
data.tar.gz: 9a2a5afdf4915f7fc0ba5453a657da788817bce9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4639ae0212bf4cdc713f1e2738a683e55d561fea521ddb0221e539f23679d917e59ff7d28f8d06c21b72aec7ee1d1ee06399380cef948548ea7b27fa4471cae2
|
7
|
+
data.tar.gz: 5698b967a5ff5791ef8ec29f8811502233bd8793c12d8686702c920817b062782da2ec27fece84d937a778a6ae9343745803d28fc6e553774ebca989bfe80c76
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 1.2.1
|
2
|
+
|
3
|
+
* Fix missing files being triggered by empty files
|
4
|
+
|
5
|
+
* Fix missing files also being skipped files
|
6
|
+
|
7
|
+
* Add run identifier option to prevent incorrect spec version execution
|
8
|
+
|
1
9
|
# 1.2.0
|
2
10
|
|
3
11
|
* Can now run tests on multiple machines at a time by running in head node mode
|
data/README.md
CHANGED
@@ -101,6 +101,12 @@ A corresponding set up for a node node using SSH would be:
|
|
101
101
|
|
102
102
|
N.B. Ensure that the head node has tcp local port forwarding permitted.
|
103
103
|
|
104
|
+
A set of nodes and head node can be given a unique string in case multiple spec
|
105
|
+
file versions may be tested near simultaneously to prevent execution of the
|
106
|
+
wrong version.
|
107
|
+
|
108
|
+
$ multirspec -r a_git_commit_hash
|
109
|
+
|
104
110
|
### Rake
|
105
111
|
|
106
112
|
There is a rake task wrapper for `multirspec`:
|
data/exe/multirspec
CHANGED
@@ -19,7 +19,8 @@ coordinator = RSpec::MultiprocessRunner::Coordinator.new(
|
|
19
19
|
head_node: options.head_node,
|
20
20
|
port: options.port,
|
21
21
|
hostname: options.hostname,
|
22
|
-
max_nodes: options.max_nodes
|
22
|
+
max_nodes: options.max_nodes,
|
23
|
+
run_identifier: options.run_identifier
|
23
24
|
}
|
24
25
|
)
|
25
26
|
|
@@ -7,7 +7,8 @@ module RSpec::MultiprocessRunner
|
|
7
7
|
class CommandLineOptions
|
8
8
|
attr_accessor :worker_count, :file_timeout_seconds, :example_timeout_seconds,
|
9
9
|
:rspec_options, :explicit_files_or_directories, :pattern, :log_failing_files,
|
10
|
-
:first_is_1, :use_given_order, :port, :head_node, :hostname, :max_nodes
|
10
|
+
:first_is_1, :use_given_order, :port, :head_node, :hostname, :max_nodes,
|
11
|
+
:run_identifier
|
11
12
|
|
12
13
|
DEFAULT_WORKER_COUNT = 3
|
13
14
|
|
@@ -139,6 +140,10 @@ module RSpec::MultiprocessRunner
|
|
139
140
|
self.max_nodes = max_nodes
|
140
141
|
end
|
141
142
|
|
143
|
+
parser.on("-r", "--run-identifier STRING", "A unique string used by nodes to confirm identity (e.g. a git commit hash)") do |string|
|
144
|
+
self.run_identifier = string
|
145
|
+
end
|
146
|
+
|
142
147
|
parser.on_tail("-h", "--help", "Prints this help") do
|
143
148
|
help_requested!
|
144
149
|
end
|
@@ -27,7 +27,7 @@ module RSpec::MultiprocessRunner
|
|
27
27
|
run_loop
|
28
28
|
quit_all_workers
|
29
29
|
@file_coordinator.finished
|
30
|
-
if @file_coordinator.
|
30
|
+
if @file_coordinator.remaining_files.any?
|
31
31
|
run_loop
|
32
32
|
quit_all_workers
|
33
33
|
@file_coordinator.finished
|
@@ -222,7 +222,7 @@ module RSpec::MultiprocessRunner
|
|
222
222
|
print_pending_example_details(by_status_and_time["pending"])
|
223
223
|
print_failed_example_details(by_status_and_time["failed"])
|
224
224
|
print_missing_files
|
225
|
-
log_failed_files(by_status_and_time["failed"].map(&:
|
225
|
+
log_failed_files(by_status_and_time["failed"].map(&:filename).uniq + @file_coordinator.missing_files.to_a) if @log_failing_files
|
226
226
|
print_failed_process_details
|
227
227
|
puts
|
228
228
|
print_elapsed_time(elapsed)
|
@@ -231,7 +231,7 @@ module RSpec::MultiprocessRunner
|
|
231
231
|
end
|
232
232
|
|
233
233
|
def combine_example_results
|
234
|
-
@file_coordinator.results.sort_by { |r| r.time_finished }
|
234
|
+
@file_coordinator.results.select { |r| r.run_status == "example_complete" }.sort_by { |r| r.time_finished }
|
235
235
|
end
|
236
236
|
|
237
237
|
def any_example_failed?
|
@@ -22,6 +22,7 @@ module RSpec::MultiprocessRunner
|
|
22
22
|
@port = options[:port]
|
23
23
|
@max_threads = options[:max_nodes]
|
24
24
|
@head_node = options[:head_node]
|
25
|
+
@start_string = options[:run_identifier]
|
25
26
|
if @head_node
|
26
27
|
@spec_files = options[:use_given_order] ? files : sort_files(files)
|
27
28
|
Thread.start { run_tcp_server }
|
@@ -33,7 +34,11 @@ module RSpec::MultiprocessRunner
|
|
33
34
|
begin
|
34
35
|
@node_socket = TCPSocket.new @hostname, @port
|
35
36
|
raise unless start?
|
37
|
+
rescue BadStartStringError
|
38
|
+
@node_socket.close if @node_socket
|
39
|
+
raise
|
36
40
|
rescue
|
41
|
+
@node_socket.close if @node_socket
|
37
42
|
@node_socket = nil
|
38
43
|
raise if count < 0
|
39
44
|
count -= 1
|
@@ -51,7 +56,7 @@ module RSpec::MultiprocessRunner
|
|
51
56
|
|
52
57
|
def missing_files
|
53
58
|
if @head_node
|
54
|
-
@spec_files_reference - @results.map(&:
|
59
|
+
@spec_files_reference - @results.map(&:filename) - @failed_workers.map(&:current_file) - @spec_files
|
55
60
|
else
|
56
61
|
[]
|
57
62
|
end
|
@@ -81,9 +86,11 @@ module RSpec::MultiprocessRunner
|
|
81
86
|
|
82
87
|
def finished
|
83
88
|
if @head_node
|
84
|
-
@tcp_server_running
|
85
|
-
|
86
|
-
|
89
|
+
if @tcp_server_running
|
90
|
+
@tcp_server_running = false
|
91
|
+
@threads.each(&:join)
|
92
|
+
@spec_files += missing_files.to_a
|
93
|
+
end
|
87
94
|
else
|
88
95
|
@node_socket.puts [COMMAND_FINISHED].to_json
|
89
96
|
end
|
@@ -117,13 +124,18 @@ module RSpec::MultiprocessRunner
|
|
117
124
|
break unless raw_response
|
118
125
|
command, results, node = JSON.parse(raw_response)
|
119
126
|
if command == COMMAND_START
|
120
|
-
|
127
|
+
if results == @start_string
|
128
|
+
socket.puts COMMAND_START
|
129
|
+
else
|
130
|
+
socket.puts COMMAND_FINISHED
|
131
|
+
break
|
132
|
+
end
|
121
133
|
elsif command == COMMAND_FILE
|
122
134
|
socket.puts @spec_files.shift
|
123
135
|
elsif command == COMMAND_PROCESS && results
|
124
136
|
@failed_workers << MockWorker.from_json_parse(results, node || "unknown")
|
125
137
|
elsif command == COMMAND_RESULTS && results = results.map { |result|
|
126
|
-
|
138
|
+
Result.from_json_parse(result) }
|
127
139
|
@results += results
|
128
140
|
elsif command == COMMAND_FINISHED
|
129
141
|
break
|
@@ -131,18 +143,22 @@ module RSpec::MultiprocessRunner
|
|
131
143
|
end
|
132
144
|
end
|
133
145
|
|
134
|
-
def work_left_to_do?
|
135
|
-
!@spec_files.empty?
|
136
|
-
end
|
137
|
-
|
138
146
|
def start?
|
139
147
|
begin
|
140
|
-
@node_socket.puts [COMMAND_START].to_json
|
148
|
+
@node_socket.puts [COMMAND_START, @start_string].to_json
|
141
149
|
response = @node_socket.gets
|
142
|
-
response
|
150
|
+
response = response.chomp if response
|
151
|
+
raise BadStartStringError if response == COMMAND_FINISHED
|
152
|
+
response == COMMAND_START
|
143
153
|
rescue Errno::EPIPE
|
144
154
|
false
|
145
155
|
end
|
146
156
|
end
|
147
157
|
end
|
158
|
+
|
159
|
+
class BadStartStringError < StandardError
|
160
|
+
def initialize(msg="An incorrect unique string was passed by the head node.")
|
161
|
+
super
|
162
|
+
end
|
163
|
+
end
|
148
164
|
end
|
@@ -77,6 +77,9 @@ module RSpec::MultiprocessRunner
|
|
77
77
|
# Max number of connections to head_node. Defaults to `5`
|
78
78
|
attr_accessor :max_nodes
|
79
79
|
|
80
|
+
#Unique string used by nodes to confirm identity
|
81
|
+
attr_accessor :run_identifier
|
82
|
+
|
80
83
|
def initialize(*args, &task_block)
|
81
84
|
@name = args.shift || :multispec
|
82
85
|
@verbose = true
|
@@ -150,6 +153,9 @@ module RSpec::MultiprocessRunner
|
|
150
153
|
if max_nodes
|
151
154
|
cmd_parts << '--max-nodes' << max_nodes.to_s
|
152
155
|
end
|
156
|
+
if run_identifier
|
157
|
+
cmd_parts << '--run-identifier' << run-identifier.to_s
|
158
|
+
end
|
153
159
|
if files_or_directories
|
154
160
|
cmd_parts.concat(files_or_directories)
|
155
161
|
end
|
@@ -175,11 +175,12 @@ module RSpec::MultiprocessRunner
|
|
175
175
|
return :dead unless message_hash # ignore EOF
|
176
176
|
case message_hash["status"]
|
177
177
|
when STATUS_RUN_COMPLETE
|
178
|
+
example_results << Result.new(message_hash)
|
178
179
|
@current_file = nil
|
179
180
|
@current_file_started_at = nil
|
180
181
|
@current_example_started_at = nil
|
181
182
|
when STATUS_EXAMPLE_COMPLETE
|
182
|
-
example_results <<
|
183
|
+
example_results << Result.new(message_hash)
|
183
184
|
suffix =
|
184
185
|
case message_hash["example_status"]
|
185
186
|
when "failed"
|
@@ -219,7 +220,7 @@ module RSpec::MultiprocessRunner
|
|
219
220
|
description: description,
|
220
221
|
line_number: line_number,
|
221
222
|
details: details,
|
222
|
-
|
223
|
+
filename: @current_file
|
223
224
|
)
|
224
225
|
end
|
225
226
|
|
@@ -321,15 +322,16 @@ module RSpec::MultiprocessRunner
|
|
321
322
|
end
|
322
323
|
|
323
324
|
# @private
|
324
|
-
class
|
325
|
-
attr_reader :status, :description, :details, :
|
326
|
-
|
327
|
-
def initialize(
|
328
|
-
@hash =
|
329
|
-
@
|
330
|
-
@
|
331
|
-
@
|
332
|
-
@
|
325
|
+
class Result
|
326
|
+
attr_reader :run_status, :status, :description, :details, :filename, :time_finished
|
327
|
+
|
328
|
+
def initialize(complete_message, time = Time.now)
|
329
|
+
@hash = complete_message
|
330
|
+
@run_status = complete_message["status"]
|
331
|
+
@status = complete_message["example_status"]
|
332
|
+
@description = complete_message["description"]
|
333
|
+
@details = complete_message["details"]
|
334
|
+
@filename = complete_message["filename"]
|
333
335
|
@time_finished = time
|
334
336
|
end
|
335
337
|
|
@@ -338,7 +340,7 @@ module RSpec::MultiprocessRunner
|
|
338
340
|
end
|
339
341
|
|
340
342
|
def self.from_json_parse(hash)
|
341
|
-
|
343
|
+
Result.new(hash["hash"], Time.iso8601(hash["time"]))
|
342
344
|
end
|
343
345
|
end
|
344
346
|
end
|