1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activerecord/test/cases/test_fixtures_test.rb

99 lines
2.8 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
require "cases/helper"
require "tempfile"
require "fileutils"
require "models/zine"
class TestFixturesTest < ActiveRecord::TestCase
setup do
@klass = Class.new
@klass.include(ActiveRecord::TestFixtures)
end
def test_use_transactional_tests_defaults_to_true
assert_equal true, @klass.use_transactional_tests
end
2015-09-20 14:02:11 -04:00
def test_use_transactional_tests_can_be_overridden
@klass.use_transactional_tests = "foobar"
assert_equal "foobar", @klass.use_transactional_tests
end
unless in_memory_db?
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
def test_doesnt_rely_on_active_support_test_case_specific_methods_with_legacy_connection_handling
old_value = ActiveRecord.legacy_connection_handling
ActiveRecord.legacy_connection_handling = true
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
tmp_dir = Dir.mktmpdir
File.write(File.join(tmp_dir, "zines.yml"), <<~YML)
going_out:
title: Hello
YML
klass = Class.new(Minitest::Test) do
include ActiveRecord::TestFixtures
self.fixture_path = tmp_dir
self.use_transactional_tests = true
fixtures :all
2020-12-26 13:09:49 -05:00
def test_run_successfully
assert_equal("Hello", Zine.first.title)
assert_equal("Hello", zines(:going_out).title)
end
end
old_handler = ActiveRecord::Base.connection_handler
ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
assert_deprecated do
ActiveRecord::Base.connection_handlers = {}
end
ActiveRecord::Base.establish_connection(:arunit)
2020-12-26 13:09:49 -05:00
test_result = klass.new("test_run_successfully").run
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
assert_predicate(test_result, :passed?)
ensure
clean_up_legacy_connection_handlers
ActiveRecord::Base.connection_handler = old_handler
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
FileUtils.rm_r(tmp_dir)
ActiveRecord.legacy_connection_handling = old_value
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
end
def test_doesnt_rely_on_active_support_test_case_specific_methods
tmp_dir = Dir.mktmpdir
File.write(File.join(tmp_dir, "zines.yml"), <<~YML)
going_out:
title: Hello
YML
klass = Class.new(Minitest::Test) do
include ActiveRecord::TestFixtures
self.fixture_path = tmp_dir
self.use_transactional_tests = true
fixtures :all
2020-12-26 13:09:49 -05:00
def test_run_successfully
Implement granular role and shard swapping This change allows for a connection to be swapped on role or shard for a class. Previously calling `connected_to` would swap all the connections to a particular role or shard. Granular connection swapping is useful for swapping one connection to reading while leaving all other connection classes on writing. The public methods on connection handler have been updated to behave the same as they did previously on the different handlers. The difference however is instead of calling `ActiveRecord::Base.connection_handlers[:reading].clear_all_connections!` you now call `ActiveRecord::Base.connection_handler.clear_all_connections!` which will clear based on current role set by a `connected_to` block. Outside the context of a `connected_to` block, `clear_all_connections!` can take an optional parameter to clear specific connections by role. The major changes in this PR are: * We introduced a `legacy_connection_handling` configuration option that is set to true by default. It will be set to `false` for all new applications. * In the new connection handling there will be one only connection handler. Previously there was a connection handler for each role. Now the role is stored in the `PoolManager`. In order to maintain backwards compatibility we introduced a `LegacyPoolManager` to avoid duplicate conditionals. See diagram in PR body for changes to connection management. * `connected_to` will now use a stacked concurrent map to keep track of the connection for each class. For each opened block the `class`, `role`, and `shard` will be added to the stack, when the block is exited the `class`, `role`, `shard` array will be removed from the stack. * With these changes `ActiveRecord::Base.connected_to` will remain global. If called all connections in the block will use the `role` and `shard` that was switched to. If called with a parent class like `AnimalsRecord.connected_to` only models under `AnimalsRecord` will be switched and everything else will remain the same. Examples: Given an application we have a `User` model that inherits from `ApplicationRecord` and a `Dog` model that inherits from `AnimalsRecord`. `AnimalsRecord` and `ApplicationRecord` have writing and reading connections as well as shard `default`, `one`, and `two`. ```ruby ActiveRecord::Base.connected_to(role: :reading) do User.first # reads from default replica Dog.first # reads from default replica AnimalsRecord.connected_to(role: :writing, shard: :one) do User.first # reads from default replica Dog.first # reads from shard one primary end User.first # reads from default replica Dog.first # reads from default replica ApplicationRecord.connected_to(role: :writing, shard: :two) do User.first # reads from shard two primary Dog.first # reads from default replica end end ``` Things this PR does not solve: * Currently there is no API for swapping more than one but not all connections. Apps with many primaries may want to swap 3 but not all 10 connections. We plan to build an API for that in a followup PR. * The middleware remains the same and is using the global switching methods. Therefore at this time to use this new feature applications must manually switch connections. We will also address this in a followup PR. * The `schema_cache` is currently on the `PoolConfig`. We plan on trying to move this up to the `PoolManager` or elsewhere later on so each `PoolConfig` doesn't need to hold a reference to the `schema_cache`. Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
2020-09-11 16:06:25 -04:00
assert_equal("Hello", Zine.first.title)
assert_equal("Hello", zines(:going_out).title)
end
end
old_handler = ActiveRecord::Base.connection_handler
ActiveRecord::Base.connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
ActiveRecord::Base.establish_connection(:arunit)
2020-12-26 13:09:49 -05:00
test_result = klass.new("test_run_successfully").run
assert_predicate(test_result, :passed?)
ensure
ActiveRecord::Base.connection_handler = old_handler
clean_up_connection_handler
FileUtils.rm_r(tmp_dir)
end
end
end