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
|
Running tests in parallel adds overhead in terms of database
|
||||||
setup and fixture loading. Now, Rails will only parallelize test executions when
|
setup and fixture loading. Now, Rails will only parallelize test executions when
|
||||||
there are enough tests to make it worth it.
|
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
|
```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*
|
*Jorge Manrubia*
|
||||||
|
|
|
@ -88,7 +88,7 @@ module ActiveSupport
|
||||||
|
|
||||||
cattr_accessor :test_order # :nodoc:
|
cattr_accessor :test_order # :nodoc:
|
||||||
cattr_accessor :test_parallelization_disabled, default: false # :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!
|
def self.disable_test_parallelization!
|
||||||
self.test_parallelization_disabled = true unless ENV["PARALLEL_WORKERS"]
|
self.test_parallelization_disabled = true unless ENV["PARALLEL_WORKERS"]
|
||||||
|
|
|
@ -72,13 +72,17 @@ module ActiveSupport
|
||||||
#
|
#
|
||||||
# The threaded parallelization uses minitest's parallel executor directly.
|
# The threaded parallelization uses minitest's parallel executor directly.
|
||||||
# The processes parallelization uses a Ruby DRb server.
|
# 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 = Concurrent.physical_processor_count if workers == :number_of_processors
|
||||||
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
|
workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
|
||||||
|
|
||||||
return if workers <= 1 || ActiveSupport.test_parallelization_disabled
|
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
|
end
|
||||||
|
|
||||||
# Set up hook for parallel testing. This can be used if you have multiple
|
# Set up hook for parallel testing. This can be used if you have multiple
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
module ActiveSupport
|
module ActiveSupport
|
||||||
module Testing
|
module Testing
|
||||||
class ParallelizeExecutor # :nodoc:
|
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
|
@size = size
|
||||||
@parallelize_with = with
|
@parallelize_with = with
|
||||||
@parallel_executor = build_parallel_executor
|
@threshold = threshold
|
||||||
end
|
end
|
||||||
|
|
||||||
def start
|
def start
|
||||||
|
@ -27,6 +27,10 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
def parallel_executor
|
||||||
|
@parallel_executor ||= build_parallel_executor
|
||||||
|
end
|
||||||
|
|
||||||
def build_parallel_executor
|
def build_parallel_executor
|
||||||
case parallelize_with
|
case parallelize_with
|
||||||
when :processes
|
when :processes
|
||||||
|
@ -49,7 +53,7 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
def should_parallelize?
|
def should_parallelize?
|
||||||
ENV["PARALLEL_WORKERS"] || tests_count > ActiveSupport.test_parallelization_minimum_number_of_tests
|
ENV["PARALLEL_WORKERS"] || tests_count > threshold
|
||||||
end
|
end
|
||||||
|
|
||||||
def tests_count
|
def tests_count
|
||||||
|
@ -64,7 +68,7 @@ module ActiveSupport
|
||||||
if parallelized?
|
if parallelized?
|
||||||
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
|
"Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}"
|
||||||
else
|
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
|
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
|
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
|
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
|
```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
|
The Test Database
|
||||||
|
|
|
@ -2421,18 +2421,18 @@ module ApplicationTests
|
||||||
assert_equal OpenSSL::Digest::SHA256, ActiveSupport::KeyGenerator.hash_digest_class
|
assert_equal OpenSSL::Digest::SHA256, ActiveSupport::KeyGenerator.hash_digest_class
|
||||||
end
|
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'
|
remove_from_config '.*config\.load_defaults.*\n'
|
||||||
|
|
||||||
app_file "config/environments/test.rb", <<-RUBY
|
app_file "config/environments/test.rb", <<-RUBY
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.active_support.test_parallelization_minimum_number_of_tests = 1234
|
config.active_support.test_parallelization_threshold = 1234
|
||||||
end
|
end
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
app "test"
|
app "test"
|
||||||
|
|
||||||
assert_equal 1234, ActiveSupport.test_parallelization_minimum_number_of_tests
|
assert_equal 1234, ActiveSupport.test_parallelization_threshold
|
||||||
end
|
end
|
||||||
|
|
||||||
test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do
|
test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do
|
||||||
|
|
|
@ -1166,8 +1166,6 @@ module ApplicationTests
|
||||||
require_relative "../config/environment"
|
require_relative "../config/environment"
|
||||||
require "rails/test_help"
|
require "rails/test_help"
|
||||||
|
|
||||||
ActiveSupport.test_parallelization_minimum_number_of_tests = #{threshold}
|
|
||||||
|
|
||||||
class ActiveSupport::TestCase
|
class ActiveSupport::TestCase
|
||||||
<%- if force -%>
|
<%- if force -%>
|
||||||
# Force parallelization, even with single files
|
# Force parallelization, even with single files
|
||||||
|
@ -1175,7 +1173,7 @@ module ApplicationTests
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|
||||||
# Run tests in parallel with specified workers
|
# 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.
|
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
||||||
fixtures :all
|
fixtures :all
|
||||||
|
|
Loading…
Reference in New Issue