connection_pool_test.rb 4.6 KB
Newer Older
1
require "cases/helper"
2 3 4 5

module ActiveRecord
  module ConnectionAdapters
    class ConnectionPoolTest < ActiveRecord::TestCase
6 7
      attr_reader :pool

8
      def setup
9 10
        super

11 12
        # Keep a duplicate pool so we do not bother others
        @pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
13 14 15 16 17 18 19 20 21 22

        if in_memory_db?
          # Separate connections to an in-memory database create an entirely new database,
          # with an empty schema etc, so we just stub out this schema on the fly.
          @pool.with_connection do |connection|
            connection.create_table :posts do |t|
              t.integer :cololumn
            end
          end
        end
23 24
      end

25 26
      def teardown
        super
27
        @pool.disconnect!
28 29
      end

30 31 32 33
      def active_connections(pool)
        pool.connections.find_all(&:in_use?)
      end

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
      def test_released_connection_moves_between_threads
        thread_conn = nil

        Thread.new {
          pool.with_connection do |conn|
            thread_conn = conn
          end
        }.join

        assert thread_conn

        Thread.new {
          pool.with_connection do |conn|
            assert_equal thread_conn, conn
          end
        }.join
      end

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
      def test_with_connection
        assert_equal 0, active_connections(pool).size

        main_thread = pool.connection
        assert_equal 1, active_connections(pool).size

        Thread.new {
          pool.with_connection do |conn|
            assert conn
            assert_equal 2, active_connections(pool).size
          end
          assert_equal 1, active_connections(pool).size
        }.join

        main_thread.close
        assert_equal 0, active_connections(pool).size
      end

      def test_active_connection_in_use
        assert !pool.active_connection?
        main_thread = pool.connection

        assert pool.active_connection?

        main_thread.close

        assert !pool.active_connection?
      end

81 82 83 84 85 86 87 88
      def test_full_pool_exception
        assert_raises(PoolFullError) do
          (@pool.size + 1).times do
            @pool.checkout
          end
        end
      end

89
      def test_reap_and_active
90 91 92 93 94 95 96 97 98
        @pool.checkout
        @pool.checkout
        @pool.checkout
        @pool.timeout = 0

        connections = @pool.connections.dup

        @pool.reap

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
        assert_equal connections.length, @pool.connections.length
      end

      def test_reap_inactive
        @pool.checkout
        @pool.checkout
        @pool.checkout
        @pool.timeout = 0

        connections = @pool.connections.dup
        connections.each do |conn|
          conn.extend(Module.new { def active?; false; end; })
        end

        @pool.reap

115 116
        assert_equal 0, @pool.connections.length
      ensure
117
        connections.each(&:close)
118 119
      end

120 121 122 123 124 125 126 127 128 129 130 131
      def test_remove_connection
        conn = @pool.checkout
        assert conn.in_use?

        length = @pool.connections.length
        @pool.remove conn
        assert conn.in_use?
        assert_equal(length - 1, @pool.connections.length)
      ensure
        conn.close
      end

132 133 134 135 136
      def test_remove_connection_for_thread
        conn = @pool.connection
        @pool.remove conn
        assert_not_equal(conn, @pool.connection)
      ensure
137
        conn.close if conn
138 139
      end

140 141 142 143 144 145 146 147
      def test_active_connection?
        assert !@pool.active_connection?
        assert @pool.connection
        assert @pool.active_connection?
        @pool.release_connection
        assert !@pool.active_connection?
      end

148 149 150 151 152 153 154 155 156
      def test_checkout_behaviour
        pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
        connection = pool.connection
        assert_not_nil connection
        threads = []
        4.times do |i|
          threads << Thread.new(i) do |pool_count|
            connection = pool.connection
            assert_not_nil connection
157
            connection.close
158 159
          end
        end
A
Aaron Patterson 已提交
160

161
        threads.each(&:join)
A
Aaron Patterson 已提交
162

163
        Thread.new do
164
          assert pool.connection
165 166
          pool.connection.close
        end.join
167
      end
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

      def test_automatic_reconnect=
        pool = ConnectionPool.new ActiveRecord::Base.connection_pool.spec
        assert pool.automatic_reconnect
        assert pool.connection

        pool.disconnect!
        assert pool.connection

        pool.disconnect!
        pool.automatic_reconnect = false

        assert_raises(ConnectionNotEstablished) do
          pool.connection
        end

        assert_raises(ConnectionNotEstablished) do
          pool.with_connection
        end
      end
188 189 190 191

      def test_pool_sets_connection_visitor
        assert @pool.connection.visitor.is_a?(Arel::Visitors::ToSql)
      end
192 193 194
    end
  end
end