Make various minor fixes to the Active Record test suite
Extracted from: https://github.com/rails/rails/pull/50999 - Make fixtures setup and teardown methods private. - Don't run adapter thread safety tests with sqlite3_mem - Make foreign_key_tests more resilient to leaked state - Use `exit!` in fork to avoid `at_exit` side effects. - Disable transactional fixtures in tests that do a lot of low level assertions on connections or connection pools.
This commit is contained in:
parent
bfcfede66a
commit
29fe34486d
@ -110,64 +110,64 @@ def uses_transaction?(method)
|
||||
end
|
||||
end
|
||||
|
||||
def fixture_path # :nodoc:
|
||||
ActiveRecord.deprecator.warn(<<~WARNING)
|
||||
TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2. Use #fixture_paths instead.
|
||||
If multiple fixture paths have been configured with #fixture_paths, then #fixture_path will just return
|
||||
the first path.
|
||||
WARNING
|
||||
fixture_paths.first
|
||||
end
|
||||
|
||||
def run_in_transaction?
|
||||
use_transactional_tests &&
|
||||
!self.class.uses_transaction?(name)
|
||||
end
|
||||
|
||||
def setup_fixtures(config = ActiveRecord::Base)
|
||||
if pre_loaded_fixtures && !use_transactional_tests
|
||||
raise RuntimeError, "pre_loaded_fixtures requires use_transactional_tests"
|
||||
private
|
||||
def fixture_path
|
||||
ActiveRecord.deprecator.warn(<<~WARNING)
|
||||
TestFixtures#fixture_path is deprecated and will be removed in Rails 7.2. Use #fixture_paths instead.
|
||||
If multiple fixture paths have been configured with #fixture_paths, then #fixture_path will just return
|
||||
the first path.
|
||||
WARNING
|
||||
fixture_paths.first
|
||||
end
|
||||
|
||||
@fixture_cache = {}
|
||||
@fixture_connections = {}
|
||||
@fixture_cache_key = [self.class.fixture_table_names.dup, self.class.fixture_paths.dup, self.class.fixture_class_names.dup]
|
||||
@@already_loaded_fixtures ||= {}
|
||||
@connection_subscriber = nil
|
||||
@saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
|
||||
def run_in_transaction?
|
||||
use_transactional_tests &&
|
||||
!self.class.uses_transaction?(name)
|
||||
end
|
||||
|
||||
if run_in_transaction?
|
||||
# Load fixtures once and begin transaction.
|
||||
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key]
|
||||
unless @loaded_fixtures
|
||||
@@already_loaded_fixtures.clear
|
||||
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key] = load_fixtures(config)
|
||||
def setup_fixtures(config = ActiveRecord::Base)
|
||||
if pre_loaded_fixtures && !use_transactional_tests
|
||||
raise RuntimeError, "pre_loaded_fixtures requires use_transactional_tests"
|
||||
end
|
||||
|
||||
setup_transactional_fixtures
|
||||
else
|
||||
# Load fixtures for every test.
|
||||
ActiveRecord::FixtureSet.reset_cache
|
||||
invalidate_already_loaded_fixtures
|
||||
@loaded_fixtures = load_fixtures(config)
|
||||
@fixture_cache = {}
|
||||
@fixture_connections = {}
|
||||
@fixture_cache_key = [self.class.fixture_table_names.dup, self.class.fixture_paths.dup, self.class.fixture_class_names.dup]
|
||||
@@already_loaded_fixtures ||= {}
|
||||
@connection_subscriber = nil
|
||||
@saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
|
||||
|
||||
if run_in_transaction?
|
||||
# Load fixtures once and begin transaction.
|
||||
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key]
|
||||
unless @loaded_fixtures
|
||||
@@already_loaded_fixtures.clear
|
||||
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key] = load_fixtures(config)
|
||||
end
|
||||
|
||||
setup_transactional_fixtures
|
||||
else
|
||||
# Load fixtures for every test.
|
||||
ActiveRecord::FixtureSet.reset_cache
|
||||
invalidate_already_loaded_fixtures
|
||||
@loaded_fixtures = load_fixtures(config)
|
||||
end
|
||||
|
||||
# Instantiate fixtures for every test if requested.
|
||||
instantiate_fixtures if use_instantiated_fixtures
|
||||
end
|
||||
|
||||
# Instantiate fixtures for every test if requested.
|
||||
instantiate_fixtures if use_instantiated_fixtures
|
||||
end
|
||||
def teardown_fixtures
|
||||
# Rollback changes if a transaction is active.
|
||||
if run_in_transaction?
|
||||
teardown_transactional_fixtures
|
||||
else
|
||||
ActiveRecord::FixtureSet.reset_cache
|
||||
end
|
||||
|
||||
def teardown_fixtures
|
||||
# Rollback changes if a transaction is active.
|
||||
if run_in_transaction?
|
||||
teardown_transactional_fixtures
|
||||
else
|
||||
ActiveRecord::FixtureSet.reset_cache
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
||||
end
|
||||
|
||||
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
||||
end
|
||||
|
||||
private
|
||||
def setup_transactional_fixtures
|
||||
setup_shared_connection_pool
|
||||
|
||||
|
@ -820,19 +820,21 @@ class AdapterThreadSafetyTest < ActiveRecord::TestCase
|
||||
@threads.each(&:kill)
|
||||
end
|
||||
|
||||
test "#active? is synchronized" do
|
||||
threads(2, 25) { @connection.select_all("SELECT 1") }
|
||||
threads(2, 25) { @connection.verify! }
|
||||
threads(2, 25) { @connection.disconnect! }
|
||||
unless in_memory_db?
|
||||
test "#active? is synchronized" do
|
||||
threads(2, 25) { @connection.select_all("SELECT 1") }
|
||||
threads(2, 25) { @connection.verify! }
|
||||
threads(2, 25) { @connection.disconnect! }
|
||||
|
||||
join
|
||||
end
|
||||
join
|
||||
end
|
||||
|
||||
test "#verify! is synchronized" do
|
||||
threads(2, 25) { @connection.verify! }
|
||||
threads(2, 25) { @connection.disconnect! }
|
||||
test "#verify! is synchronized" do
|
||||
threads(2, 25) { @connection.verify! }
|
||||
threads(2, 25) { @connection.disconnect! }
|
||||
|
||||
join
|
||||
join
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -1555,6 +1555,7 @@ def test_marshal_between_processes
|
||||
post.comments.build
|
||||
wr.write Marshal.dump(post)
|
||||
wr.close
|
||||
exit!(0)
|
||||
end
|
||||
|
||||
wr.close
|
||||
|
@ -6,6 +6,11 @@
|
||||
module ActiveRecord
|
||||
module ConnectionAdapters
|
||||
module ConnectionPoolTests
|
||||
def self.included(test)
|
||||
super
|
||||
test.use_transactional_tests = false
|
||||
end
|
||||
|
||||
attr_reader :pool
|
||||
|
||||
def setup
|
||||
|
@ -674,20 +674,30 @@ def change
|
||||
end
|
||||
|
||||
def test_add_foreign_key_is_reversible
|
||||
@connection.drop_table("cities", if_exists: true)
|
||||
@connection.drop_table("houses", if_exists: true)
|
||||
|
||||
migration = CreateCitiesAndHousesMigration.new
|
||||
silence_stream($stdout) { migration.migrate(:up) }
|
||||
assert_equal 1, @connection.foreign_keys("houses").size
|
||||
ensure
|
||||
silence_stream($stdout) { migration.migrate(:down) }
|
||||
ensure
|
||||
@connection.drop_table("cities", if_exists: true)
|
||||
@connection.drop_table("houses", if_exists: true)
|
||||
end
|
||||
|
||||
def test_foreign_key_constraint_is_not_cached_incorrectly
|
||||
@connection.drop_table("cities", if_exists: true)
|
||||
@connection.drop_table("houses", if_exists: true)
|
||||
|
||||
migration = CreateCitiesAndHousesMigration.new
|
||||
silence_stream($stdout) { migration.migrate(:up) }
|
||||
output = dump_table_schema "houses"
|
||||
assert_match %r{\s+add_foreign_key "houses",.+on_delete: :cascade$}, output
|
||||
ensure
|
||||
silence_stream($stdout) { migration.migrate(:down) }
|
||||
ensure
|
||||
@connection.drop_table("cities", if_exists: true)
|
||||
@connection.drop_table("houses", if_exists: true)
|
||||
end
|
||||
|
||||
class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current
|
||||
|
@ -6,6 +6,8 @@
|
||||
require "models/zine"
|
||||
|
||||
class TestFixturesTest < ActiveRecord::TestCase
|
||||
self.use_transactional_tests = false
|
||||
|
||||
setup do
|
||||
@klass = Class.new
|
||||
@klass.include(ActiveRecord::TestFixtures)
|
||||
|
Loading…
Reference in New Issue
Block a user