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:
parent
52e3dc23b9
commit
675d9ffb6e
@ -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*
|
||||
|
@ -88,7 +88,7 @@ def self.eager_load!
|
||||
|
||||
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"]
|
||||
|
@ -72,13 +72,17 @@ def test_order
|
||||
#
|
||||
# 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
|
||||
|
@ -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 @@ def shutdown
|
||||
end
|
||||
|
||||
private
|
||||
def parallel_executor
|
||||
@parallel_executor ||= build_parallel_executor
|
||||
end
|
||||
|
||||
def build_parallel_executor
|
||||
case parallelize_with
|
||||
when :processes
|
||||
@ -49,7 +53,7 @@ def parallelized?
|
||||
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 @@ def execution_info
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -2421,18 +2421,18 @@ class D < C
|
||||
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
|
||||
|
@ -1166,8 +1166,6 @@ def exercise_parallelization_regardless_of_machine_core_count(with:, force: true
|
||||
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 @@ class ActiveSupport::TestCase
|
||||
<%- 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
|
||||
|
Loading…
Reference in New Issue
Block a user