rspec-multiprocess_runner 1.2.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|