summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/database/background_migration_job_spec.rb
blob: 40f47325be3b8db69b9180f46ccc5562692116ec (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::Database::BackgroundMigrationJob do
  it_behaves_like 'having unique enum values'

  describe '.for_migration_execution' do
    let!(:job1) { create(:background_migration_job) }
    let!(:job2) { create(:background_migration_job, arguments: ['hi', 2]) }
    let!(:job3) { create(:background_migration_job, class_name: 'OtherJob', arguments: ['hi', 2]) }

    it 'returns jobs matching class_name and arguments' do
      relation = described_class.for_migration_execution('TestJob', ['hi', 2])

      expect(relation.count).to eq(1)
      expect(relation.first).to have_attributes(class_name: 'TestJob', arguments: ['hi', 2])
    end

    it 'normalizes class names by removing leading ::' do
      relation = described_class.for_migration_execution('::TestJob', ['hi', 2])

      expect(relation.count).to eq(1)
      expect(relation.first).to have_attributes(class_name: 'TestJob', arguments: ['hi', 2])
    end
  end

  describe '.for_partitioning_migration' do
    let!(:job1) { create(:background_migration_job, arguments: [1, 100, 'other_table']) }
    let!(:job2) { create(:background_migration_job, arguments: [1, 100, 'audit_events']) }
    let!(:job3) { create(:background_migration_job, class_name: 'OtherJob', arguments: [1, 100, 'audit_events']) }

    it 'returns jobs matching class_name and the table_name job argument' do
      relation = described_class.for_partitioning_migration('TestJob', 'audit_events')

      expect(relation.count).to eq(1)
      expect(relation.first).to have_attributes(class_name: 'TestJob', arguments: [1, 100, 'audit_events'])
    end

    it 'normalizes class names by removing leading ::' do
      relation = described_class.for_partitioning_migration('::TestJob', 'audit_events')

      expect(relation.count).to eq(1)
      expect(relation.first).to have_attributes(class_name: 'TestJob', arguments: [1, 100, 'audit_events'])
    end
  end

  describe '.mark_all_as_succeeded' do
    let!(:job1) { create(:background_migration_job, arguments: [1, 100]) }
    let!(:job2) { create(:background_migration_job, arguments: [1, 100]) }
    let!(:job3) { create(:background_migration_job, arguments: [101, 200]) }
    let!(:job4) { create(:background_migration_job, class_name: 'OtherJob', arguments: [1, 100]) }

    it 'marks all matching jobs as succeeded' do
      expect { described_class.mark_all_as_succeeded('TestJob', [1, 100]) }
        .to change { described_class.succeeded.count }.from(0).to(2)

      expect(job1.reload).to be_succeeded
      expect(job2.reload).to be_succeeded
      expect(job3.reload).to be_pending
      expect(job4.reload).to be_pending
    end

    it 'normalizes class_names by removing leading ::' do
      expect { described_class.mark_all_as_succeeded('::TestJob', [1, 100]) }
        .to change { described_class.succeeded.count }.from(0).to(2)

      expect(job1.reload).to be_succeeded
      expect(job2.reload).to be_succeeded
      expect(job3.reload).to be_pending
      expect(job4.reload).to be_pending
    end

    context 'when previous matching jobs have already succeeded' do
      let(:initial_time) { Time.now.round }
      let!(:job1) { create(:background_migration_job, :succeeded, created_at: initial_time, updated_at: initial_time) }

      it 'does not update non-pending jobs' do
        Timecop.freeze(initial_time + 1.day) do
          expect { described_class.mark_all_as_succeeded('TestJob', [1, 100]) }
            .to change { described_class.succeeded.count }.from(1).to(2)
        end

        expect(job1.reload.updated_at).to eq(initial_time)
        expect(job2.reload).to be_succeeded
        expect(job3.reload).to be_pending
        expect(job4.reload).to be_pending
      end
    end
  end

  describe '#class_name=' do
    context 'when the class_name is given without the leading ::' do
      it 'sets the class_name to the given value' do
        job = described_class.new(class_name: 'TestJob')

        expect(job.class_name).to eq('TestJob')
      end
    end

    context 'when the class_name is given with the leading ::' do
      it 'removes the leading :: when setting the class_name' do
        job = described_class.new(class_name: '::TestJob')

        expect(job.class_name).to eq('TestJob')
      end
    end

    context 'when the value is nil' do
      it 'sets the class_name to nil' do
        job = described_class.new(class_name: nil)

        expect(job.class_name).to be_nil
      end
    end

    context 'when the values is blank' do
      it 'sets the class_name to the given value' do
        job = described_class.new(class_name: '')

        expect(job.class_name).to eq('')
      end
    end
  end
end