summaryrefslogtreecommitdiff
path: root/spec/workers/container_registry/cleanup_worker_spec.rb
blob: 955d2175085b3a462793ca04f4e87dbc308029ad (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
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe ContainerRegistry::CleanupWorker, :aggregate_failures, feature_category: :container_registry do
  let(:worker) { described_class.new }

  describe '#perform' do
    let_it_be_with_reload(:container_repository) { create(:container_repository) }

    subject(:perform) { worker.perform }

    context 'with no delete scheduled container repositories' do
      it "doesn't enqueue delete container repository jobs" do
        expect(ContainerRegistry::DeleteContainerRepositoryWorker).not_to receive(:perform_with_capacity)

        perform
      end
    end

    context 'with delete scheduled container repositories' do
      before do
        container_repository.delete_scheduled!
      end

      it 'enqueues delete container repository jobs' do
        expect(ContainerRegistry::DeleteContainerRepositoryWorker).to receive(:perform_with_capacity)

        perform
      end
    end

    context 'with stale delete ongoing container repositories' do
      let(:delete_started_at) { (described_class::STALE_DELETE_THRESHOLD + 5.minutes).ago }

      before do
        container_repository.update!(status: :delete_ongoing, delete_started_at: delete_started_at)
      end

      it 'resets them and enqueue delete container repository jobs' do
        expect(ContainerRegistry::DeleteContainerRepositoryWorker).to receive(:perform_with_capacity)

        expect { perform }
          .to change { container_repository.reload.status }.from('delete_ongoing').to('delete_scheduled')
                .and change { container_repository.reload.delete_started_at }.to(nil)
      end
    end

    context 'with stale ongoing repair details' do
      let_it_be(:stale_updated_at) { (described_class::STALE_REPAIR_DETAIL_THRESHOLD + 5.minutes).ago }
      let_it_be(:recent_updated_at) { (described_class::STALE_REPAIR_DETAIL_THRESHOLD - 5.minutes).ago }
      let_it_be(:old_repair_detail) { create(:container_registry_data_repair_detail, updated_at: stale_updated_at) }
      let_it_be(:new_repair_detail) { create(:container_registry_data_repair_detail, updated_at: recent_updated_at) }

      it 'deletes them' do
        expect { perform }.to change { ContainerRegistry::DataRepairDetail.count }.from(2).to(1)
        expect(ContainerRegistry::DataRepairDetail.all).to contain_exactly(new_repair_detail)
      end
    end

    shared_examples 'does not enqueue record repair detail jobs' do
      it 'does not enqueue record repair detail jobs' do
        expect(ContainerRegistry::RecordDataRepairDetailWorker).not_to receive(:perform_with_capacity)

        perform
      end
    end

    context 'when on gitlab.com', :saas do
      context 'when the gitlab api is supported' do
        let(:relation) { instance_double(ActiveRecord::Relation) }

        before do
          allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(true)
          allow(Project).to receive(:pending_data_repair_analysis).and_return(relation)
        end

        context 'when there are pending projects to analyze' do
          before do
            allow(relation).to receive(:exists?).and_return(true)
          end

          it "enqueues record repair detail jobs" do
            expect(ContainerRegistry::RecordDataRepairDetailWorker).to receive(:perform_with_capacity)

            perform
          end
        end

        context 'when there are no pending projects to analyze' do
          before do
            allow(relation).to receive(:exists?).and_return(false)
          end

          it_behaves_like 'does not enqueue record repair detail jobs'
        end
      end

      context 'when the Gitlab API is not supported' do
        before do
          allow(ContainerRegistry::GitlabApiClient).to receive(:supports_gitlab_api?).and_return(false)
        end

        it_behaves_like 'does not enqueue record repair detail jobs'
      end
    end

    context 'when not on Gitlab.com' do
      it_behaves_like 'does not enqueue record repair detail jobs'
    end

    context 'when registry_data_repair_worker feature is disabled' do
      before do
        stub_feature_flags(registry_data_repair_worker: false)
      end

      it_behaves_like 'does not enqueue record repair detail jobs'
    end

    context 'for counts logging' do
      let_it_be(:delete_started_at) { (described_class::STALE_DELETE_THRESHOLD + 5.minutes).ago }
      let_it_be(:stale_delete_container_repository) do
        create(:container_repository, :status_delete_ongoing, delete_started_at: delete_started_at)
      end

      before do
        container_repository.delete_scheduled!
      end

      it 'logs the counts' do
        expect(worker).to receive(:log_extra_metadata_on_done).with(:delete_scheduled_container_repositories_count, 1)
        expect(worker).to receive(:log_extra_metadata_on_done).with(:stale_delete_container_repositories_count, 1)

        perform
      end
    end
  end
end