blob: 340151e6dbb452d32d10d8e23ab1f15af41b0f9b (
plain) (
tree)
|
|
# frozen_string_literal: true
require "cases/helper"
require "models/person"
require "action_dispatch"
module ActiveRecord
class DatabaseSelectorTest < ActiveRecord::TestCase
setup do
@session_store = {}
@session = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session.new(@session_store)
end
teardown do
ActiveRecord::Base.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
end
def test_empty_session
assert_equal Time.at(0), @session.last_write_timestamp
end
def test_writing_the_session_timestamps
assert @session.update_last_write_timestamp
session2 = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session.new(@session_store)
assert_equal @session.last_write_timestamp, session2.last_write_timestamp
end
def test_writing_session_time_changes
assert @session.update_last_write_timestamp
before = @session.last_write_timestamp
sleep(0.1)
assert @session.update_last_write_timestamp
assert_not_equal before, @session.last_write_timestamp
end
def test_read_from_replicas
@session_store[:last_write] = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session.convert_time_to_timestamp(Time.now - 5.seconds)
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session)
called = false
resolver.read do
called = true
assert ActiveRecord::Base.connected_to?(role: :reading)
end
assert called
end
def test_read_from_primary
@session_store[:last_write] = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session.convert_time_to_timestamp(Time.now)
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session)
called = false
resolver.read do
called = true
assert ActiveRecord::Base.connected_to?(role: :writing)
end
assert called
end
def test_write_to_primary
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session)
# Session should start empty
assert_nil @session_store[:last_write]
called = false
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
end
assert called
# and be populated by the last write time
assert @session_store[:last_write]
end
def test_write_to_primary_with_exception
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session)
# Session should start empty
assert_nil @session_store[:last_write]
called = false
assert_raises(ActiveRecord::RecordNotFound) do
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
raise ActiveRecord::RecordNotFound
end
end
assert called
# and be populated by the last write time
assert @session_store[:last_write]
end
def test_read_from_primary_with_options
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 5.seconds)
# Session should start empty
assert_nil @session_store[:last_write]
called = false
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
end
assert called
# and be populated by the last write time
assert @session_store[:last_write]
read = false
resolver.read do
assert ActiveRecord::Base.connected_to?(role: :writing)
read = true
end
assert read
end
def test_preventing_writes_turns_off_for_primary_write
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 5.seconds)
# Session should start empty
assert_nil @session_store[:last_write]
called = false
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
end
assert called
# and be populated by the last write time
assert @session_store[:last_write]
read = false
write = false
resolver.read do
assert ActiveRecord::Base.connected_to?(role: :writing)
assert ActiveRecord::Base.connection_handler.prevent_writes
read = true
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
assert_not ActiveRecord::Base.connection_handler.prevent_writes
write = true
end
end
assert write
assert read
end
def test_read_from_replica_with_no_delay
resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver.new(@session, delay: 0.seconds)
# Session should start empty
assert_nil @session_store[:last_write]
called = false
resolver.write do
assert ActiveRecord::Base.connected_to?(role: :writing)
called = true
end
assert called
# and be populated by the last write time
assert @session_store[:last_write]
read = false
resolver.read do
assert ActiveRecord::Base.connected_to?(role: :reading)
read = true
end
assert read
end
def test_the_middleware_chooses_writing_role_with_POST_request
middleware = ActiveRecord::Middleware::DatabaseSelector.new(lambda { |env|
assert ActiveRecord::Base.connected_to?(role: :writing)
[200, {}, ["body"]]
})
assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "POST")
end
def test_the_middleware_chooses_reading_role_with_GET_request
middleware = ActiveRecord::Middleware::DatabaseSelector.new(lambda { |env|
assert ActiveRecord::Base.connected_to?(role: :reading)
[200, {}, ["body"]]
})
assert_equal [200, {}, ["body"]], middleware.call("REQUEST_METHOD" => "GET")
end
end
end
|