Skip to content

Commit 0367cbf

Browse files
authored
Merge pull request rails#54984 from rails/add-ability-to-opt-out-of-parallel-database-hooks
Implement ability to opt out of parallel database hooks
2 parents 0b627b7 + 1f98fd2 commit 0367cbf

File tree

6 files changed

+82
-3
lines changed

6 files changed

+82
-3
lines changed

activerecord/lib/active_record/test_databases.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
module ActiveRecord
66
module TestDatabases # :nodoc:
77
ActiveSupport::Testing::Parallelization.before_fork_hook do
8-
ActiveRecord::Base.connection_handler.clear_all_connections!
8+
if ActiveSupport.parallelize_test_databases
9+
ActiveRecord::Base.connection_handler.clear_all_connections!
10+
end
911
end
1012

1113
ActiveSupport::Testing::Parallelization.after_fork_hook do |i|
12-
create_and_load_schema(i, env_name: ActiveRecord::ConnectionHandling::DEFAULT_ENV.call)
14+
if ActiveSupport.parallelize_test_databases
15+
create_and_load_schema(i, env_name: ActiveRecord::ConnectionHandling::DEFAULT_ENV.call)
16+
end
1317
end
1418

1519
def self.create_and_load_schema(i, env_name:)

activerecord/test/cases/test_databases_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,32 @@ def test_create_databases_after_fork
5353
ENV["RAILS_ENV"] = previous_env
5454
end
5555

56+
def test_create_databases_skipped_if_parallelize_test_databases_is_false
57+
parallelize_databases = ActiveSupport.parallelize_test_databases
58+
ActiveSupport.parallelize_test_databases = false
59+
60+
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "arunit"
61+
prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, {
62+
"arunit" => {
63+
"primary" => { "adapter" => "sqlite3", "database" => "test/db/primary.sqlite3" }
64+
}
65+
}
66+
67+
idx = 42
68+
base_db_config = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary")
69+
expected_database = "#{base_db_config.database}"
70+
71+
ActiveSupport::Testing::Parallelization.after_fork_hooks.each { |cb| cb.call(idx) }
72+
73+
# In this case, there should be no updates
74+
assert_equal expected_database, ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").database
75+
ensure
76+
ActiveSupport.parallelize_test_databases = parallelize_databases
77+
ActiveRecord::Base.configurations = prev_configs
78+
ActiveRecord::Base.establish_connection(:arunit)
79+
ENV["RAILS_ENV"] = previous_env
80+
end
81+
5682
def test_order_of_configurations_isnt_changed_by_test_databases
5783
previous_env, ENV["RAILS_ENV"] = ENV["RAILS_ENV"], "arunit"
5884
prev_configs, ActiveRecord::Base.configurations = ActiveRecord::Base.configurations, {

activesupport/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
* Implement ability to skip creating parallel testing databases.
2+
3+
With parallel testing, Rails will create a database per process. If this isn't
4+
desirable or you would like to implement databases handling on your own, you can
5+
now turn off this default behavior.
6+
7+
To skip creating a database per process, you can change it via the
8+
`parallelize` method:
9+
10+
```ruby
11+
parallelize(workers: 10, parallelize_databases: false)
12+
```
13+
14+
or via the application configuration:
15+
16+
```ruby
17+
config.active_support.parallelize_databases = false
18+
```
19+
20+
*Eileen M. Uchitelle*
21+
122
* Allow to configure maximum cache key sizes
223

324
When the key exceeds the configured limit (250 bytes by default), it will be truncated and

activesupport/lib/active_support.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def self.eager_load!
104104

105105
cattr_accessor :test_order # :nodoc:
106106
cattr_accessor :test_parallelization_threshold, default: 50 # :nodoc:
107+
cattr_accessor :parallelize_test_databases, default: true # :nodoc:
107108

108109
@error_reporter = ActiveSupport::ErrorReporter.new
109110
singleton_class.attr_accessor :error_reporter # :nodoc:

activesupport/lib/active_support/test_case.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,27 @@ def test_order
7979
# Because parallelization presents an overhead, it is only enabled when the
8080
# number of tests to run is above the +threshold+ param. The default value is
8181
# 50, and it's configurable via +config.active_support.test_parallelization_threshold+.
82-
def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold)
82+
#
83+
# If you want to skip Rails default creation of one database per process in favor of
84+
# writing your own implementation, you can set +parallelize_databases+, or configure it
85+
# via +config.active_support.parallelize_test_databases+.
86+
#
87+
# parallelize(workers: :number_of_processes, parallelize_databases: false)
88+
#
89+
# Note that your test suite may deadlock if you attempt to use only one database
90+
# with multiple processes.
91+
def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold, parallelize_databases: ActiveSupport.parallelize_test_databases)
8392
case
8493
when ENV["PARALLEL_WORKERS"]
8594
workers = ENV["PARALLEL_WORKERS"].to_i
8695
when workers == :number_of_processors
8796
workers = (Concurrent.available_processor_count || Concurrent.processor_count).floor
8897
end
8998

99+
if with == :processes
100+
ActiveSupport.parallelize_test_databases = parallelize_databases
101+
end
102+
90103
Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold)
91104
end
92105

railties/test/application/configuration_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,6 +3204,20 @@ class Post < ActiveRecord::Base
32043204
assert_equal 1234, ActiveSupport.test_parallelization_threshold
32053205
end
32063206

3207+
test "ActiveSupport.parallelize_test_databases can be configured via config.active_support.parallelize_test_databases" do
3208+
remove_from_config '.*config\.load_defaults.*\n'
3209+
3210+
app_file "config/environments/test.rb", <<-RUBY
3211+
Rails.application.configure do
3212+
config.active_support.parallelize_test_databases = false
3213+
end
3214+
RUBY
3215+
3216+
app "test"
3217+
3218+
assert_not ActiveSupport.parallelize_test_databases
3219+
end
3220+
32073221
test "custom serializers should be able to set via config.active_job.custom_serializers in an initializer" do
32083222
class ::DummySerializer < ActiveJob::Serializers::ObjectSerializer; end
32093223

0 commit comments

Comments
 (0)