parallel_tests 5.2.0 → 5.3.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/Readme.md +45 -23
- data/lib/parallel_tests/cli.rb +38 -8
- data/lib/parallel_tests/gherkin/runner.rb +10 -5
- data/lib/parallel_tests/rspec/runner.rb +5 -2
- data/lib/parallel_tests/test/runner.rb +21 -9
- data/lib/parallel_tests/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 976016bff736bf3c0a3318b375b57575596a97185e25e5991c1e4bf3853a359f
|
4
|
+
data.tar.gz: 970d5aa2f19a5166ce304d686681583ba20990439893e82c59926453f7d32277
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cc814265ca73b3ced92dad469fe94b42d9068aa29cc1ff218a74c920ef3d7c286eef27d6864b555852de6257cd2d041d801373a30c81936181bd5a7e612e672
|
7
|
+
data.tar.gz: feb60ffbb3b67da7990e406471bd4a8f6b4144453bc307bf33fdeca62111ed3744ca3a1a4e0fad2a80064e6db441aa68b18fb076d86586d8768d98a4f68ddbd3
|
data/Readme.md
CHANGED
@@ -101,17 +101,23 @@ require "parallel_tests"
|
|
101
101
|
|
102
102
|
# preparation:
|
103
103
|
# affected by race-condition: first process may boot slower than the second
|
104
|
-
#
|
105
|
-
|
104
|
+
# the Process.ppid will be the pod of the process that started the parallel tests
|
105
|
+
# when not using TEST_ENV_NUMBER we use a unique file per process because ppid would be the users shell
|
106
|
+
done = "/tmp/parallel-setup-done-#{ENV['TEST_ENV_NUMBER'] ? Process.ppid : Process.pid}"
|
107
|
+
if ParallelTests.first_process?
|
108
|
+
do_something
|
109
|
+
File.write done, "true"
|
110
|
+
else
|
111
|
+
sleep 0.1 until File.exist?(done)
|
112
|
+
end
|
106
113
|
|
107
114
|
# cleanup:
|
108
|
-
# last_process?
|
109
|
-
ParallelTests.last_process? ? do_something : sleep(1)
|
110
|
-
|
115
|
+
# could also use last_process? but that is just the last process to start, not the last to finish
|
111
116
|
at_exit do
|
112
117
|
if ParallelTests.first_process?
|
113
|
-
|
114
|
-
|
118
|
+
File.unlink done
|
119
|
+
ParallelTests.wait_for_other_processes_to_finish
|
120
|
+
undo_something
|
115
121
|
end
|
116
122
|
end
|
117
123
|
```
|
@@ -239,7 +245,7 @@ Setup for non-rails
|
|
239
245
|
`parallel_cucumber -n 2 -o '-p foo_profile --tags @only_this_tag or @only_that_tag --format summary'`
|
240
246
|
|
241
247
|
Options are:
|
242
|
-
<!--
|
248
|
+
<!-- rake readme -->
|
243
249
|
-n PROCESSES How many processes to use, default: available CPUs
|
244
250
|
-p, --pattern PATTERN run tests matching this regex pattern
|
245
251
|
--exclude-pattern PATTERN exclude tests matching this regex pattern
|
@@ -258,7 +264,7 @@ Options are:
|
|
258
264
|
--failure-exit-code INT Specify the exit code to use when tests fail
|
259
265
|
--specify-groups SPECS Use 'specify-groups' if you want to specify multiple specs running in multiple
|
260
266
|
processes in a specific formation. Commas indicate specs in the same process,
|
261
|
-
pipes indicate specs in a new process. If SPECS is a
|
267
|
+
pipes indicate specs in a new process. If SPECS is a '-' the value for this
|
262
268
|
option is read from STDIN instead. Cannot use with --single, --isolate, or
|
263
269
|
--isolate-n. Ex.
|
264
270
|
$ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
|
@@ -268,7 +274,10 @@ Options are:
|
|
268
274
|
--only-group GROUP_INDEX[,GROUP_INDEX]
|
269
275
|
Only run the given group numbers.
|
270
276
|
Changes `--group-by` default to 'filesize'.
|
271
|
-
-e, --exec COMMAND execute
|
277
|
+
-e, --exec COMMAND execute COMMAND in parallel and with ENV['TEST_ENV_NUMBER']
|
278
|
+
--exec-args COMMAND execute COMMAND in parallel with test files as arguments, for example:
|
279
|
+
$ parallel_tests --exec-args echo
|
280
|
+
> echo spec/a_spec.rb spec/b_spec.rb
|
272
281
|
-o, --test-options 'OPTIONS' execute test commands with those options
|
273
282
|
-t, --type TYPE test(default) / rspec / cucumber / spinach
|
274
283
|
--suffix PATTERN override built in test file pattern (should match suffix):
|
@@ -288,7 +297,9 @@ Options are:
|
|
288
297
|
--unknown-runtime SECONDS Use given number as unknown runtime (otherwise use average time)
|
289
298
|
--first-is-1 Use "1" as TEST_ENV_NUMBER to not reuse the default test environment
|
290
299
|
--fail-fast Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported
|
291
|
-
--test-file-limit LIMIT Limit to this number of files per test run by batching
|
300
|
+
--test-file-limit LIMIT Limit to this number of files per test run by batching
|
301
|
+
(for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number
|
302
|
+
and summarizing partial results)
|
292
303
|
--verbose Print debug output
|
293
304
|
--verbose-command Combines options --verbose-process-command and --verbose-rerun-command
|
294
305
|
--verbose-process-command Print the command that will be executed by each process before it begins
|
@@ -296,21 +307,31 @@ Options are:
|
|
296
307
|
--quiet Print only tests output
|
297
308
|
-v, --version Show Version
|
298
309
|
-h, --help Show this.
|
310
|
+
<!-- rake readme -->
|
299
311
|
|
300
|
-
You can run any
|
312
|
+
You can run any command in parallel with `-e` / `--exec`
|
301
313
|
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
314
|
+
```bash
|
315
|
+
parallel_test -n 3 -e 'ruby -e "puts %[hello from process #{ENV[:TEST_ENV_NUMBER.to_s].inspect}]"'
|
316
|
+
hello from process "2"
|
317
|
+
hello from process ""
|
318
|
+
hello from process "3"
|
319
|
+
```
|
308
320
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
321
|
+
and pass arguments to a command with `--exec-args`
|
322
|
+
|
323
|
+
```bash
|
324
|
+
parallel_test -n 3 --exec-args echo
|
325
|
+
spec/a_spec.rb spec/b_spec.rb
|
326
|
+
spec/c_spec.rb spec/d_spec.rb
|
327
|
+
spec/e_spec.rb
|
328
|
+
```
|
329
|
+
|
330
|
+
and run multiple commands by using `sh` and `--exec-args`
|
331
|
+
|
332
|
+
```bash
|
333
|
+
parallel_test -n 3 --exec-args "sh -c \"echo 'hello world' && rspec \$@\" --"
|
334
|
+
```
|
314
335
|
|
315
336
|
TIPS
|
316
337
|
====
|
@@ -452,6 +473,7 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
|
|
452
473
|
- [Jay Dorsey](https://github.com/jaydorsey)
|
453
474
|
- [hatsu](https://github.com/hatsu38)
|
454
475
|
- [Mark Huk](https://github.com/vimutter)
|
476
|
+
- [Johannes Vetter](https://github.com/johvet)
|
455
477
|
|
456
478
|
[Michael Grosser](http://grosser.it)<br/>
|
457
479
|
michael@grosser.it<br/>
|
data/lib/parallel_tests/cli.rb
CHANGED
@@ -15,7 +15,7 @@ module ParallelTests
|
|
15
15
|
ENV['DISABLE_SPRING'] ||= '1'
|
16
16
|
|
17
17
|
num_processes = ParallelTests.determine_number_of_processes(options[:count])
|
18
|
-
num_processes = (num_processes * ParallelTests.determine_multiple(options[:
|
18
|
+
num_processes = (num_processes * ParallelTests.determine_multiple(options[:multiply_processes])).round
|
19
19
|
|
20
20
|
options[:first_is_1] ||= first_is_1?
|
21
21
|
|
@@ -191,8 +191,9 @@ module ParallelTests
|
|
191
191
|
end
|
192
192
|
|
193
193
|
def parse_options!(argv)
|
194
|
-
newline_padding =
|
194
|
+
newline_padding = 37 # poor man's way of getting a decent table like layout for -h output on 120 char width terminal
|
195
195
|
options = {}
|
196
|
+
|
196
197
|
OptionParser.new do |opts|
|
197
198
|
opts.banner = <<~BANNER
|
198
199
|
Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
|
@@ -205,12 +206,14 @@ module ParallelTests
|
|
205
206
|
|
206
207
|
Options are:
|
207
208
|
BANNER
|
209
|
+
|
208
210
|
opts.on("-n PROCESSES", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
|
209
211
|
opts.on("-p", "--pattern PATTERN", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
|
210
212
|
opts.on("--exclude-pattern", "--exclude-pattern PATTERN", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
|
213
|
+
|
211
214
|
opts.on(
|
212
215
|
"--group-by TYPE",
|
213
|
-
<<~TEXT
|
216
|
+
heredoc(<<~TEXT, newline_padding)
|
214
217
|
group tests by:
|
215
218
|
found - order of finding files
|
216
219
|
steps - number of cucumber/spinach steps
|
@@ -220,6 +223,7 @@ module ParallelTests
|
|
220
223
|
default - runtime when runtime log is filled otherwise filesize
|
221
224
|
TEXT
|
222
225
|
) { |type| options[:group_by] = type.to_sym }
|
226
|
+
|
223
227
|
opts.on("-m COUNT", "--multiply-processes COUNT", Float, "use given number as a multiplier of processes to run") do |m|
|
224
228
|
options[:multiply_processes] = m
|
225
229
|
end
|
@@ -251,7 +255,7 @@ module ParallelTests
|
|
251
255
|
|
252
256
|
opts.on(
|
253
257
|
"--specify-groups SPECS",
|
254
|
-
<<~TEXT
|
258
|
+
heredoc(<<~TEXT, newline_padding)
|
255
259
|
Use 'specify-groups' if you want to specify multiple specs running in multiple
|
256
260
|
processes in a specific formation. Commas indicate specs in the same process,
|
257
261
|
pipes indicate specs in a new process. If SPECS is a '-' the value for this
|
@@ -267,28 +271,40 @@ module ParallelTests
|
|
267
271
|
opts.on(
|
268
272
|
"--only-group GROUP_INDEX[,GROUP_INDEX]",
|
269
273
|
Array,
|
270
|
-
<<~TEXT
|
274
|
+
heredoc(<<~TEXT, newline_padding)
|
271
275
|
Only run the given group numbers.
|
272
276
|
Changes `--group-by` default to 'filesize'.
|
273
277
|
TEXT
|
274
278
|
) { |groups| options[:only_group] = groups.map(&:to_i) }
|
275
279
|
|
276
|
-
opts.on("-e", "--exec COMMAND", "execute
|
280
|
+
opts.on("-e", "--exec COMMAND", "execute COMMAND in parallel and with ENV['TEST_ENV_NUMBER']") { |arg| options[:execute] = Shellwords.shellsplit(arg) }
|
281
|
+
opts.on(
|
282
|
+
"--exec-args COMMAND",
|
283
|
+
heredoc(<<~TEXT, newline_padding)
|
284
|
+
execute COMMAND in parallel with test files as arguments, for example:
|
285
|
+
$ parallel_tests --exec-args echo
|
286
|
+
> echo spec/a_spec.rb spec/b_spec.rb
|
287
|
+
TEXT
|
288
|
+
) { |arg| options[:execute_args] = Shellwords.shellsplit(arg) }
|
289
|
+
|
277
290
|
opts.on("-o", "--test-options 'OPTIONS'", "execute test commands with those options") { |arg| options[:test_options] = Shellwords.shellsplit(arg) }
|
291
|
+
|
278
292
|
opts.on("-t", "--type TYPE", "test(default) / rspec / cucumber / spinach") do |type|
|
279
293
|
@runner = load_runner(type)
|
280
294
|
rescue NameError, LoadError => e
|
281
295
|
puts "Runner for `#{type}` type has not been found! (#{e})"
|
282
296
|
abort
|
283
297
|
end
|
298
|
+
|
284
299
|
opts.on(
|
285
300
|
"--suffix PATTERN",
|
286
|
-
<<~TEXT
|
301
|
+
heredoc(<<~TEXT, newline_padding)
|
287
302
|
override built in test file pattern (should match suffix):
|
288
303
|
'_spec.rb$' - matches rspec files
|
289
304
|
'_(test|spec).rb$' - matches test or spec files
|
290
305
|
TEXT
|
291
306
|
) { |pattern| options[:suffix] = /#{pattern}/ }
|
307
|
+
|
292
308
|
opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
|
293
309
|
opts.on("--prefix-output-with-test-env-number", "Prefixes test env number to the output when not using --serialize-stdout") { options[:prefix_output_with_test_env_number] = true }
|
294
310
|
opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
|
@@ -302,7 +318,17 @@ module ParallelTests
|
|
302
318
|
opts.on("--unknown-runtime SECONDS", Float, "Use given number as unknown runtime (otherwise use average time)") { |time| options[:unknown_runtime] = time }
|
303
319
|
opts.on("--first-is-1", "Use \"1\" as TEST_ENV_NUMBER to not reuse the default test environment") { options[:first_is_1] = true }
|
304
320
|
opts.on("--fail-fast", "Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported") { options[:fail_fast] = true }
|
305
|
-
|
321
|
+
|
322
|
+
opts.on(
|
323
|
+
"--test-file-limit LIMIT",
|
324
|
+
Integer,
|
325
|
+
heredoc(<<~TEXT, newline_padding)
|
326
|
+
Limit to this number of files per test run by batching
|
327
|
+
(for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number
|
328
|
+
and summarizing partial results)
|
329
|
+
TEXT
|
330
|
+
) { |limit| options[:test_file_limit] = limit }
|
331
|
+
|
306
332
|
opts.on("--verbose", "Print debug output") { options[:verbose] = true }
|
307
333
|
opts.on("--verbose-command", "Combines options --verbose-process-command and --verbose-rerun-command") { options.merge! verbose_process_command: true, verbose_rerun_command: true }
|
308
334
|
opts.on("--verbose-process-command", "Print the command that will be executed by each process before it begins") { options[:verbose_process_command] = true }
|
@@ -452,5 +478,9 @@ module ParallelTests
|
|
452
478
|
yield
|
453
479
|
end
|
454
480
|
end
|
481
|
+
|
482
|
+
def heredoc(text, newline_padding)
|
483
|
+
text.rstrip.gsub("\n", "\n#{' ' * newline_padding}")
|
484
|
+
end
|
455
485
|
end
|
456
486
|
end
|
@@ -18,11 +18,7 @@ module ParallelTests
|
|
18
18
|
options[:env] ||= {}
|
19
19
|
options[:env] = options[:env].merge({ 'AUTOTEST' => '1' }) if $stdout.tty?
|
20
20
|
|
21
|
-
|
22
|
-
cmd += runtime_logging if File.directory?(File.dirname(runtime_log))
|
23
|
-
cmd += combined_scenarios
|
24
|
-
cmd += cucumber_opts(options[:test_options])
|
25
|
-
execute_command(cmd, process_number, num_processes, options)
|
21
|
+
execute_command(build_command(combined_scenarios, options), process_number, num_processes, options)
|
26
22
|
end
|
27
23
|
|
28
24
|
def test_file_name
|
@@ -41,6 +37,15 @@ module ParallelTests
|
|
41
37
|
line =~ /^\d+ (steps?|scenarios?)/
|
42
38
|
end
|
43
39
|
|
40
|
+
def build_test_command(file_list, options)
|
41
|
+
[
|
42
|
+
*executable,
|
43
|
+
*(runtime_logging if File.directory?(File.dirname(runtime_log))),
|
44
|
+
*file_list,
|
45
|
+
*cucumber_opts(options[:test_options])
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
44
49
|
# cucumber has 2 result lines per test run, that cannot be added
|
45
50
|
# 1 scenario (1 failed)
|
46
51
|
# 1 step (1 failed)
|
@@ -6,8 +6,7 @@ module ParallelTests
|
|
6
6
|
class Runner < ParallelTests::Test::Runner
|
7
7
|
class << self
|
8
8
|
def run_tests(test_files, process_number, num_processes, options)
|
9
|
-
|
10
|
-
execute_command(cmd, process_number, num_processes, options)
|
9
|
+
execute_command(build_command(test_files, options), process_number, num_processes, options)
|
11
10
|
end
|
12
11
|
|
13
12
|
def determine_executable
|
@@ -42,6 +41,10 @@ module ParallelTests
|
|
42
41
|
line =~ /\d+ examples?, \d+ failures?/
|
43
42
|
end
|
44
43
|
|
44
|
+
def build_test_command(file_list, options)
|
45
|
+
[*executable, *options[:test_options], *color, *spec_opts, *file_list]
|
46
|
+
end
|
47
|
+
|
45
48
|
# remove old seed and add new seed
|
46
49
|
# --seed 1234
|
47
50
|
# --order rand
|
@@ -28,15 +28,7 @@ module ParallelTests
|
|
28
28
|
|
29
29
|
def run_tests(test_files, process_number, num_processes, options)
|
30
30
|
require_list = test_files.map { |file| file.gsub(" ", "\\ ") }.join(" ")
|
31
|
-
|
32
|
-
*executable,
|
33
|
-
'-Itest',
|
34
|
-
'-e',
|
35
|
-
"%w[#{require_list}].each { |f| require %{./\#{f}} }",
|
36
|
-
'--',
|
37
|
-
*options[:test_options]
|
38
|
-
]
|
39
|
-
execute_command(cmd, process_number, num_processes, options)
|
31
|
+
execute_command(build_command(require_list, options), process_number, num_processes, options)
|
40
32
|
end
|
41
33
|
|
42
34
|
# ignores other commands runner noise
|
@@ -168,6 +160,26 @@ module ParallelTests
|
|
168
160
|
["ruby"]
|
169
161
|
end
|
170
162
|
|
163
|
+
def build_command(file_list, options)
|
164
|
+
if options[:execute_args]
|
165
|
+
options[:execute_args] + file_list
|
166
|
+
else
|
167
|
+
build_test_command(file_list, options)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# load all test files, to be overwritten by other runners
|
172
|
+
def build_test_command(file_list, options)
|
173
|
+
[
|
174
|
+
*executable,
|
175
|
+
'-Itest', # adding ./test directory to the load path for compatibility to common setups
|
176
|
+
'-e',
|
177
|
+
"%w[#{file_list}].each { |f| require %{./\#{f}} }", # using %w to keep things readable
|
178
|
+
'--',
|
179
|
+
*options[:test_options]
|
180
|
+
]
|
181
|
+
end
|
182
|
+
|
171
183
|
def sum_up_results(results)
|
172
184
|
results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
|
173
185
|
counts = results.scan(/(\d+) (\w+)/)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_tests
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel
|
@@ -69,9 +69,9 @@ licenses:
|
|
69
69
|
- MIT
|
70
70
|
metadata:
|
71
71
|
bug_tracker_uri: https://github.com/grosser/parallel_tests/issues
|
72
|
-
changelog_uri: https://github.com/grosser/parallel_tests/blob/v5.
|
73
|
-
documentation_uri: https://github.com/grosser/parallel_tests/blob/v5.
|
74
|
-
source_code_uri: https://github.com/grosser/parallel_tests/tree/v5.
|
72
|
+
changelog_uri: https://github.com/grosser/parallel_tests/blob/v5.3.1/CHANGELOG.md
|
73
|
+
documentation_uri: https://github.com/grosser/parallel_tests/blob/v5.3.1/Readme.md
|
74
|
+
source_code_uri: https://github.com/grosser/parallel_tests/tree/v5.3.1
|
75
75
|
wiki_uri: https://github.com/grosser/parallel_tests/wiki
|
76
76
|
rubygems_mfa_required: 'true'
|
77
77
|
post_install_message:
|