diff options
Diffstat (limited to 'activerecord/test/cases/connection_management_test.rb')
-rw-r--r-- | activerecord/test/cases/connection_management_test.rb | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/activerecord/test/cases/connection_management_test.rb b/activerecord/test/cases/connection_management_test.rb new file mode 100644 index 0000000000..0941ee3309 --- /dev/null +++ b/activerecord/test/cases/connection_management_test.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +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_predicate 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_not_predicate 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_predicate 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_not_predicate 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_predicate 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_predicate 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_respond_to response_body, :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 |