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/connection_management_test.rb
Sean Griffin 1ca6f7f767 Do not attempt to return connection with open transaction to pool (#24610)
When the query cache completes, if Active Record is still inside of a
transaction, it is because the transaction is meant to be left open
above this unit of work (such as transactional fixtures in tests). There
were several tests around the behavior of "tests" that were invalid, as
tests are not run through the executor. They have been changed to
reflect the new behavior, which is closer to what actually occurs in
Rails tests.

Fixes #23989
Fixes #24491
Close #24500
2016-04-22 12:56:43 -06:00

112 lines
3.4 KiB
Ruby

require "cases/helper"
require "rack"
module ActiveRecord
module ConnectionAdapters
class ConnectionManagementTest < ActiveRecord::TestCase
self.use_transactional_tests = false
class App
attr_reader :calls
def initialize
@calls = []
end
def call(env)
@calls << env
[200, {}, ['hi mom']]
end
end
def setup
@env = {}
@app = App.new
@management = middleware(@app)
# make sure we have an active connection
assert ActiveRecord::Base.connection
assert ActiveRecord::Base.connection_handler.active_connections?
end
def test_app_delegation
manager = middleware(@app)
manager.call @env
assert_equal [@env], @app.calls
end
def test_body_responds_to_each
_, _, body = @management.call(@env)
bits = []
body.each { |bit| bits << bit }
assert_equal ['hi mom'], bits
end
def test_connections_are_cleared_after_body_close
_, _, body = @management.call(@env)
body.close
assert !ActiveRecord::Base.connection_handler.active_connections?
end
def test_active_connections_are_not_cleared_on_body_close_during_transaction
ActiveRecord::Base.transaction do
_, _, body = @management.call(@env)
body.close
assert ActiveRecord::Base.connection_handler.active_connections?
end
end
def test_connections_closed_if_exception
app = Class.new(App) { def call(env); raise NotImplementedError; end }.new
explosive = middleware(app)
assert_raises(NotImplementedError) { explosive.call(@env) }
assert !ActiveRecord::Base.connection_handler.active_connections?
end
def test_connections_not_closed_if_exception_inside_transaction
ActiveRecord::Base.transaction do
app = Class.new(App) { def call(env); raise RuntimeError; end }.new
explosive = middleware(app)
assert_raises(RuntimeError) { explosive.call(@env) }
assert ActiveRecord::Base.connection_handler.active_connections?
end
end
test "doesn't clear active connections when running in a test case" do
executor.wrap do
@management.call(@env)
assert ActiveRecord::Base.connection_handler.active_connections?
end
end
test "proxy is polite to its body and responds to it" do
body = Class.new(String) { def to_path; "/path"; end }.new
app = lambda { |_| [200, {}, body] }
response_body = middleware(app).call(@env)[2]
assert response_body.respond_to?(:to_path)
assert_equal "/path", response_body.to_path
end
test "doesn't mutate the original response" do
original_response = [200, {}, 'hi']
app = lambda { |_| original_response }
middleware(app).call(@env)[2]
assert_equal 'hi', original_response.last
end
private
def executor
@executor ||= Class.new(ActiveSupport::Executor).tap do |exe|
ActiveRecord::QueryCache.install_executor_hooks(exe)
end
end
def middleware(app)
lambda do |env|
a, b, c = executor.wrap { app.call(env) }
[a, b, Rack::BodyProxy.new(c) { }]
end
end
end
end
end