summaryrefslogtreecommitdiff
path: root/spec/tasks/gitlab/db/decomposition/rollback/bump_ci_sequences_rake_spec.rb
blob: b03e964ce8719b3c2706f8de37f29c26bff85aab (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
# frozen_string_literal: true

require 'rake_helper'

RSpec.describe 'gitlab:db:decomposition:rollback:bump_ci_sequences', :silence_stdout,
               :suppress_gitlab_schemas_validate_connection do
  before :all do
    Rake.application.rake_require 'tasks/gitlab/db/decomposition/rollback/bump_ci_sequences'

    # empty task as env is already loaded
    Rake::Task.define_task :environment
  end

  let(:expected_error_message) do
    <<-EOS.strip_heredoc
      Please specify a positive integer `increase_by` value
      Example: rake gitlab:db:decomposition:rollback:bump_ci_sequences[100000]
    EOS
  end

  let(:main_sequence_name) { 'issues_id_seq' }
  let(:ci_sequence_name) { 'ci_build_needs_id_seq' }

  # This is just to make sure that all of the sequences start with `is_called=True`
  # which means that the next call to nextval() is going to increment the sequence.
  # To give predictable test results.
  before do
    ApplicationRecord.connection.select_value("select nextval($1)", nil, [ci_sequence_name])
  end

  context 'when passing wrong argument' do
    it 'will print an error message and exit when passing no argument' do
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences')
      end.to raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
      .and output(expected_error_message).to_stdout
    end

    it 'will print an error message and exit when passing a non positive integer value' do
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '-5')
      end.to raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
      .and output(expected_error_message).to_stdout
    end
  end

  context 'when bumping the ci sequences' do
    it 'changes ci sequences by the passed argument `increase_by` value on the main database' do
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '15')
      end.to change {
        last_value_of_sequence(ApplicationRecord.connection, ci_sequence_name)
      }.by(16) # the +1 is because the sequence has is_called = true
    end

    it 'will still increase the value of sequences that have is_called = False' do
      # see `is_called`: https://www.postgresql.org/docs/12/functions-sequence.html
      # choosing a new arbitrary value for the sequence
      new_value = last_value_of_sequence(ApplicationRecord.connection, ci_sequence_name) + 1000
      ApplicationRecord.connection.select_value("select setval($1, $2, false)", nil, [ci_sequence_name, new_value])
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '15')
      end.to change {
        last_value_of_sequence(ApplicationRecord.connection, ci_sequence_name)
      }.by(15)
    end

    it 'resets the INCREMENT value of the sequences back to 1 for the following calls to nextval()' do
      run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '15')
      value_1 = ApplicationRecord.connection.select_value("select nextval($1)", nil, [ci_sequence_name])
      value_2 = ApplicationRecord.connection.select_value("select nextval($1)", nil, [ci_sequence_name])
      expect(value_2 - value_1).to eq(1)
    end

    it 'does not change the sequences on the gitlab_main tables' do
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '10')
      end.to change {
        last_value_of_sequence(ApplicationRecord.connection, main_sequence_name)
      }.by(0)
      .and change {
        last_value_of_sequence(ApplicationRecord.connection, ci_sequence_name)
      }.by(11) # the +1 is because the sequence has is_called = true
    end
  end

  context 'when multiple databases' do
    before do
      skip_if_multiple_databases_not_setup
    end

    it 'does not change ci sequences on the ci database' do
      expect do
        run_rake_task('gitlab:db:decomposition:rollback:bump_ci_sequences', '10')
      end.to change {
        last_value_of_sequence(Ci::ApplicationRecord.connection, ci_sequence_name)
      }.by(0)
    end
  end
end

def last_value_of_sequence(connection, sequence_name)
  connection.select_value("select last_value from #{sequence_name}")
end