499 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			499 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
require 'spec_helper'
 | 
						|
 | 
						|
RSpec.describe Gitlab::Database::MigrationHelpers::V2 do
 | 
						|
  include Database::TriggerHelpers
 | 
						|
  include Database::TableSchemaHelpers
 | 
						|
 | 
						|
  let(:migration) do
 | 
						|
    ActiveRecord::Migration.new.extend(described_class)
 | 
						|
  end
 | 
						|
 | 
						|
  before do
 | 
						|
    allow(migration).to receive(:puts)
 | 
						|
 | 
						|
    allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
 | 
						|
  end
 | 
						|
 | 
						|
  shared_examples_for 'Setting up to rename a column' do
 | 
						|
    let(:model) { Class.new(ActiveRecord::Base) }
 | 
						|
 | 
						|
    before do
 | 
						|
      model.table_name = :_test_table
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when called inside a transaction block' do
 | 
						|
      before do
 | 
						|
        allow(migration).to receive(:transaction_open?).and_return(true)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'raises an error' do
 | 
						|
        expect do
 | 
						|
          migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
        end.to raise_error("#{operation} can not be run inside a transaction")
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the existing column has a default function' do
 | 
						|
      before do
 | 
						|
        migration.change_column_default :_test_table, existing_column, -> { 'now()' }
 | 
						|
      end
 | 
						|
 | 
						|
      it 'raises an error' do
 | 
						|
        expect do
 | 
						|
          migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
        end.to raise_error("#{operation} does not currently support columns with default functions")
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when passing a batch column' do
 | 
						|
      context 'when the batch column does not exist' do
 | 
						|
        it 'raises an error' do
 | 
						|
          expect do
 | 
						|
            migration.public_send(operation, :_test_table, :original, :renamed, batch_column_name: :missing)
 | 
						|
          end.to raise_error('Column missing does not exist on _test_table')
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when the batch column does exist' do
 | 
						|
        it 'passes it when creating the column' do
 | 
						|
          expect(migration).to receive(:create_column_from)
 | 
						|
            .with(:_test_table, existing_column, added_column, type: nil, batch_column_name: :status)
 | 
						|
            .and_call_original
 | 
						|
 | 
						|
          migration.public_send(operation, :_test_table, :original, :renamed, batch_column_name: :status)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the existing column has a default value' do
 | 
						|
      before do
 | 
						|
        migration.change_column_default :_test_table, existing_column, 'default value'
 | 
						|
      end
 | 
						|
 | 
						|
      it 'creates the renamed column, syncing existing data' do
 | 
						|
        existing_record_1 = model.create!(status: 0, existing_column => 'existing')
 | 
						|
        existing_record_2 = model.create!(status: 0)
 | 
						|
 | 
						|
        migration.send(operation, :_test_table, :original, :renamed)
 | 
						|
        model.reset_column_information
 | 
						|
 | 
						|
        expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
 | 
						|
 | 
						|
        expect(existing_record_1.reload).to have_attributes(status: 0, original: 'existing', renamed: 'existing')
 | 
						|
        expect(existing_record_2.reload).to have_attributes(status: 0, original: 'default value', renamed: 'default value')
 | 
						|
      end
 | 
						|
 | 
						|
      it 'installs triggers to sync new data' do
 | 
						|
        migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
        model.reset_column_information
 | 
						|
 | 
						|
        new_record_1 = model.create!(status: 1, original: 'first')
 | 
						|
        new_record_2 = model.create!(status: 1, renamed: 'second')
 | 
						|
        new_record_3 = model.create!(status: 1)
 | 
						|
        new_record_4 = model.create!(status: 1)
 | 
						|
 | 
						|
        expect(new_record_1.reload).to have_attributes(status: 1, original: 'first', renamed: 'first')
 | 
						|
        expect(new_record_2.reload).to have_attributes(status: 1, original: 'second', renamed: 'second')
 | 
						|
        expect(new_record_3.reload).to have_attributes(status: 1, original: 'default value', renamed: 'default value')
 | 
						|
        expect(new_record_4.reload).to have_attributes(status: 1, original: 'default value', renamed: 'default value')
 | 
						|
 | 
						|
        new_record_1.update!(original: 'updated')
 | 
						|
        new_record_2.update!(renamed: nil)
 | 
						|
        new_record_3.update!(renamed: 'update renamed')
 | 
						|
        new_record_4.update!(original: 'update original')
 | 
						|
 | 
						|
        expect(new_record_1.reload).to have_attributes(status: 1, original: 'updated', renamed: 'updated')
 | 
						|
        expect(new_record_2.reload).to have_attributes(status: 1, original: nil, renamed: nil)
 | 
						|
        expect(new_record_3.reload).to have_attributes(status: 1, original: 'update renamed', renamed: 'update renamed')
 | 
						|
        expect(new_record_4.reload).to have_attributes(status: 1, original: 'update original', renamed: 'update original')
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the existing column has a default value that evaluates to NULL' do
 | 
						|
      before do
 | 
						|
        migration.change_column_default :_test_table, existing_column, -> { "('test' || null)" }
 | 
						|
      end
 | 
						|
 | 
						|
      it 'creates the renamed column, syncing existing data' do
 | 
						|
        existing_record_1 = model.create!(status: 0, existing_column => 'existing')
 | 
						|
        existing_record_2 = model.create!(status: 0)
 | 
						|
 | 
						|
        migration.send(operation, :_test_table, :original, :renamed)
 | 
						|
        model.reset_column_information
 | 
						|
 | 
						|
        expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
 | 
						|
 | 
						|
        expect(existing_record_1.reload).to have_attributes(status: 0, original: 'existing', renamed: 'existing')
 | 
						|
        expect(existing_record_2.reload).to have_attributes(status: 0, original: nil, renamed: nil)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'installs triggers to sync new data' do
 | 
						|
        migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
        model.reset_column_information
 | 
						|
 | 
						|
        new_record_1 = model.create!(status: 1, original: 'first')
 | 
						|
        new_record_2 = model.create!(status: 1, renamed: 'second')
 | 
						|
        new_record_3 = model.create!(status: 1)
 | 
						|
        new_record_4 = model.create!(status: 1)
 | 
						|
 | 
						|
        expect(new_record_1.reload).to have_attributes(status: 1, original: 'first', renamed: 'first')
 | 
						|
        expect(new_record_2.reload).to have_attributes(status: 1, original: 'second', renamed: 'second')
 | 
						|
        expect(new_record_3.reload).to have_attributes(status: 1, original: nil, renamed: nil)
 | 
						|
        expect(new_record_4.reload).to have_attributes(status: 1, original: nil, renamed: nil)
 | 
						|
 | 
						|
        new_record_1.update!(original: 'updated')
 | 
						|
        new_record_2.update!(renamed: nil)
 | 
						|
        new_record_3.update!(renamed: 'update renamed')
 | 
						|
        new_record_4.update!(original: 'update original')
 | 
						|
 | 
						|
        expect(new_record_1.reload).to have_attributes(status: 1, original: 'updated', renamed: 'updated')
 | 
						|
        expect(new_record_2.reload).to have_attributes(status: 1, original: nil, renamed: nil)
 | 
						|
        expect(new_record_3.reload).to have_attributes(status: 1, original: 'update renamed', renamed: 'update renamed')
 | 
						|
        expect(new_record_4.reload).to have_attributes(status: 1, original: 'update original', renamed: 'update original')
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    it 'creates the renamed column, syncing existing data' do
 | 
						|
      existing_record_1 = model.create!(status: 0, existing_column => 'existing')
 | 
						|
      existing_record_2 = model.create!(status: 0, existing_column => nil)
 | 
						|
 | 
						|
      migration.send(operation, :_test_table, :original, :renamed)
 | 
						|
      model.reset_column_information
 | 
						|
 | 
						|
      expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
 | 
						|
 | 
						|
      expect(existing_record_1.reload).to have_attributes(status: 0, original: 'existing', renamed: 'existing')
 | 
						|
      expect(existing_record_2.reload).to have_attributes(status: 0, original: nil, renamed: nil)
 | 
						|
    end
 | 
						|
 | 
						|
    it 'installs triggers to sync new data' do
 | 
						|
      migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
      model.reset_column_information
 | 
						|
 | 
						|
      new_record_1 = model.create!(status: 1, original: 'first')
 | 
						|
      new_record_2 = model.create!(status: 1, renamed: 'second')
 | 
						|
 | 
						|
      expect(new_record_1.reload).to have_attributes(status: 1, original: 'first', renamed: 'first')
 | 
						|
      expect(new_record_2.reload).to have_attributes(status: 1, original: 'second', renamed: 'second')
 | 
						|
 | 
						|
      new_record_1.update!(original: 'updated')
 | 
						|
      new_record_2.update!(renamed: nil)
 | 
						|
 | 
						|
      expect(new_record_1.reload).to have_attributes(status: 1, original: 'updated', renamed: 'updated')
 | 
						|
      expect(new_record_2.reload).to have_attributes(status: 1, original: nil, renamed: nil)
 | 
						|
    end
 | 
						|
 | 
						|
    it 'requires the helper to run in ddl mode' do
 | 
						|
      expect(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas).to receive(:require_ddl_mode!)
 | 
						|
 | 
						|
      migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#rename_column_concurrently' do
 | 
						|
    before do
 | 
						|
      allow(migration).to receive(:transaction_open?).and_return(false)
 | 
						|
 | 
						|
      migration.create_table :_test_table do |t|
 | 
						|
        t.integer :status, null: false
 | 
						|
        t.text :original
 | 
						|
        t.text :other_column
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    it_behaves_like 'Setting up to rename a column' do
 | 
						|
      let(:operation) { :rename_column_concurrently }
 | 
						|
      let(:existing_column) { :original }
 | 
						|
      let(:added_column) { :renamed }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the column to rename does not exist' do
 | 
						|
      it 'raises an error' do
 | 
						|
        expect do
 | 
						|
          migration.rename_column_concurrently :_test_table, :missing_column, :renamed
 | 
						|
        end.to raise_error('Column missing_column does not exist on _test_table')
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#undo_cleanup_concurrent_column_rename' do
 | 
						|
    before do
 | 
						|
      allow(migration).to receive(:transaction_open?).and_return(false)
 | 
						|
 | 
						|
      migration.create_table :_test_table do |t|
 | 
						|
        t.integer :status, null: false
 | 
						|
        t.text :other_column
 | 
						|
        t.text :renamed
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    it_behaves_like 'Setting up to rename a column' do
 | 
						|
      let(:operation) { :undo_cleanup_concurrent_column_rename }
 | 
						|
      let(:existing_column) { :renamed }
 | 
						|
      let(:added_column) { :original }
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the renamed column does not exist' do
 | 
						|
      it 'raises an error' do
 | 
						|
        expect do
 | 
						|
          migration.undo_cleanup_concurrent_column_rename :_test_table, :original, :missing_column
 | 
						|
        end.to raise_error('Column missing_column does not exist on _test_table')
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  shared_examples_for 'Cleaning up from renaming a column' do
 | 
						|
    let(:connection) { migration.connection }
 | 
						|
 | 
						|
    before do
 | 
						|
      allow(migration).to receive(:transaction_open?).and_return(false)
 | 
						|
 | 
						|
      migration.create_table :_test_table do |t|
 | 
						|
        t.integer :status, null: false
 | 
						|
        t.text :original
 | 
						|
        t.text :other_column
 | 
						|
      end
 | 
						|
 | 
						|
      migration.rename_column_concurrently :_test_table, :original, :renamed
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the helper is called repeatedly' do
 | 
						|
      before do
 | 
						|
        migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'does not make repeated attempts to cleanup' do
 | 
						|
        expect(migration).not_to receive(:remove_column)
 | 
						|
 | 
						|
        expect do
 | 
						|
          migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
        end.not_to raise_error
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when the renamed column exists' do
 | 
						|
      let(:triggers) do
 | 
						|
        [
 | 
						|
          ['trigger_020dbcb8cdd0', 'function_for_trigger_020dbcb8cdd0', before: 'insert'],
 | 
						|
          ['trigger_6edaca641d03', 'function_for_trigger_6edaca641d03', before: 'update'],
 | 
						|
          ['trigger_a3fb9f3add34', 'function_for_trigger_a3fb9f3add34', before: 'update']
 | 
						|
        ]
 | 
						|
      end
 | 
						|
 | 
						|
      it 'removes the sync triggers and renamed columns' do
 | 
						|
        triggers.each do |(trigger_name, function_name, event)|
 | 
						|
          expect_function_to_exist(function_name)
 | 
						|
          expect_valid_function_trigger(:_test_table, trigger_name, function_name, event)
 | 
						|
        end
 | 
						|
 | 
						|
        expect(migration.column_exists?(:_test_table, added_column)).to eq(true)
 | 
						|
 | 
						|
        migration.public_send(operation, :_test_table, :original, :renamed)
 | 
						|
 | 
						|
        expect(migration.column_exists?(:_test_table, added_column)).to eq(false)
 | 
						|
 | 
						|
        triggers.each do |(trigger_name, function_name, _)|
 | 
						|
          expect_trigger_not_to_exist(:_test_table, trigger_name)
 | 
						|
          expect_function_not_to_exist(function_name)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#undo_rename_column_concurrently' do
 | 
						|
    it_behaves_like 'Cleaning up from renaming a column' do
 | 
						|
      let(:operation) { :undo_rename_column_concurrently }
 | 
						|
      let(:added_column) { :renamed }
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#cleanup_concurrent_column_rename' do
 | 
						|
    it_behaves_like 'Cleaning up from renaming a column' do
 | 
						|
      let(:operation) { :cleanup_concurrent_column_rename }
 | 
						|
      let(:added_column) { :original }
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#create_table' do
 | 
						|
    let(:table_name) { :_test_table }
 | 
						|
    let(:column_attributes) do
 | 
						|
      [
 | 
						|
        { name: 'id',         sql_type: 'bigint',                   null: false, default: nil    },
 | 
						|
        { name: 'created_at', sql_type: 'timestamp with time zone', null: false, default: nil    },
 | 
						|
        { name: 'updated_at', sql_type: 'timestamp with time zone', null: false, default: nil    },
 | 
						|
        { name: 'some_id',    sql_type: 'integer',                  null: false, default: nil    },
 | 
						|
        { name: 'active',     sql_type: 'boolean',                  null: false, default: 'true' },
 | 
						|
        { name: 'name',       sql_type: 'text',                     null: true,  default: nil    }
 | 
						|
      ]
 | 
						|
    end
 | 
						|
 | 
						|
    context 'using a limit: attribute on .text' do
 | 
						|
      it 'creates the table as expected' do
 | 
						|
        migration.create_table table_name do |t|
 | 
						|
          t.timestamps_with_timezone
 | 
						|
          t.integer :some_id, null: false
 | 
						|
          t.boolean :active, null: false, default: true
 | 
						|
          t.text :name, limit: 100
 | 
						|
        end
 | 
						|
 | 
						|
        expect_table_columns_to_match(column_attributes, table_name)
 | 
						|
        expect_check_constraint(table_name, 'check_e9982cf9da', 'char_length(name) <= 100')
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#with_lock_retries' do
 | 
						|
    let(:model) do
 | 
						|
      ActiveRecord::Migration.new.extend(described_class)
 | 
						|
    end
 | 
						|
 | 
						|
    let(:buffer) { StringIO.new }
 | 
						|
    let(:in_memory_logger) { Gitlab::JsonLogger.new(buffer) }
 | 
						|
    let(:env) { { 'DISABLE_LOCK_RETRIES' => 'true' } }
 | 
						|
 | 
						|
    it 'sets the migration class name in the logs' do
 | 
						|
      model.with_lock_retries(env: env, logger: in_memory_logger) {}
 | 
						|
 | 
						|
      buffer.rewind
 | 
						|
      expect(buffer.read).to include("\"class\":\"#{model.class}\"")
 | 
						|
    end
 | 
						|
 | 
						|
    where(raise_on_exhaustion: [true, false])
 | 
						|
 | 
						|
    with_them do
 | 
						|
      it 'sets raise_on_exhaustion as requested' do
 | 
						|
        with_lock_retries = double
 | 
						|
        expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
 | 
						|
        expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: raise_on_exhaustion)
 | 
						|
 | 
						|
        model.with_lock_retries(env: env, logger: in_memory_logger, raise_on_exhaustion: raise_on_exhaustion) {}
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    it 'does not raise on exhaustion by default' do
 | 
						|
      with_lock_retries = double
 | 
						|
      expect(Gitlab::Database::WithLockRetries).to receive(:new).and_return(with_lock_retries)
 | 
						|
      expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
 | 
						|
 | 
						|
      model.with_lock_retries(env: env, logger: in_memory_logger) {}
 | 
						|
    end
 | 
						|
 | 
						|
    it 'defaults to disallowing subtransactions' do
 | 
						|
      with_lock_retries = double
 | 
						|
      expect(Gitlab::Database::WithLockRetries).to receive(:new).with(hash_including(allow_savepoints: false)).and_return(with_lock_retries)
 | 
						|
      expect(with_lock_retries).to receive(:run).with(raise_on_exhaustion: false)
 | 
						|
 | 
						|
      model.with_lock_retries(env: env, logger: in_memory_logger) {}
 | 
						|
    end
 | 
						|
 | 
						|
    context 'when in transaction' do
 | 
						|
      before do
 | 
						|
        allow(model).to receive(:transaction_open?).and_return(true)
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when lock retries are enabled' do
 | 
						|
        before do
 | 
						|
          allow(model).to receive(:enable_lock_retries?).and_return(true)
 | 
						|
        end
 | 
						|
 | 
						|
        it 'does not use Gitlab::Database::WithLockRetries and executes the provided block directly' do
 | 
						|
          expect(Gitlab::Database::WithLockRetries).not_to receive(:new)
 | 
						|
 | 
						|
          expect(model.with_lock_retries(env: env, logger: in_memory_logger) { :block_result }).to eq(:block_result)
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      context 'when lock retries are not enabled' do
 | 
						|
        before do
 | 
						|
          allow(model).to receive(:enable_lock_retries?).and_return(false)
 | 
						|
        end
 | 
						|
 | 
						|
        it 'raises an error' do
 | 
						|
          expect { model.with_lock_retries(env: env, logger: in_memory_logger) {} }.to raise_error /can not be run inside an already open transaction/
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  describe '#truncate_tables!' do
 | 
						|
    before do
 | 
						|
      ApplicationRecord.connection.execute(<<~SQL)
 | 
						|
        CREATE TABLE _test_gitlab_main_table (id serial primary key);
 | 
						|
        CREATE TABLE _test_gitlab_main_table2 (id serial primary key);
 | 
						|
 | 
						|
        INSERT INTO _test_gitlab_main_table DEFAULT VALUES;
 | 
						|
        INSERT INTO _test_gitlab_main_table2 DEFAULT VALUES;
 | 
						|
      SQL
 | 
						|
 | 
						|
      Ci::ApplicationRecord.connection.execute(<<~SQL)
 | 
						|
        CREATE TABLE _test_gitlab_ci_table (id serial primary key);
 | 
						|
      SQL
 | 
						|
    end
 | 
						|
 | 
						|
    it 'truncates the table' do
 | 
						|
      expect(migration).to receive(:execute).with('TRUNCATE TABLE "_test_gitlab_main_table"').and_call_original
 | 
						|
 | 
						|
      expect { migration.truncate_tables!('_test_gitlab_main_table') }
 | 
						|
        .to change { ApplicationRecord.connection.select_value('SELECT count(1) from _test_gitlab_main_table') }.to(0)
 | 
						|
    end
 | 
						|
 | 
						|
    it 'truncates multiple tables' do
 | 
						|
      expect(migration).to receive(:execute).with('TRUNCATE TABLE "_test_gitlab_main_table", "_test_gitlab_main_table2"').and_call_original
 | 
						|
 | 
						|
      expect { migration.truncate_tables!('_test_gitlab_main_table', '_test_gitlab_main_table2') }
 | 
						|
        .to change { ApplicationRecord.connection.select_value('SELECT count(1) from _test_gitlab_main_table') }.to(0)
 | 
						|
        .and change { ApplicationRecord.connection.select_value('SELECT count(1) from _test_gitlab_main_table2') }.to(0)
 | 
						|
    end
 | 
						|
 | 
						|
    it 'raises an ArgumentError if truncating multiple gitlab_schema' do
 | 
						|
      expect do
 | 
						|
        migration.truncate_tables!('_test_gitlab_main_table', '_test_gitlab_ci_table')
 | 
						|
      end.to raise_error(ArgumentError, /one `gitlab_schema`/)
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with multiple databases' do
 | 
						|
      before do
 | 
						|
        skip_if_shared_database(:ci)
 | 
						|
      end
 | 
						|
 | 
						|
      context 'for ci database' do
 | 
						|
        before do
 | 
						|
          migration.instance_variable_set :@connection, Ci::ApplicationRecord.connection
 | 
						|
        end
 | 
						|
 | 
						|
        it 'skips the TRUNCATE statement tables not in schema for connection' do
 | 
						|
          expect(migration).not_to receive(:execute)
 | 
						|
 | 
						|
          migration.truncate_tables!('_test_gitlab_main_table')
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      context 'for main database' do
 | 
						|
        before do
 | 
						|
          migration.instance_variable_set :@connection, ApplicationRecord.connection
 | 
						|
        end
 | 
						|
 | 
						|
        it 'executes a TRUNCATE statement' do
 | 
						|
          expect(migration).to receive(:execute).with('TRUNCATE TABLE "_test_gitlab_main_table"')
 | 
						|
 | 
						|
          migration.truncate_tables!('_test_gitlab_main_table')
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    context 'with single database' do
 | 
						|
      before do
 | 
						|
        skip_if_database_exists(:ci)
 | 
						|
      end
 | 
						|
 | 
						|
      it 'executes a TRUNCATE statement' do
 | 
						|
        expect(migration).to receive(:execute).with('TRUNCATE TABLE "_test_gitlab_main_table"')
 | 
						|
 | 
						|
        migration.truncate_tables!('_test_gitlab_main_table')
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |