parallel_tests 4.7.1 → 4.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b091de564b1cd9f2c57b94dd973bceea01f7722e4c6bafbe71e6b75c7a265421
4
- data.tar.gz: bf14a02a03bef8046e2973a904701f03b10bdae1ef8a84654511c18631efe179
3
+ metadata.gz: 40c390881f78ed6c146e2f11deee7e19fc5df5fa99494779a15743ce6a8463a0
4
+ data.tar.gz: 89cc457abaea5d29160f745ccc6cd57e2ba365f53f64b82248eb3033533da804
5
5
  SHA512:
6
- metadata.gz: d4d7df8aed6d01ba8a9b98064a4c88ad7b88270884d9b5f24c34c2094772974c81fef357c9534e97265e57603b780c9b61af4b1a70a32ae6891ba87256633dfd
7
- data.tar.gz: a0f0e19e7d02d3046f41ebe8c51a72056bd840d25b54947564b5b015df8946f0e4b0c86920b3cabca7ff1a82f29dcbb44e53daeaf92ae3721de29b6388c92fe0
6
+ metadata.gz: d1cc1c8645f580ea2eb43ee650e24a1c314c1af93937a5d11a8591e405bbc429b23fcfc79ed92bc50f9d15ec3a1aa35abe1db2a718927dbab50b1077a4fa91c6
7
+ data.tar.gz: b50b820699c76f128d1bce2495d5f2363cac1a53e978713c6e3a51b5e298f841292153a898514ded1153d7c99c230e67c95f3f23c6a4416a78dc26991c875b11
data/Readme.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # parallel_tests
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/parallel_tests.svg)](https://rubygems.org/gems/parallel_tests)
4
- [![Build status](https://github.com/grosser/parallel_tests/workflows/test/badge.svg)](https://github.com/grosser/parallel_tests/actions?query=workflow%3Atest)
4
+ [![Build status](https://github.com/grosser/parallel_tests/workflows/test/badge.svg)](https://github.com/grosser/parallel_tests/actions?query=workflow%3Atest&branch=master)
5
5
 
6
6
  Speedup Minitest + RSpec + Turnip + Cucumber + Spinach by running parallel on multiple CPU cores.<br/>
7
7
  ParallelTests splits tests into balanced groups (by number of lines or runtime) and runs each group in a process with its own database.
@@ -93,7 +93,7 @@ rake "parallel:rake[my:custom:task,2]"
93
93
  ```
94
94
 
95
95
 
96
- Running things once
96
+ Running setup or teardown once
97
97
  ===================
98
98
 
99
99
  ```Ruby
@@ -121,8 +121,11 @@ Even test group runtimes
121
121
 
122
122
  Test groups will often run for different times, making the full test run as slow as the slowest group.
123
123
 
124
- Step 1: Use these loggers (see below) to record test runtime
125
- Step 2: Your next run will use the recorded test runtimes (use `--runtime-log <file>` if you picked a location different from below)
124
+ **Step 1**: Use these loggers (see below) to record test runtime
125
+
126
+ **Step 2**: The next test run will use the recorded test runtimes (use `--runtime-log <file>` if you picked a location different from below)
127
+
128
+ **Step 3**: Automate upload/download of test runtime from your CI system [example](https://github.com/grosser/parallel_rails_example/blob/master/.github/workflows/test.yml) (chunks need to be combined, an alternative is [amend](https://github.com/grosser/amend))
126
129
 
127
130
  ### RSpec
128
131
 
@@ -143,8 +146,6 @@ require 'parallel_tests/test/runtime_logger' if ENV['RECORD_RUNTIME']
143
146
  results will be logged to `tmp/parallel_runtime_test.log` when `RECORD_RUNTIME` is set,
144
147
  so it is not always required or overwritten.
145
148
 
146
- ### TODO: add instructions for other frameworks
147
-
148
149
  Loggers
149
150
  =======
150
151
 
@@ -237,23 +238,23 @@ Setup for non-rails
237
238
 
238
239
  Options are:
239
240
  <!-- copy output from bundle exec ./bin/parallel_test -h -->
240
- -n [PROCESSES] How many processes to use, default: available CPUs
241
- -p, --pattern [PATTERN] run tests matching this regex pattern
242
- --exclude-pattern [PATTERN] exclude tests matching this regex pattern
243
- --group-by [TYPE] group tests by:
241
+ -n PROCESSES How many processes to use, default: available CPUs
242
+ -p, --pattern PATTERN run tests matching this regex pattern
243
+ --exclude-pattern PATTERN exclude tests matching this regex pattern
244
+ --group-by TYPE group tests by:
244
245
  found - order of finding files
245
246
  steps - number of cucumber/spinach steps
246
247
  scenarios - individual cucumber scenarios
247
248
  filesize - by size of the file
248
249
  runtime - info from runtime log
249
250
  default - runtime when runtime log is filled otherwise filesize
250
- -m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
251
- -s, --single [PATTERN] Run all matching files in the same process
251
+ -m, --multiply-processes COUNT use given number as a multiplier of processes to run
252
+ -s, --single PATTERN Run all matching files in the same process
252
253
  -i, --isolate Do not run any other tests in the group used by --single(-s)
253
- --isolate-n [PROCESSES] Use 'isolate' singles with number of processes, default: 1
254
+ --isolate-n PROCESSES Use 'isolate' singles with number of processes, default: 1
254
255
  --highest-exit-status Exit with the highest exit status provided by test run(s)
255
- --failure-exit-code [INT] Specify the exit code to use when tests fail
256
- --specify-groups [SPECS] Use 'specify-groups' if you want to specify multiple specs running in multiple
256
+ --failure-exit-code INT Specify the exit code to use when tests fail
257
+ --specify-groups SPECS Use 'specify-groups' if you want to specify multiple specs running in multiple
257
258
  processes in a specific formation. Commas indicate specs in the same process,
258
259
  pipes indicate specs in a new process. Cannot use with --single, --isolate, or
259
260
  --isolate-n. Ex.
@@ -261,12 +262,13 @@ Options are:
261
262
  Process 1 will contain 1_spec.rb and 2_spec.rb
262
263
  Process 2 will contain 3_spec.rb
263
264
  Process 3 will contain all other specs
264
- --only-group INT[,INT] Only run the given group numbers.
265
+ --only-group GROUP_INDEX[,GROUP_INDEX]
266
+ Only run the given group numbers.
265
267
  Changes `--group-by` default to 'filesize'.
266
- -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUMBER']
267
- -o, --test-options '[OPTIONS]' execute test commands with those options
268
- -t, --type [TYPE] test(default) / rspec / cucumber / spinach
269
- --suffix [PATTERN] override built in test file pattern (should match suffix):
268
+ -e, --exec COMMAND execute this code parallel and with ENV['TEST_ENV_NUMBER']
269
+ -o, --test-options 'OPTIONS' execute test commands with those options
270
+ -t, --type TYPE test(default) / rspec / cucumber / spinach
271
+ --suffix PATTERN override built in test file pattern (should match suffix):
270
272
  '_spec.rb$' - matches rspec files
271
273
  '_(test|spec).rb$' - matches test or spec files
272
274
  --serialize-stdout Serialize stdout output, nothing will be written until everything is done
@@ -275,14 +277,15 @@ Options are:
275
277
  --combine-stderr Combine stderr into stdout, useful in conjunction with --serialize-stdout
276
278
  --non-parallel execute same commands but do not in parallel, needs --exec
277
279
  --no-symlinks Do not traverse symbolic links to find test files
278
- --ignore-tags [PATTERN] When counting steps ignore scenarios with tags that match this pattern
280
+ --ignore-tags PATTERN When counting steps ignore scenarios with tags that match this pattern
279
281
  --nice execute test commands with low priority.
280
- --runtime-log [PATH] Location of previously recorded test runtimes
281
- --allowed-missing [INT] Allowed percentage of missing runtimes (default = 50)
282
+ --runtime-log PATH Location of previously recorded test runtimes
283
+ --allowed-missing COUNT Allowed percentage of missing runtimes (default = 50)
282
284
  --allow-duplicates When detecting files to run, allow duplicates
283
- --unknown-runtime [FLOAT] Use given number as unknown runtime (otherwise use average time)
285
+ --unknown-runtime SECONDS Use given number as unknown runtime (otherwise use average time)
284
286
  --first-is-1 Use "1" as TEST_ENV_NUMBER to not reuse the default test environment
285
287
  --fail-fast Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported
288
+ --test-file-limit LIMIT Limit to this number of files per test run by batching (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number and summarizing partial results)
286
289
  --verbose Print debug output
287
290
  --verbose-command Combines options --verbose-process-command and --verbose-rerun-command
288
291
  --verbose-process-command Print the command that will be executed by each process before it begins
@@ -109,8 +109,19 @@ module ParallelTests
109
109
  end
110
110
 
111
111
  def run_tests(group, process_number, num_processes, options)
112
- if group.empty?
113
- { stdout: '', exit_status: 0, command: nil, seed: nil }
112
+ if (limit = options[:test_file_limit])
113
+ # TODO: will have some bugs with summarizing results and last process
114
+ results = group.each_slice(limit).map do |slice|
115
+ @runner.run_tests(slice, process_number, num_processes, options)
116
+ end
117
+ result = results[0]
118
+ results[1..].each do |res|
119
+ result[:stdout] = result[:stdout].to_s + res[:stdout].to_s
120
+ result[:exit_status] = [res[:exit_status], result[:exit_status]].max
121
+ # adding all files back in, not using original cmd to show what was actually run
122
+ result[:command] |= res[:command]
123
+ end
124
+ result
114
125
  else
115
126
  @runner.run_tests(group, process_number, num_processes, options)
116
127
  end
@@ -194,11 +205,11 @@ module ParallelTests
194
205
 
195
206
  Options are:
196
207
  BANNER
197
- opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
198
- opts.on("-p", "--pattern [PATTERN]", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
199
- opts.on("--exclude-pattern", "--exclude-pattern [PATTERN]", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
208
+ opts.on("-n PROCESSES", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
209
+ opts.on("-p", "--pattern PATTERN", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
210
+ opts.on("--exclude-pattern", "--exclude-pattern PATTERN", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
200
211
  opts.on(
201
- "--group-by [TYPE]",
212
+ "--group-by TYPE",
202
213
  <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
203
214
  group tests by:
204
215
  found - order of finding files
@@ -209,11 +220,11 @@ module ParallelTests
209
220
  default - runtime when runtime log is filled otherwise filesize
210
221
  TEXT
211
222
  ) { |type| options[:group_by] = type.to_sym }
212
- opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") do |multiply|
223
+ opts.on("-m COUNT", "--multiply-processes COUNT", Float, "use given number as a multiplier of processes to run") do |multiply|
213
224
  options[:multiply] = multiply
214
225
  end
215
226
 
216
- opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in the same process") do |pattern|
227
+ opts.on("-s PATTERN", "--single PATTERN", "Run all matching files in the same process") do |pattern|
217
228
  (options[:single_process] ||= []) << /#{pattern}/
218
229
  end
219
230
 
@@ -222,7 +233,7 @@ module ParallelTests
222
233
  end
223
234
 
224
235
  opts.on(
225
- "--isolate-n [PROCESSES]",
236
+ "--isolate-n PROCESSES",
226
237
  Integer,
227
238
  "Use 'isolate' singles with number of processes, default: 1"
228
239
  ) { |n| options[:isolate_count] = n }
@@ -233,13 +244,13 @@ module ParallelTests
233
244
  ) { options[:highest_exit_status] = true }
234
245
 
235
246
  opts.on(
236
- "--failure-exit-code [INT]",
247
+ "--failure-exit-code INT",
237
248
  Integer,
238
249
  "Specify the exit code to use when tests fail"
239
250
  ) { |code| options[:failure_exit_code] = code }
240
251
 
241
252
  opts.on(
242
- "--specify-groups [SPECS]",
253
+ "--specify-groups SPECS",
243
254
  <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
244
255
  Use 'specify-groups' if you want to specify multiple specs running in multiple
245
256
  processes in a specific formation. Commas indicate specs in the same process,
@@ -253,7 +264,7 @@ module ParallelTests
253
264
  ) { |groups| options[:specify_groups] = groups }
254
265
 
255
266
  opts.on(
256
- "--only-group INT[,INT]",
267
+ "--only-group GROUP_INDEX[,GROUP_INDEX]",
257
268
  Array,
258
269
  <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
259
270
  Only run the given group numbers.
@@ -261,16 +272,16 @@ module ParallelTests
261
272
  TEXT
262
273
  ) { |groups| options[:only_group] = groups.map(&:to_i) }
263
274
 
264
- opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |arg| options[:execute] = Shellwords.shellsplit(arg) }
265
- opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = Shellwords.shellsplit(arg) }
266
- opts.on("-t", "--type [TYPE]", "test(default) / rspec / cucumber / spinach") do |type|
275
+ opts.on("-e", "--exec COMMAND", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |arg| options[:execute] = Shellwords.shellsplit(arg) }
276
+ opts.on("-o", "--test-options 'OPTIONS'", "execute test commands with those options") { |arg| options[:test_options] = Shellwords.shellsplit(arg) }
277
+ opts.on("-t", "--type TYPE", "test(default) / rspec / cucumber / spinach") do |type|
267
278
  @runner = load_runner(type)
268
279
  rescue NameError, LoadError => e
269
280
  puts "Runner for `#{type}` type has not been found! (#{e})"
270
281
  abort
271
282
  end
272
283
  opts.on(
273
- "--suffix [PATTERN]",
284
+ "--suffix PATTERN",
274
285
  <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
275
286
  override built in test file pattern (should match suffix):
276
287
  '_spec.rb$' - matches rspec files
@@ -282,14 +293,15 @@ module ParallelTests
282
293
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
283
294
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
284
295
  opts.on("--no-symlinks", "Do not traverse symbolic links to find test files") { options[:symlinks] = false }
285
- opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
296
+ opts.on('--ignore-tags PATTERN', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
286
297
  opts.on("--nice", "execute test commands with low priority.") { options[:nice] = true }
287
- opts.on("--runtime-log [PATH]", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
288
- opts.on("--allowed-missing [INT]", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
298
+ opts.on("--runtime-log PATH", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
299
+ opts.on("--allowed-missing COUNT", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
289
300
  opts.on('--allow-duplicates', 'When detecting files to run, allow duplicates') { options[:allow_duplicates] = true }
290
- opts.on("--unknown-runtime [FLOAT]", Float, "Use given number as unknown runtime (otherwise use average time)") { |time| options[:unknown_runtime] = time }
301
+ opts.on("--unknown-runtime SECONDS", Float, "Use given number as unknown runtime (otherwise use average time)") { |time| options[:unknown_runtime] = time }
291
302
  opts.on("--first-is-1", "Use \"1\" as TEST_ENV_NUMBER to not reuse the default test environment") { options[:first_is_1] = true }
292
303
  opts.on("--fail-fast", "Stop all groups when one group fails (best used with --test-options '--fail-fast' if supported") { options[:fail_fast] = true }
304
+ opts.on("--test-file-limit LIMIT", Integer, "Limit to this number of files per test run by batching (for windows set to ~100 to stay below 8192 max command limit, might have bugs from reusing test-env-number and summarizing partial results)") { |limit| options[:test_file_limit] = limit }
293
305
  opts.on("--verbose", "Print debug output") { options[:verbose] = true }
294
306
  opts.on("--verbose-command", "Combines options --verbose-process-command and --verbose-rerun-command") { options.merge! verbose_process_command: true, verbose_rerun_command: true }
295
307
  opts.on("--verbose-process-command", "Print the command that will be executed by each process before it begins") { options[:verbose_process_command] = true }
@@ -4,8 +4,8 @@ require "parallel_tests/gherkin/runner"
4
4
  module ParallelTests
5
5
  module Cucumber
6
6
  class Runner < ParallelTests::Gherkin::Runner
7
- SCENARIOS_RESULTS_BOUNDARY_REGEX = /^(Failing|Flaky) Scenarios:$/.freeze
8
- SCENARIO_REGEX = %r{^cucumber features/.+:\d+}.freeze
7
+ SCENARIOS_RESULTS_BOUNDARY_REGEX = /^(Failing|Flaky) Scenarios:$/
8
+ SCENARIO_REGEX = %r{^cucumber features/.+:\d+}
9
9
 
10
10
  class << self
11
11
  def name
@@ -25,6 +25,8 @@ class ParallelTests::RSpec::RuntimeLogger < ParallelTests::RSpec::LoggerBase
25
25
  super if defined?(super)
26
26
  end
27
27
 
28
+ def seed(*); end
29
+
28
30
  def dump_summary(*); end
29
31
 
30
32
  def dump_failures(*); end
@@ -158,7 +158,7 @@ module ParallelTests
158
158
 
159
159
  def executable
160
160
  if (executable = ENV['PARALLEL_TESTS_EXECUTABLE'])
161
- [executable]
161
+ Shellwords.shellsplit(executable)
162
162
  else
163
163
  determine_executable
164
164
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module ParallelTests
3
- VERSION = '4.7.1'
3
+ VERSION = '4.8.0'
4
4
  end
@@ -44,7 +44,7 @@ module ParallelTests
44
44
 
45
45
  def stop_all_processes
46
46
  pids.all.each { |pid| Process.kill(:INT, pid) }
47
- rescue Errno::ESRCH
47
+ rescue Errno::ESRCH, Errno::EPERM
48
48
  # Process already terminated, do nothing
49
49
  end
50
50
 
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: 4.7.1
4
+ version: 4.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-25 00:00:00.000000000 Z
11
+ date: 2025-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
@@ -69,9 +69,11 @@ licenses:
69
69
  - MIT
70
70
  metadata:
71
71
  bug_tracker_uri: https://github.com/grosser/parallel_tests/issues
72
- documentation_uri: https://github.com/grosser/parallel_tests/blob/v4.7.1/Readme.md
73
- source_code_uri: https://github.com/grosser/parallel_tests/tree/v4.7.1
72
+ changelog_uri: https://github.com/grosser/parallel_tests/blob/v4.8.0/CHANGELOG.md
73
+ documentation_uri: https://github.com/grosser/parallel_tests/blob/v4.8.0/Readme.md
74
+ source_code_uri: https://github.com/grosser/parallel_tests/tree/v4.8.0
74
75
  wiki_uri: https://github.com/grosser/parallel_tests/wiki
76
+ rubygems_mfa_required: 'true'
75
77
  post_install_message:
76
78
  rdoc_options: []
77
79
  require_paths:
@@ -80,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
82
  requirements:
81
83
  - - ">="
82
84
  - !ruby/object:Gem::Version
83
- version: 2.7.0
85
+ version: 3.0.0
84
86
  required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  requirements:
86
88
  - - ">="