<commit_before>require_relative '../../spec_helper'

describe CartoDB::ConnectionPool do
  before(:all) do
    @max_pool_size = ConnectionPool::MAX_POOL_SIZE
    ConnectionPool::MAX_POOL_SIZE = 2
  end

  after(:all) do
    ConnectionPool::MAX_POOL_SIZE = @max_pool_size
  end

  before(:each) do
    # Need to close the connections because there might be more than the new maximum already in the pool
    $pool.close_connections!
  end

  after(:each) do
    @new_user.destroy unless @new_user.nil?
  end

  def database_object_count
    GC.start
    ObjectSpace.each_object(Sequel::Postgres::Database).count
  end

  def user_object_count
    GC.start
    ObjectSpace.each_object(User).count
  end

  def pool_contains?(connection)
    $pool.all.values.map { |a| a[:connection] }.include?(connection)
  end

  describe '#eviction_policy' do
    it 'evicts older connection (LRU)' do
      @new_user = create_user
      conn_1 = $user_1.in_database
      conn_2 = $user_2.in_database
      conn_3 = @new_user.in_database
      pool_contains?(conn_1).should be_false
      pool_contains?(conn_2).should be_true
      pool_contains?(conn_3).should be_true

      conn_1 = $user_1.in_database
      pool_contains?(conn_1).should be_true
      pool_contains?(conn_2).should be_false
      pool_contains?(conn_3).should be_true
    end
  end

  describe '#user_databases' do
    it 'does not leak user databases' do
      # The maximum number of connections allowed in memory before the test is considered to be leaking (failure).
      # Although the pool will only keep 2 connections open (MAX_POOL_SIZE set at the beginning of the test),
      # there are some other connections that are not tracked by the pool (tracked by Rails instead).
      # Typical # of connections is 5 for correct tests and 50 for leaky tests but vary depending on execution order.
      MAX_ALLOWABLE_CONNECTIONS = 10

      initial_user_count = user_object_count
      @new_user = create_user

      # Create some connections to user database and check that they are not leaked
      (0..4).each do |_|
        [$user_1, $user_2, @new_user].each do |user|
          user.in_database.test_connection.should be_true
        end
      end
      database_object_count.should < MAX_ALLOWABLE_CONNECTIONS

      # Destroy new user and ensure it does not leaks (as soon as his db connection is evicted)
      @new_user.destroy
      @new_user = nil

      (0..4).each do |_|
        [$user_1, $user_2].each do |user|
          user.in_database.test_connection.should be_true
        end
      end
      database_object_count.should < MAX_ALLOWABLE_CONNECTIONS
      user_object_count.should eq initial_user_count
    end
  end
end<commit_msg>Account for initial db objects in connection_pool_spec<commit_after>require_relative '../../spec_helper'

describe CartoDB::ConnectionPool do
  before(:all) do
    @max_pool_size = ConnectionPool::MAX_POOL_SIZE
    ConnectionPool::MAX_POOL_SIZE = 2
  end

  after(:all) do
    ConnectionPool::MAX_POOL_SIZE = @max_pool_size
  end

  before(:each) do
    # Need to close the connections because there might be more than the new maximum already in the pool
    $pool.close_connections!
  end

  after(:each) do
    @new_user.destroy unless @new_user.nil?
  end

  def database_object_count
    GC.start
    ObjectSpace.each_object(Sequel::Postgres::Database).count
  end

  def user_object_count
    GC.start
    ObjectSpace.each_object(User).count
  end

  def pool_contains?(connection)
    $pool.all.values.map { |a| a[:connection] }.include?(connection)
  end

  describe '#eviction_policy' do
    it 'evicts older connection (LRU)' do
      @new_user = create_user
      conn_1 = $user_1.in_database
      conn_2 = $user_2.in_database
      conn_3 = @new_user.in_database
      pool_contains?(conn_1).should be_false
      pool_contains?(conn_2).should be_true
      pool_contains?(conn_3).should be_true

      conn_1 = $user_1.in_database
      pool_contains?(conn_1).should be_true
      pool_contains?(conn_2).should be_false
      pool_contains?(conn_3).should be_true
    end
  end

  describe '#user_databases' do
    it 'does not leak user databases' do
      # The maximum number of connections allowed in memory before the test is considered to be leaking (failure).
      # Although the pool will only keep 2 connections open (MAX_POOL_SIZE set at the beginning of the test),
      # there are some other connections that are not tracked by the pool (tracked by Rails instead).
      # Typical # of connections is 0 for correct tests and 45 for leaky tests but vary depending on execution order.
      MAX_ALLOWABLE_CONNECTIONS = 5

      initial_user_count = user_object_count
      initial_db_count = database_object_count
      @new_user = create_user

      # Create some connections to user database and check that they are not leaked
      (0..4).each do |_|
        [$user_1, $user_2, @new_user].each do |user|
          user.in_database.test_connection.should be_true
        end
      end
      database_object_count.should < (initial_db_count + MAX_ALLOWABLE_CONNECTIONS)

      # Destroy new user and ensure it does not leaks (as soon as his db connection is evicted)
      @new_user.destroy
      @new_user = nil

      (0..4).each do |_|
        [$user_1, $user_2].each do |user|
          user.in_database.test_connection.should be_true
        end
      end
      database_object_count.should < (initial_db_count + MAX_ALLOWABLE_CONNECTIONS)
      user_object_count.should eq initial_user_count
    end
  end
end
{'fraction_non_alphanumeric': 0.07221321808031694, 'fraction_numerical': 0.00990455609580407, 'mean_word_length': 3.1822289156626504, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3093031', 'n_tokens_mistral': 1733, 'n_tokens_neox': 1683, 'n_words': 497}