Welcome to mirror list, hosted at ThFree Co, Russian Federation.

truncate_legacy_tables_rake_spec.rb « db « gitlab « tasks « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 940bb9baa603b873830cdb37e91aa46877350802 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'gitlab:db:truncate_legacy_tables', :silence_stdout, :reestablished_active_record_base,
               :suppress_gitlab_schemas_validate_connection, feature_category: :cell do
  let(:main_connection) { ApplicationRecord.connection }
  let(:ci_connection) { Ci::ApplicationRecord.connection }
  let(:test_gitlab_main_table) { '_test_gitlab_main_table' }
  let(:test_gitlab_ci_table) { '_test_gitlab_ci_table' }

  before(:all) do
    Rake.application.rake_require 'active_record/railties/databases'
    Rake.application.rake_require 'tasks/seed_fu'
    Rake.application.rake_require 'tasks/gitlab/db/validate_config'
    Rake.application.rake_require 'tasks/gitlab/db/truncate_legacy_tables'
  end

  before do
    skip_if_shared_database(:ci)

    execute_on_each_database(<<~SQL)
       CREATE TABLE #{test_gitlab_main_table} (id integer NOT NULL);
       INSERT INTO #{test_gitlab_main_table} VALUES(generate_series(1, 50));
    SQL
    execute_on_each_database(<<~SQL)
       CREATE TABLE #{test_gitlab_ci_table} (id integer NOT NULL);
       INSERT INTO #{test_gitlab_ci_table} VALUES(generate_series(1, 50));
    SQL

    allow(Gitlab::Database::GitlabSchema).to receive(:tables_to_schema).and_return(
      {
        test_gitlab_main_table => :gitlab_main,
        test_gitlab_ci_table => :gitlab_ci
      }
    )
  end

  shared_examples 'truncating legacy tables' do
    context 'when tables are not locked for writes' do
      it 'raises an error when trying to truncate the tables' do
        error_message = /is not locked for writes. Run the rake task gitlab:db:lock_writes first/
        expect { truncate_legacy_tables }.to raise_error(error_message)
      end
    end

    context 'when tables are locked for writes' do
      before do
        # Locking ci table on the main database
        Gitlab::Database::LockWritesManager.new(
          table_name: test_gitlab_ci_table,
          connection: main_connection,
          database_name: "main",
          with_retries: false
        ).lock_writes

        # Locking main table on the ci database
        Gitlab::Database::LockWritesManager.new(
          table_name: test_gitlab_main_table,
          connection: ci_connection,
          database_name: "ci",
          with_retries: false
        ).lock_writes
      end

      it 'calls TablesTruncate with the correct parameters and default minimum batch size' do
        expect(Gitlab::Database::TablesTruncate).to receive(:new).with(
          database_name: database_name,
          min_batch_size: 5,
          logger: anything,
          dry_run: false,
          until_table: nil
        ).and_call_original

        truncate_legacy_tables
      end

      it 'truncates the legacy table' do
        expect do
          truncate_legacy_tables
        end.to change { connection.select_value("SELECT count(*) from #{legacy_table}") }.from(50).to(0)
      end

      it 'does not truncate the table that belongs to the connection schema' do
        expect do
          truncate_legacy_tables
        end.not_to change { connection.select_value("SELECT count(*) from #{active_table}") }
      end

      context 'when running in dry_run mode' do
        before do
          stub_env('DRY_RUN', 'true')
        end

        it 'does not truncate any tables' do
          expect do
            truncate_legacy_tables
          end.not_to change { connection.select_value("SELECT count(*) from #{legacy_table}") }
        end

        it 'prints the truncation sql statement to the output' do
          expect do
            truncate_legacy_tables
          end.to output(/TRUNCATE TABLE #{legacy_table} RESTRICT/).to_stdout
        end
      end

      context 'when passing until_table parameter via environment variable' do
        before do
          stub_env('UNTIL_TABLE', legacy_table)
        end

        it 'sends the table name to TablesTruncate' do
          expect(Gitlab::Database::TablesTruncate).to receive(:new).with(
            database_name: database_name,
            min_batch_size: 5,
            logger: anything,
            dry_run: false,
            until_table: legacy_table
          ).and_call_original

          truncate_legacy_tables
        end
      end
    end
  end

  context 'when truncating ci tables on the main database' do
    subject(:truncate_legacy_tables) { run_rake_task('gitlab:db:truncate_legacy_tables:main') }

    let(:connection) { ApplicationRecord.connection }
    let(:database_name) { 'main' }
    let(:active_table) { test_gitlab_main_table }
    let(:legacy_table) { test_gitlab_ci_table }

    it_behaves_like 'truncating legacy tables'
  end

  context 'when truncating main tables on the ci database' do
    subject(:truncate_legacy_tables) { run_rake_task('gitlab:db:truncate_legacy_tables:ci') }

    let(:connection) { Ci::ApplicationRecord.connection }
    let(:database_name) { 'ci' }
    let(:active_table) { test_gitlab_ci_table }
    let(:legacy_table) { test_gitlab_main_table }

    it_behaves_like 'truncating legacy tables'
  end
end