Add an option threshold: to .parallel() setup method (#42789)

This adds an additional method to configure the parallelization
threshold. Before this, the only way of configuring the threshold was
via an option:

```
config.active_support.test_parallelization_minimum_number_of_tests
```
This commit is contained in:
Jorge Manrubia 2021-07-16 20:32:23 +02:00 committed by GitHub
parent 52e3dc23b9
commit 675d9ffb6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 19 deletions

View File

@ -1,13 +1,23 @@
* Parallelize tests only when overhead is justified by the number of them
* Faster tests by parallelizing only when overhead is justified by the number
of them.
Running tests in parallel adds overhead in terms of database
setup and fixture loading. Now, Rails will only parallelize test executions when
there are enough tests to make it worth it.
This threshold is 50 by default, and is configurable via:
This threshold is 50 by default, and is configurable via config setting in
your test.rb:
```ruby
config.active_support.test_parallelization_minimum_number_of_tests = 100
config.active_support.test_parallelization_threshold = 100
```
It's also configurable at the test case level:
```ruby
class ActiveSupport::TestCase
parallelize threshold: 100
end
```
*Jorge Manrubia*

View File

@ -88,7 +88,7 @@ module ActiveSupport
cattr_accessor :test_order # :nodoc:
cattr_accessor :test_parallelization_disabled, default: false # :nodoc:
cattr_accessor :test_parallelization_minimum_number_of_tests, default: 50 # :nodoc:
cattr_accessor :test_parallelization_threshold, default: 50 # :nodoc:
def self.disable_test_parallelization!
self.test_parallelization_disabled = true unless ENV["PARALLEL_WORKERS"]

View File

@ -72,13 +72,17 @@ module ActiveSupport
#
# The threaded parallelization uses minitest's parallel executor directly.
# The processes parallelization uses a Ruby DRb server.
def parallelize(workers: :number_of_processors, with: :processes)
#
# Because parallelization presents an overhead, it is only enabled when the
# number of tests to run is above the +threshold+ param. The default value is
# 50, and it's configurable via +config.active_support.test_parallelization_threshold+.
def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold)
workers = Concurrent.physical_processor_count if workers == :number_of_processors
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
return if workers <= 1 || ActiveSupport.test_parallelization_disabled
Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with)
Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold)
end
# Set up hook for parallel testing. This can be used if you have multiple

View File

@ -3,12 +3,12 @@
module ActiveSupport
module Testing
class ParallelizeExecutor # :nodoc:
attr_reader :size, :parallelize_with, :parallel_executor
attr_reader :size, :parallelize_with, :threshold
def initialize(size:, with:)
def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold)
@size = size
@parallelize_with = with
@parallel_executor = build_parallel_executor
@threshold = threshold
end
def start
@ -27,6 +27,10 @@ module ActiveSupport
end
private
def parallel_executor
@parallel_executor ||= build_parallel_executor
end
def build_parallel_executor
case parallelize_with
when :processes
@ -49,7 +53,7 @@ module ActiveSupport
end
def should_parallelize?
ENV["PARALLEL_WORKERS"] || tests_count > ActiveSupport.test_parallelization_minimum_number_of_tests
ENV["PARALLEL_WORKERS"] || tests_count > threshold
end
def tests_count
@ -64,7 +68,7 @@ module ActiveSupport
if parallelized?
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
else
"Running #{tests_count} tests in a single process (parallelization threshold is #{ActiveSupport.test_parallelization_minimum_number_of_tests})"
"Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})"
end
end
end

View File

@ -573,10 +573,20 @@ create as changes are not automatically rolled back after the test completes.
Running tests in parallel adds an overhead in terms of database setup and
fixture loading. Because of this, Rails won't parallelize executions that involve
fewer than 50 tests. You can configure this threshold in your `test.rb`:
fewer than 50 tests.
You can configure this threshold in your `test.rb`:
```ruby
config.active_support.test_parallelization_minimum_number_of_tests = 100
config.active_support.test_parallelization_threshold = 100
```
And also when setting up parallelization at the test case level:
```ruby
class ActiveSupport::TestCase
parallelize threshold: 100
end
```
The Test Database

View File

@ -2421,18 +2421,18 @@ module ApplicationTests
assert_equal OpenSSL::Digest::SHA256, ActiveSupport::KeyGenerator.hash_digest_class
end
test "ActiveSupport.test_parallelization_minimum_number_of_tests can be configured via config.active_support.test_parallelization_minimum_number_of_tests" do
test "ActiveSupport.test_parallelization_threshold can be configured via config.active_support.test_parallelization_threshold" do
remove_from_config '.*config\.load_defaults.*\n'
app_file "config/environments/test.rb", <<-RUBY
Rails.application.configure do
config.active_support.test_parallelization_minimum_number_of_tests = 1234
config.active_support.test_parallelization_threshold = 1234
end
RUBY
app "test"
assert_equal 1234, ActiveSupport.test_parallelization_minimum_number_of_tests
assert_equal 1234, ActiveSupport.test_parallelization_threshold
end
test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do

View File

@ -1166,8 +1166,6 @@ module ApplicationTests
require_relative "../config/environment"
require "rails/test_help"
ActiveSupport.test_parallelization_minimum_number_of_tests = #{threshold}
class ActiveSupport::TestCase
<%- if force -%>
# Force parallelization, even with single files
@ -1175,7 +1173,7 @@ module ApplicationTests
<%- end -%>
# Run tests in parallel with specified workers
parallelize(workers: 2, with: :<%= with %>)
parallelize(workers: 2, with: :<%= with %>, threshold: #{threshold})
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all