mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #41684 from ricardotk002/disable-parallel-testing
Disable parallel testing when running individual files
This commit is contained in:
commit
ad9e52066c
5 changed files with 112 additions and 6 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
* Tests parallelization is now disabled when running individual files to prevent the setup overhead.
|
||||||
|
|
||||||
|
It can still be enforced if the environment variable `PARALLEL_WORKERS` is present and set to a value greater than 1.
|
||||||
|
|
||||||
|
*Ricardo Díaz*
|
||||||
|
|
||||||
* Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`.
|
* Fix proxying keyword arguments in `ActiveSupport::CurrentAttributes`.
|
||||||
|
|
||||||
*Marcin Kołodziej*
|
*Marcin Kołodziej*
|
||||||
|
|
|
@ -87,6 +87,11 @@ module ActiveSupport
|
||||||
end
|
end
|
||||||
|
|
||||||
cattr_accessor :test_order # :nodoc:
|
cattr_accessor :test_order # :nodoc:
|
||||||
|
cattr_accessor :test_parallelization_disabled, default: false # :nodoc:
|
||||||
|
|
||||||
|
def self.disable_test_parallelization!
|
||||||
|
self.test_parallelization_disabled = true unless ENV["PARALLEL_WORKERS"]
|
||||||
|
end
|
||||||
|
|
||||||
def self.to_time_preserves_timezone
|
def self.to_time_preserves_timezone
|
||||||
DateAndTime::Compatibility.preserve_timezone
|
DateAndTime::Compatibility.preserve_timezone
|
||||||
|
|
|
@ -75,7 +75,7 @@ module ActiveSupport
|
||||||
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
|
return if workers <= 1 || ActiveSupport.test_parallelization_disabled
|
||||||
|
|
||||||
executor = case with
|
executor = case with
|
||||||
when :processes
|
when :processes
|
||||||
|
@ -91,6 +91,12 @@ module ActiveSupport
|
||||||
Minitest.parallel_executor = executor
|
Minitest.parallel_executor = executor
|
||||||
|
|
||||||
parallelize_me!
|
parallelize_me!
|
||||||
|
|
||||||
|
# `Minitest::Test.parallelize_me!` will try to change `test_order` to return
|
||||||
|
# `:parallel`. However, since `ActiveSupport::TestCase` is already overriding it,
|
||||||
|
# in some inheritance situations, it will have precedence over the `Minitest` one.
|
||||||
|
# For this reason, it needs to be updated by hand.
|
||||||
|
self.test_order = :parallel
|
||||||
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,6 +3,7 @@
|
||||||
require "shellwords"
|
require "shellwords"
|
||||||
require "method_source"
|
require "method_source"
|
||||||
require "rake/file_list"
|
require "rake/file_list"
|
||||||
|
require "active_support"
|
||||||
require "active_support/core_ext/module/attribute_accessors"
|
require "active_support/core_ext/module/attribute_accessors"
|
||||||
|
|
||||||
module Rails
|
module Rails
|
||||||
|
@ -46,7 +47,8 @@ module Rails
|
||||||
|
|
||||||
tests = Rake::FileList[patterns.any? ? patterns : default_test_glob]
|
tests = Rake::FileList[patterns.any? ? patterns : default_test_glob]
|
||||||
tests.exclude(default_test_exclude_glob) if patterns.empty?
|
tests.exclude(default_test_exclude_glob) if patterns.empty?
|
||||||
|
# Disable parallel testing if there's only one test file to run.
|
||||||
|
ActiveSupport.disable_test_parallelization! if tests.size <= 1
|
||||||
tests.to_a.each { |path| require File.expand_path(path) }
|
tests.to_a.each { |path| require File.expand_path(path) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -539,6 +539,76 @@ module ApplicationTests
|
||||||
assert_no_match "create_table(:users)", output
|
assert_no_match "create_table(:users)", output
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_parallel_is_disabled_when_single_file_is_run
|
||||||
|
exercise_parallelization_regardless_of_machine_core_count(with: :processes, force: false)
|
||||||
|
|
||||||
|
file_name = app_file "test/unit/parallel_test.rb", <<-RUBY
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ParallelTest < ActiveSupport::TestCase
|
||||||
|
def test_verify_test_order
|
||||||
|
puts "Test order: \#{self.class.test_order}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
output = run_test_command(file_name)
|
||||||
|
|
||||||
|
assert_match "Test order: random", output
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parallel_is_enabled_when_multiple_files_are_run
|
||||||
|
exercise_parallelization_regardless_of_machine_core_count(with: :processes, force: false)
|
||||||
|
|
||||||
|
file_1 = app_file "test/unit/parallel_test_first.rb", <<-RUBY
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ParallelTestFirst < ActiveSupport::TestCase
|
||||||
|
def test_verify_test_order
|
||||||
|
puts "Test order (file 1): \#{self.class.test_order}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
file_2 = app_file "test/unit/parallel_test_second.rb", <<-RUBY
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ParallelTestSecond < ActiveSupport::TestCase
|
||||||
|
def test_verify_test_order
|
||||||
|
puts "Test order (file 2): \#{self.class.test_order}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
output = run_test_command([file_1, file_2].join(" "))
|
||||||
|
|
||||||
|
assert_match "Test order (file 1): parallel", output
|
||||||
|
assert_match "Test order (file 2): parallel", output
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_parallel_is_enabled_when_PARALLEL_WORKERS_is_set
|
||||||
|
@old = ENV["PARALLEL_WORKERS"]
|
||||||
|
ENV["PARALLEL_WORKERS"] = "5"
|
||||||
|
|
||||||
|
exercise_parallelization_regardless_of_machine_core_count(with: :processes, force: false)
|
||||||
|
|
||||||
|
file_name = app_file "test/unit/parallel_test.rb", <<-RUBY
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class ParallelTest < ActiveSupport::TestCase
|
||||||
|
def test_verify_test_order
|
||||||
|
puts "Test order: \#{self.class.test_order}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
output = run_test_command(file_name)
|
||||||
|
|
||||||
|
assert_match "Test order: parallel", output
|
||||||
|
ensure
|
||||||
|
ENV["PARALLEL_WORKERS"] = @old
|
||||||
|
end
|
||||||
|
|
||||||
def test_run_in_parallel_with_process_worker_crash
|
def test_run_in_parallel_with_process_worker_crash
|
||||||
exercise_parallelization_regardless_of_machine_core_count(with: :processes)
|
exercise_parallelization_regardless_of_machine_core_count(with: :processes)
|
||||||
|
|
||||||
|
@ -1039,11 +1109,28 @@ module ApplicationTests
|
||||||
RUBY
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
def exercise_parallelization_regardless_of_machine_core_count(with:)
|
def exercise_parallelization_regardless_of_machine_core_count(with:, force: true)
|
||||||
|
file_content = ERB.new(<<-ERB, trim_mode: "-").result_with_hash(with: with.to_s, force: force)
|
||||||
|
ENV["RAILS_ENV"] ||= "test"
|
||||||
|
require_relative "../config/environment"
|
||||||
|
require "rails/test_help"
|
||||||
|
|
||||||
|
class ActiveSupport::TestCase
|
||||||
|
<%- if force -%>
|
||||||
|
# Force parallelization, even with single files
|
||||||
|
ActiveSupport.test_parallelization_disabled = false
|
||||||
|
<%- end -%>
|
||||||
|
|
||||||
|
# Run tests in parallel with specified workers
|
||||||
|
parallelize(workers: 2, with: :<%= with %>)
|
||||||
|
|
||||||
|
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
||||||
|
fixtures :all
|
||||||
|
end
|
||||||
|
ERB
|
||||||
|
|
||||||
app_path("test/test_helper.rb") do |file_name|
|
app_path("test/test_helper.rb") do |file_name|
|
||||||
file = File.read(file_name)
|
File.write(file_name, file_content)
|
||||||
file.sub!(/parallelize\(([^)]*)\)/, "parallelize(workers: 2, with: :#{with})")
|
|
||||||
File.write(file_name, file)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue