<commit_before>describe "pglogical replication" do
  self.use_transactional_tests = false

  let(:slave_db_name)        { Rails.configuration.database_configuration[Rails.env]["database"] }
  let(:master_db_name)       { "#{slave_db_name}_master" }
  let(:replication_set_name) { "test_rep_set" }
  let(:sub_name)             { "test_subscription" }

  let(:excluded_tables_regex) do
    excluded_tables = @replication_config[:exclude_tables].join("|")
    excluded_tables = "^(#{excluded_tables})$"
    Regexp.new(excluded_tables)
  end

  let(:conn_info) do
    config = Rails.configuration.database_configuration[Rails.env]
    dsn = ""
    dsn << "user=#{config["username"]} " if config["username"]
    dsn << "password=#{config["password"]} " if config["password"]
    dsn << "host=#{config["host"]}" if config["host"]
    dsn
  end

  let(:slave_dsn)  { "dbname=#{slave_db_name} #{conn_info}" }
  let(:master_dsn) { "dbname=#{master_db_name} #{conn_info}" }

  before do
    skip "pglogical must be installed" unless ActiveRecord::Base.connection.pglogical.installed?

    MiqRegion.seed
    Zone.seed
    MiqServer.seed

    master_db_config = Rails.configuration.database_configuration[Rails.env].symbolize_keys
                                                                            .merge(:database => master_db_name)

    c = MiqServer.my_server.get_config
    c.config.store_path(:workers, :worker_base, :replication_worker, :replication, :destination, master_db_config)
    c.save

    @replication_config = c.config.fetch_path(:workers, :worker_base, :replication_worker, :replication)

    class ::MasterDb < ActiveRecord::Base; end
    MasterDb.establish_connection(master_db_config)
    @master_connection = MasterDb.connection
    @slave_connection = ActiveRecord::Base.connection

    enable_nodes
  end

  after do
    Object.send(:remove_const, :MasterDb) if defined? MasterDb
    @slave_connection.pglogical.replication_set_drop(replication_set_name)
    @slave_connection.pglogical.node_drop("slave_node")
  end

  # As these tests are not rolled back it makes sense to do the test in one shot and make them order dependant.
  it "replicates" do
    insert_start = 0

    # Test that rows are replicated initially on subscription create
    tables = insert_records(insert_start)
    @master_connection.pglogical.subscription_create(sub_name, slave_dsn, [replication_set_name], false)
    sleep(5)
    assert_records_replicated(tables)
    insert_start += 2

    # Test subscription info methods
    sub_info = @master_connection.pglogical.subscription_show_status(sub_name)
    expect(sub_info["subscription_name"]).to eq(sub_name)
    expect(sub_info["status"]).to eq("replicating")
    expect(sub_info["provider_dsn"]).to eq(slave_dsn)
    expect(sub_info["replication_sets"]).to eq([replication_set_name])

    sub_list = @master_connection.pglogical.subscriptions
    expect(sub_list.first).to eq(sub_info)

    # add a block so that we can be sure we try to clean up the subscription
    # otherwise existing replication connections will prevent us from removing
    # the test master database
    begin
      # Test that rows are replicated as they are inserted when there is an active subscription
      tables = insert_records(insert_start)
      sleep(5)
      assert_records_replicated(tables)
      insert_start += 2

      # Test that no changes are replicated through a disabled subscription
      @master_connection.pglogical.subscription_disable(sub_name)
      tables = insert_records(insert_start)
      assert_records_not_replicated(tables)
      insert_start += 2

      # Test that previous changes are replicated through a re-enabled subscription
      @master_connection.pglogical.subscription_enable(sub_name)
      sleep(5)
      assert_records_replicated(tables)

    ensure
      # Drop the subscription and make sure no more rows are replicated
      @master_connection.pglogical.subscription_drop(sub_name)
      tables = insert_records(insert_start)
      assert_records_not_replicated(tables)
    end
  end

  def insert_records(start = 0)<commit_msg>Move more spec code into the block so the subscription will be removed on failure<commit_after>describe "pglogical replication" do
  self.use_transactional_tests = false

  let(:slave_db_name)        { Rails.configuration.database_configuration[Rails.env]["database"] }
  let(:master_db_name)       { "#{slave_db_name}_master" }
  let(:replication_set_name) { "test_rep_set" }
  let(:sub_name)             { "test_subscription" }

  let(:excluded_tables_regex) do
    excluded_tables = @replication_config[:exclude_tables].join("|")
    excluded_tables = "^(#{excluded_tables})$"
    Regexp.new(excluded_tables)
  end

  let(:conn_info) do
    config = Rails.configuration.database_configuration[Rails.env]
    dsn = ""
    dsn << "user=#{config["username"]} " if config["username"]
    dsn << "password=#{config["password"]} " if config["password"]
    dsn << "host=#{config["host"]}" if config["host"]
    dsn
  end

  let(:slave_dsn)  { "dbname=#{slave_db_name} #{conn_info}" }
  let(:master_dsn) { "dbname=#{master_db_name} #{conn_info}" }

  before do
    skip "pglogical must be installed" unless ActiveRecord::Base.connection.pglogical.installed?

    MiqRegion.seed
    Zone.seed
    MiqServer.seed

    master_db_config = Rails.configuration.database_configuration[Rails.env].symbolize_keys
                                                                            .merge(:database => master_db_name)

    c = MiqServer.my_server.get_config
    c.config.store_path(:workers, :worker_base, :replication_worker, :replication, :destination, master_db_config)
    c.save

    @replication_config = c.config.fetch_path(:workers, :worker_base, :replication_worker, :replication)

    class ::MasterDb < ActiveRecord::Base; end
    MasterDb.establish_connection(master_db_config)
    @master_connection = MasterDb.connection
    @slave_connection = ActiveRecord::Base.connection

    enable_nodes
  end

  after do
    Object.send(:remove_const, :MasterDb) if defined? MasterDb
    @slave_connection.pglogical.replication_set_drop(replication_set_name)
    @slave_connection.pglogical.node_drop("slave_node")
  end

  # As these tests are not rolled back it makes sense to do the test in one shot and make them order dependant.
  it "replicates" do
    insert_start = 0

    # Test that rows are replicated initially on subscription create
    tables = insert_records(insert_start)
    @master_connection.pglogical.subscription_create(sub_name, slave_dsn, [replication_set_name], false)

    # add a block so that we can be sure we try to clean up the subscription
    # otherwise existing replication connections will prevent us from removing
    # the test master database
    begin

      sleep(5)
      assert_records_replicated(tables)
      insert_start += 2

      # Test subscription info methods
      sub_info = @master_connection.pglogical.subscription_show_status(sub_name)
      expect(sub_info["subscription_name"]).to eq(sub_name)
      expect(sub_info["status"]).to eq("replicating")
      expect(sub_info["provider_dsn"]).to eq(slave_dsn)
      expect(sub_info["replication_sets"]).to eq([replication_set_name])

      sub_list = @master_connection.pglogical.subscriptions
      expect(sub_list.first).to eq(sub_info)

      # Test that rows are replicated as they are inserted when there is an active subscription
      tables = insert_records(insert_start)
      sleep(5)
      assert_records_replicated(tables)
      insert_start += 2

      # Test that no changes are replicated through a disabled subscription
      @master_connection.pglogical.subscription_disable(sub_name)
      tables = insert_records(insert_start)
      assert_records_not_replicated(tables)
      insert_start += 2

      # Test that previous changes are replicated through a re-enabled subscription
      @master_connection.pglogical.subscription_enable(sub_name)
      sleep(5)
      assert_records_replicated(tables)

    ensure
      # Drop the subscription and make sure no more rows are replicated
      @master_connection.pglogical.subscription_drop(sub_name)
      tables = insert_records(insert_start)
      assert_records_not_replicated(tables)
    end
  end

  def insert_records(start = 0)
{'fraction_non_alphanumeric': 0.09244102070293693, 'fraction_numerical': 0.0019258545979778526, 'mean_word_length': 3.9194789816459443, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4315668', 'n_tokens_mistral': 2497, 'n_tokens_neox': 2429, 'n_words': 539}