Commit 6a96e3a5 authored by James Fargher's avatar James Fargher

Merge branch '267546-parent-worker' into 'master'

Update container expiration policy worker [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!56962
parents e3df0b6e 23e0ed66
...@@ -29,13 +29,15 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo ...@@ -29,13 +29,15 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo
def perform_throttled def perform_throttled
try_obtain_lease do try_obtain_lease do
with_runnable_policy do |policy| unless loopless_enabled?
ContainerExpirationPolicy.transaction do with_runnable_policy do |policy|
policy.schedule_next_run! ContainerExpirationPolicy.transaction do
ContainerRepository.for_project_id(policy.id) policy.schedule_next_run!
.each_batch do |relation| ContainerRepository.for_project_id(policy.id)
relation.update_all(expiration_policy_cleanup_status: :cleanup_scheduled) .each_batch do |relation|
end relation.update_all(expiration_policy_cleanup_status: :cleanup_scheduled)
end
end
end end
end end
...@@ -75,6 +77,10 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo ...@@ -75,6 +77,10 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo
Feature.enabled?(:container_registry_expiration_policies_throttling) Feature.enabled?(:container_registry_expiration_policies_throttling)
end end
def loopless_enabled?
Feature.enabled?(:container_registry_expiration_policies_loopless)
end
def lease_timeout def lease_timeout
5.hours 5.hours
end end
......
---
name: container_registry_expiration_policies_loopless
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56962
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/325273
milestone: '13.11'
type: development
group: group::package
default_enabled: false
...@@ -11,7 +11,7 @@ RSpec.describe ContainerExpirationPolicyWorker do ...@@ -11,7 +11,7 @@ RSpec.describe ContainerExpirationPolicyWorker do
describe '#perform' do describe '#perform' do
subject { worker.perform } subject { worker.perform }
RSpec.shared_examples 'not executing any policy' do shared_examples 'not executing any policy' do
it 'does not run any policy' do it 'does not run any policy' do
expect(ContainerExpirationPolicyService).not_to receive(:new) expect(ContainerExpirationPolicyService).not_to receive(:new)
...@@ -19,6 +19,21 @@ RSpec.describe ContainerExpirationPolicyWorker do ...@@ -19,6 +19,21 @@ RSpec.describe ContainerExpirationPolicyWorker do
end end
end end
shared_examples 'handling a taken exclusive lease' do
context 'with exclusive lease taken' do
before do
stub_exclusive_lease_taken(worker.lease_key, timeout: 5.hours)
end
it 'does not do anything' do
expect(ContainerExpirationPolicies::CleanupContainerRepositoryWorker).not_to receive(:perform_with_capacity)
expect(worker).not_to receive(:runnable_policies)
expect { subject }.not_to change { ContainerRepository.cleanup_scheduled.count }
end
end
end
context 'With no container expiration policies' do context 'With no container expiration policies' do
it 'does not execute any policies' do it 'does not execute any policies' do
expect(ContainerRepository).not_to receive(:for_project_id) expect(ContainerRepository).not_to receive(:for_project_id)
...@@ -27,66 +42,86 @@ RSpec.describe ContainerExpirationPolicyWorker do ...@@ -27,66 +42,86 @@ RSpec.describe ContainerExpirationPolicyWorker do
end end
end end
context 'with container expiration policies' do context 'with throttling enabled' do
let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :runnable) } before do
let_it_be(:container_repository) { create(:container_repository, project: container_expiration_policy.project) } stub_feature_flags(container_registry_expiration_policies_throttling: true)
end
context 'with a valid container expiration policy' do context 'with loopless disabled' do
it 'schedules the next run' do before do
expect { subject }.to change { container_expiration_policy.reload.next_run_at } stub_feature_flags(container_registry_expiration_policies_loopless: false)
end end
it 'marks the container repository as scheduled for cleanup' do context 'with container expiration policies' do
expect { subject }.to change { container_repository.reload.cleanup_scheduled? }.from(false).to(true) let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :runnable) }
expect(ContainerRepository.cleanup_scheduled.count).to eq(1) let_it_be(:container_repository) { create(:container_repository, project: container_expiration_policy.project) }
end
it 'calls the limited capacity worker' do before do
expect(ContainerExpirationPolicies::CleanupContainerRepositoryWorker).to receive(:perform_with_capacity) expect(worker).to receive(:with_runnable_policy).and_call_original
end
subject context 'with a valid container expiration policy' do
end it 'schedules the next run' do
end expect { subject }.to change { container_expiration_policy.reload.next_run_at }
end
context 'with a disabled container expiration policy' do it 'marks the container repository as scheduled for cleanup' do
before do expect { subject }.to change { container_repository.reload.cleanup_scheduled? }.from(false).to(true)
container_expiration_policy.disable! expect(ContainerRepository.cleanup_scheduled.count).to eq(1)
end end
it 'does not run the policy' do it 'calls the limited capacity worker' do
expect(ContainerRepository).not_to receive(:for_project_id) expect(ContainerExpirationPolicies::CleanupContainerRepositoryWorker).to receive(:perform_with_capacity)
expect { subject }.not_to change { ContainerRepository.cleanup_scheduled.count } subject
end end
end end
context 'with an invalid container expiration policy' do context 'with a disabled container expiration policy' do
let(:user) { container_expiration_policy.project.owner } before do
container_expiration_policy.disable!
end
before do it 'does not run the policy' do
container_expiration_policy.update_column(:name_regex, '*production') expect(ContainerRepository).not_to receive(:for_project_id)
end
it 'disables the policy and tracks an error' do expect { subject }.not_to change { ContainerRepository.cleanup_scheduled.count }
expect(ContainerRepository).not_to receive(:for_project_id) end
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(instance_of(described_class::InvalidPolicyError), container_expiration_policy_id: container_expiration_policy.id) end
expect { subject }.to change { container_expiration_policy.reload.enabled }.from(true).to(false) context 'with an invalid container expiration policy' do
expect(ContainerRepository.cleanup_scheduled).to be_empty let(:user) { container_expiration_policy.project.owner }
before do
container_expiration_policy.update_column(:name_regex, '*production')
end
it 'disables the policy and tracks an error' do
expect(ContainerRepository).not_to receive(:for_project_id)
expect(Gitlab::ErrorTracking).to receive(:log_exception).with(instance_of(described_class::InvalidPolicyError), container_expiration_policy_id: container_expiration_policy.id)
expect { subject }.to change { container_expiration_policy.reload.enabled }.from(true).to(false)
expect(ContainerRepository.cleanup_scheduled).to be_empty
end
end
end end
end
end
context 'with exclusive lease taken' do it_behaves_like 'handling a taken exclusive lease'
before do
stub_exclusive_lease_taken(worker.lease_key, timeout: 5.hours)
end end
it 'does not execute any policy' do context 'with loopless enabled' do
expect(ContainerExpirationPolicies::CleanupContainerRepositoryWorker).not_to receive(:perform_with_capacity) before do
expect(worker).not_to receive(:runnable_policies) stub_feature_flags(container_registry_expiration_policies_loopless: true)
expect(worker).not_to receive(:with_runnable_policy)
end
expect { subject }.not_to change { ContainerRepository.cleanup_scheduled.count } it 'calls the limited capacity worker' do
expect(ContainerExpirationPolicies::CleanupContainerRepositoryWorker).to receive(:perform_with_capacity)
subject
end
it_behaves_like 'handling a taken exclusive lease'
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment