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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-01-20 12:16:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-20 12:16:11 +0300
commitedaa33dee2ff2f7ea3fac488d41558eb5f86d68c (patch)
tree11f143effbfeba52329fb7afbd05e6e2a3790241 /spec/workers
parentd8a5691316400a0f7ec4f83832698f1988eb27c1 (diff)
Add latest changes from gitlab-org/gitlab@14-7-stable-eev14.7.0-rc42
Diffstat (limited to 'spec/workers')
-rw-r--r--spec/workers/ci/build_finished_worker_spec.rb15
-rw-r--r--spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb32
-rw-r--r--spec/workers/clusters/agents/delete_expired_events_worker_spec.rb30
-rw-r--r--spec/workers/concerns/application_worker_spec.rb67
-rw-r--r--spec/workers/concerns/cluster_agent_queue_spec.rb19
-rw-r--r--spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb36
-rw-r--r--spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb4
-rw-r--r--spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb12
-rw-r--r--spec/workers/deployments/hooks_worker_spec.rb4
-rw-r--r--spec/workers/email_receiver_worker_spec.rb78
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb3
-rw-r--r--spec/workers/loose_foreign_keys/cleanup_worker_spec.rb28
-rw-r--r--spec/workers/merge_requests/update_head_pipeline_worker_spec.rb138
-rw-r--r--spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb30
-rw-r--r--spec/workers/packages/cleanup_package_file_worker_spec.rb64
-rw-r--r--spec/workers/packages/cleanup_package_registry_worker_spec.rb57
-rw-r--r--spec/workers/pages_update_configuration_worker_spec.rb53
-rw-r--r--spec/workers/pages_worker_spec.rb16
-rw-r--r--spec/workers/purge_dependency_proxy_cache_worker_spec.rb6
-rw-r--r--spec/workers/web_hook_worker_spec.rb9
20 files changed, 502 insertions, 199 deletions
diff --git a/spec/workers/ci/build_finished_worker_spec.rb b/spec/workers/ci/build_finished_worker_spec.rb
index 9096b0d2ba9..839723ac2fc 100644
--- a/spec/workers/ci/build_finished_worker_spec.rb
+++ b/spec/workers/ci/build_finished_worker_spec.rb
@@ -50,6 +50,21 @@ RSpec.describe Ci::BuildFinishedWorker do
subject
end
+
+ context 'when a build can be auto-retried' do
+ before do
+ allow(build)
+ .to receive(:auto_retry_allowed?)
+ .and_return(true)
+ end
+
+ it 'does not add a todo' do
+ expect(::Ci::MergeRequests::AddTodoWhenBuildFailsWorker)
+ .not_to receive(:perform_async)
+
+ subject
+ end
+ end
end
context 'when build has a chat' do
diff --git a/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb b/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb
new file mode 100644
index 00000000000..0460738f3f2
--- /dev/null
+++ b/spec/workers/ci/job_artifacts/expire_project_build_artifacts_worker_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::JobArtifacts::ExpireProjectBuildArtifactsWorker do
+ let(:worker) { described_class.new }
+ let(:current_time) { Time.current }
+
+ let_it_be(:project) { create(:project) }
+
+ around do |example|
+ freeze_time { example.run }
+ end
+
+ describe '#perform' do
+ it 'executes ExpireProjectArtifactsService service with the project' do
+ expect_next_instance_of(Ci::JobArtifacts::ExpireProjectBuildArtifactsService, project.id, current_time) do |instance|
+ expect(instance).to receive(:execute).and_call_original
+ end
+
+ worker.perform(project.id)
+ end
+
+ context 'when project does not exist' do
+ it 'does nothing' do
+ expect(Ci::JobArtifacts::ExpireProjectBuildArtifactsService).not_to receive(:new)
+
+ worker.perform(non_existing_record_id)
+ end
+ end
+ end
+end
diff --git a/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb b/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb
new file mode 100644
index 00000000000..1a5ca744091
--- /dev/null
+++ b/spec/workers/clusters/agents/delete_expired_events_worker_spec.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::Agents::DeleteExpiredEventsWorker do
+ let(:agent) { create(:cluster_agent) }
+
+ describe '#perform' do
+ let(:agent_id) { agent.id }
+ let(:deletion_service) { double(execute: true) }
+
+ subject { described_class.new.perform(agent_id) }
+
+ it 'calls the deletion service' do
+ expect(deletion_service).to receive(:execute).once
+ expect(Clusters::Agents::DeleteExpiredEventsService).to receive(:new)
+ .with(agent).and_return(deletion_service)
+
+ subject
+ end
+
+ context 'agent no longer exists' do
+ let(:agent_id) { -1 }
+
+ it 'completes without raising an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/workers/concerns/application_worker_spec.rb b/spec/workers/concerns/application_worker_spec.rb
index 7608b5f49a1..85731de2a45 100644
--- a/spec/workers/concerns/application_worker_spec.rb
+++ b/spec/workers/concerns/application_worker_spec.rb
@@ -287,12 +287,6 @@ RSpec.describe ApplicationWorker do
end
context 'different kinds of push_bulk' do
- shared_context 'disable the `sidekiq_push_bulk_in_batches` feature flag' do
- before do
- stub_feature_flags(sidekiq_push_bulk_in_batches: false)
- end
- end
-
shared_context 'set safe limit beyond the number of jobs to be enqueued' do
before do
stub_const("#{described_class}::SAFE_PUSH_BULK_LIMIT", args.count + 1)
@@ -408,27 +402,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'does not schedule the jobs for any specific time'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'logs bulk insertions'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'does not schedule the jobs for any specific time'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'does not schedule the jobs for any specific time'
- end
- end
end
end
@@ -476,26 +449,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'schedules all the jobs at a specific time'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time'
- end
- end
end
end
@@ -575,26 +528,6 @@ RSpec.describe ApplicationWorker do
it_behaves_like 'returns job_id of all enqueued jobs'
it_behaves_like 'schedules all the jobs at a specific time, per batch'
end
-
- context 'when the feature flag `sidekiq_push_bulk_in_batches` is disabled' do
- include_context 'disable the `sidekiq_push_bulk_in_batches` feature flag'
-
- context 'when the number of jobs to be enqueued does not exceed the safe limit' do
- include_context 'set safe limit beyond the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time, per batch'
- end
-
- context 'when the number of jobs to be enqueued exceeds safe limit' do
- include_context 'set safe limit below the number of jobs to be enqueued'
-
- it_behaves_like 'enqueues jobs in one go'
- it_behaves_like 'returns job_id of all enqueued jobs'
- it_behaves_like 'schedules all the jobs at a specific time, per batch'
- end
- end
end
end
end
diff --git a/spec/workers/concerns/cluster_agent_queue_spec.rb b/spec/workers/concerns/cluster_agent_queue_spec.rb
new file mode 100644
index 00000000000..b5189cbd8c8
--- /dev/null
+++ b/spec/workers/concerns/cluster_agent_queue_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ClusterAgentQueue do
+ let(:worker) do
+ Class.new do
+ def self.name
+ 'ExampleWorker'
+ end
+
+ include ApplicationWorker
+ include ClusterAgentQueue
+ end
+ end
+
+ it { expect(worker.queue).to eq('cluster_agent:example') }
+ it { expect(worker.get_feature_category).to eq(:kubernetes_management) }
+end
diff --git a/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb b/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb
new file mode 100644
index 00000000000..95962d4810e
--- /dev/null
+++ b/spec/workers/concerns/packages/cleanup_artifact_worker_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Packages::CleanupArtifactWorker do
+ let_it_be(:worker_class) do
+ Class.new do
+ def self.name
+ 'Gitlab::Foo::Bar::DummyWorker'
+ end
+
+ include ApplicationWorker
+ include ::Packages::CleanupArtifactWorker
+ end
+ end
+
+ let(:worker) { worker_class.new }
+
+ describe '#model' do
+ subject { worker.send(:model) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#log_metadata' do
+ subject { worker.send(:log_metadata) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+
+ describe '#log_cleanup_item' do
+ subject { worker.send(:log_cleanup_item) }
+
+ it { expect { subject }.to raise_error(NotImplementedError) }
+ end
+end
diff --git a/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb b/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
index ed0bdefbdb8..1100f9a7fae 100644
--- a/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
+++ b/spec/workers/dependency_proxy/cleanup_dependency_proxy_worker_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe DependencyProxy::CleanupDependencyProxyWorker do
context 'when there are records to be deleted' do
it_behaves_like 'an idempotent worker' do
it 'queues the cleanup jobs', :aggregate_failures do
- create(:dependency_proxy_blob, :expired)
- create(:dependency_proxy_manifest, :expired)
+ create(:dependency_proxy_blob, :pending_destruction)
+ create(:dependency_proxy_manifest, :pending_destruction)
expect(DependencyProxy::CleanupBlobWorker).to receive(:perform_with_capacity).twice
expect(DependencyProxy::CleanupManifestWorker).to receive(:perform_with_capacity).twice
diff --git a/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb b/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
index b035a2ec0b7..6a2fdfbe8f5 100644
--- a/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
+++ b/spec/workers/dependency_proxy/image_ttl_group_policy_worker_spec.rb
@@ -17,19 +17,19 @@ RSpec.describe DependencyProxy::ImageTtlGroupPolicyWorker do
let_it_be_with_reload(:new_blob) { create(:dependency_proxy_blob, group: group) }
let_it_be_with_reload(:new_manifest) { create(:dependency_proxy_manifest, group: group) }
- it 'updates the old images to expired' do
+ it 'updates the old images to pending_destruction' do
expect { subject }
- .to change { old_blob.reload.status }.from('default').to('expired')
- .and change { old_manifest.reload.status }.from('default').to('expired')
+ .to change { old_blob.reload.status }.from('default').to('pending_destruction')
+ .and change { old_manifest.reload.status }.from('default').to('pending_destruction')
.and not_change { new_blob.reload.status }
.and not_change { new_manifest.reload.status }
end
end
context 'counts logging' do
- let_it_be(:expired_blob) { create(:dependency_proxy_blob, :expired, group: group) }
- let_it_be(:expired_blob2) { create(:dependency_proxy_blob, :expired, group: group) }
- let_it_be(:expired_manifest) { create(:dependency_proxy_manifest, :expired, group: group) }
+ let_it_be(:expired_blob) { create(:dependency_proxy_blob, :pending_destruction, group: group) }
+ let_it_be(:expired_blob2) { create(:dependency_proxy_blob, :pending_destruction, group: group) }
+ let_it_be(:expired_manifest) { create(:dependency_proxy_manifest, :pending_destruction, group: group) }
let_it_be(:processing_blob) { create(:dependency_proxy_blob, status: :processing, group: group) }
let_it_be(:processing_manifest) { create(:dependency_proxy_manifest, status: :processing, group: group) }
let_it_be(:error_blob) { create(:dependency_proxy_blob, status: :error, group: group) }
diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb
index b4a91cff2ac..50ead66cfbf 100644
--- a/spec/workers/deployments/hooks_worker_spec.rb
+++ b/spec/workers/deployments/hooks_worker_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Deployments::HooksWorker do
it 'executes project services for deployment_hooks' do
deployment = create(:deployment, :running)
project = deployment.project
- service = create(:service, type: 'SlackService', project: project, deployment_events: true, active: true)
+ service = create(:integration, type: 'SlackService', project: project, deployment_events: true, active: true)
expect(ProjectServiceWorker).to receive(:perform_async).with(service.id, an_instance_of(Hash))
@@ -23,7 +23,7 @@ RSpec.describe Deployments::HooksWorker do
it 'does not execute an inactive service' do
deployment = create(:deployment, :running)
project = deployment.project
- create(:service, type: 'SlackService', project: project, deployment_events: true, active: false)
+ create(:integration, type: 'SlackService', project: project, deployment_events: true, active: false)
expect(ProjectServiceWorker).not_to receive(:perform_async)
diff --git a/spec/workers/email_receiver_worker_spec.rb b/spec/workers/email_receiver_worker_spec.rb
index 83720ee132b..dba535654a1 100644
--- a/spec/workers/email_receiver_worker_spec.rb
+++ b/spec/workers/email_receiver_worker_spec.rb
@@ -21,87 +21,45 @@ RSpec.describe EmailReceiverWorker, :mailer do
context "when an error occurs" do
before do
allow_any_instance_of(Gitlab::Email::Receiver).to receive(:execute).and_raise(error)
- expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original
end
- context 'when the error is Gitlab::Email::EmptyEmailError' do
+ context 'when error is a processing error' do
let(:error) { Gitlab::Email::EmptyEmailError.new }
- it 'sends out a rejection email' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
+ it 'triggers email failure handler' do
+ expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error|
+ expect(receiver).to be_a(Gitlab::Email::Receiver)
+ expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded)
+ expect(received_error).to be(error)
end
- email = ActionMailer::Base.deliveries.last
- expect(email).not_to be_nil
- expect(email.to).to eq(["jake@adventuretime.ooo"])
- expect(email.subject).to include("Rejected")
- end
-
- it 'strips out the body before passing to EmailRejectionMailer' do
- mail = Mail.new(raw_message)
- mail.body = nil
-
- expect(EmailRejectionMailer).to receive(:rejection).with(anything, mail.encoded, anything).and_call_original
-
described_class.new.perform(raw_message)
end
- end
-
- context 'when the error is Gitlab::Email::AutoGeneratedEmailError' do
- let(:error) { Gitlab::Email::AutoGeneratedEmailError.new }
-
- it 'does not send out any rejection email' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- should_not_email_anyone
- end
- end
- context 'when the error is Gitlab::Email::InvalidAttachment' do
- let(:error) { Gitlab::Email::InvalidAttachment.new("Could not deal with that") }
+ it 'logs the error' do
+ expect(Sidekiq.logger).to receive(:error).with(hash_including('exception.class' => error.class.name)).and_call_original
- it 'reports the error to the sender' do
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- email = ActionMailer::Base.deliveries.last
- expect(email).not_to be_nil
- expect(email.to).to eq(["jake@adventuretime.ooo"])
- expect(email.body.parts.last.to_s).to include("Could not deal with that")
+ described_class.new.perform(raw_message)
end
end
- context 'when the error is ActiveRecord::StatementTimeout' do
+ context 'when error is not a processing error' do
let(:error) { ActiveRecord::StatementTimeout.new("Statement timeout") }
- it 'does not report the error to the sender' do
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original
-
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
+ it 'triggers email failure handler' do
+ expect(Gitlab::Email::FailureHandler).to receive(:handle) do |receiver, received_error|
+ expect(receiver).to be_a(Gitlab::Email::Receiver)
+ expect(receiver.mail.encoded).to eql(Mail::Message.new(raw_message).encoded)
+ expect(received_error).to be(error)
end
- email = ActionMailer::Base.deliveries.last
- expect(email).to be_nil
+ described_class.new.perform(raw_message)
end
- end
-
- context 'when the error is RateLimitedService::RateLimitedError' do
- let(:error) { RateLimitedService::RateLimitedError.new(key: :issues_create, rate_limiter: Gitlab::ApplicationRateLimiter) }
- it 'does not report the error to the sender' do
+ it 'reports the error' do
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(error).and_call_original
- perform_enqueued_jobs do
- described_class.new.perform(raw_message)
- end
-
- email = ActionMailer::Base.deliveries.last
- expect(email).to be_nil
+ described_class.new.perform(raw_message)
end
end
end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 00b6d2635a5..bb4e2981070 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -361,6 +361,7 @@ RSpec.describe 'Every Sidekiq worker' do
'ObjectPool::ScheduleJoinWorker' => 3,
'ObjectStorage::BackgroundMoveWorker' => 5,
'ObjectStorage::MigrateUploadsWorker' => 3,
+ 'Packages::CleanupPackageFileWorker' => 0,
'Packages::Composer::CacheUpdateWorker' => false,
'Packages::Go::SyncPackagesWorker' => 3,
'Packages::Maven::Metadata::SyncWorker' => 3,
@@ -369,7 +370,7 @@ RSpec.describe 'Every Sidekiq worker' do
'PagesDomainSslRenewalWorker' => 3,
'PagesDomainVerificationWorker' => 3,
'PagesTransferWorker' => 3,
- 'PagesUpdateConfigurationWorker' => 3,
+ 'PagesUpdateConfigurationWorker' => 1,
'PagesWorker' => 3,
'PersonalAccessTokens::Groups::PolicyWorker' => 3,
'PersonalAccessTokens::Instance::PolicyWorker' => 3,
diff --git a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
index 3c628d036ff..497f95cf34d 100644
--- a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
+++ b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe LooseForeignKeys::CleanupWorker do
include MigrationsHelpers
+ using RSpec::Parameterized::TableSyntax
def create_table_structure
migration = ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers)
@@ -149,4 +150,31 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
expect { described_class.new.perform }.not_to change { LooseForeignKeys::DeletedRecord.status_processed.count }
end
end
+
+ describe 'multi-database support' do
+ where(:current_minute, :configured_base_models, :expected_connection) do
+ 2 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | ApplicationRecord.connection
+ 3 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | Ci::ApplicationRecord.connection
+ 2 | { main: ApplicationRecord } | ApplicationRecord.connection
+ 3 | { main: ApplicationRecord } | ApplicationRecord.connection
+ end
+
+ with_them do
+ before do
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(configured_base_models)
+ end
+
+ it 'uses the correct connection' do
+ LooseForeignKeys::DeletedRecord.count.times do
+ expect_next_found_instance_of(LooseForeignKeys::DeletedRecord) do |instance|
+ expect(instance.class.connection).to eq(expected_connection)
+ end
+ end
+
+ travel_to DateTime.new(2019, 1, 1, 10, current_minute) do
+ described_class.new.perform
+ end
+ end
+ end
+ end
end
diff --git a/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb
new file mode 100644
index 00000000000..f3ea14ad539
--- /dev/null
+++ b/spec/workers/merge_requests/update_head_pipeline_worker_spec.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::UpdateHeadPipelineWorker do
+ include ProjectForksHelper
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:ref) { 'master' }
+ let(:pipeline) { create(:ci_pipeline, project: project, ref: ref) }
+ let(:event) { Ci::PipelineCreatedEvent.new(data: { pipeline_id: pipeline.id }) }
+
+ subject { consume_event(event) }
+
+ def consume_event(event)
+ described_class.new.perform(event.class.name, event.data)
+ end
+
+ context 'when merge requests already exist for this source branch', :sidekiq_inline do
+ let(:merge_request_1) do
+ create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
+ end
+
+ let(:merge_request_2) do
+ create(:merge_request, source_branch: 'feature', target_branch: "v1.1.0", source_project: project)
+ end
+
+ context 'when related merge request is already merged' do
+ let!(:merged_merge_request) do
+ create(:merge_request, source_branch: 'master', target_branch: "branch_2", source_project: project, state: 'merged')
+ end
+
+ it 'does not schedule update head pipeline job' do
+ expect(UpdateHeadPipelineForMergeRequestWorker).not_to receive(:perform_async).with(merged_merge_request.id)
+
+ subject
+ end
+ end
+
+ context 'when the head pipeline sha equals merge request sha' do
+ let(:ref) { 'feature' }
+
+ before do
+ pipeline.update!(sha: project.repository.commit(ref).id)
+ end
+
+ it 'updates head pipeline of each merge request' do
+ merge_request_1
+ merge_request_2
+
+ subject
+
+ expect(merge_request_1.reload.head_pipeline).to eq(pipeline)
+ expect(merge_request_2.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+
+ context 'when the head pipeline sha does not equal merge request sha' do
+ let(:ref) { 'feature' }
+
+ it 'does not update the head piepeline of MRs' do
+ merge_request_1
+ merge_request_2
+
+ subject
+
+ expect(merge_request_1.reload.head_pipeline).not_to eq(pipeline)
+ expect(merge_request_2.reload.head_pipeline).not_to eq(pipeline)
+ end
+ end
+
+ context 'when there is no pipeline for source branch' do
+ it "does not update merge request head pipeline" do
+ merge_request = create(:merge_request, source_branch: 'feature',
+ target_branch: "branch_1",
+ source_project: project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).not_to eq(pipeline)
+ end
+ end
+
+ context 'when merge request target project is different from source project' do
+ let(:project) { fork_project(target_project, nil, repository: true) }
+ let(:target_project) { create(:project, :repository) }
+ let(:user) { create(:user) }
+ let(:ref) { 'feature' }
+
+ before do
+ project.add_developer(user)
+ pipeline.update!(sha: project.repository.commit(ref).id)
+ end
+
+ it 'updates head pipeline for merge request' do
+ merge_request = create(:merge_request, source_branch: 'feature',
+ target_branch: "master",
+ source_project: project,
+ target_project: target_project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+
+ context 'when the pipeline is not the latest for the branch' do
+ it 'does not update merge request head pipeline' do
+ merge_request = create(:merge_request, source_branch: 'master',
+ target_branch: "branch_1",
+ source_project: project)
+
+ create(:ci_pipeline, project: pipeline.project, ref: pipeline.ref)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to be_nil
+ end
+ end
+
+ context 'when pipeline has errors' do
+ before do
+ pipeline.update!(yaml_errors: 'some errors', status: :failed)
+ end
+
+ it 'updates merge request head pipeline reference' do
+ merge_request = create(:merge_request, source_branch: 'master',
+ target_branch: 'feature',
+ source_project: project)
+
+ subject
+
+ expect(merge_request.reload.head_pipeline).to eq(pipeline)
+ end
+ end
+ end
+end
diff --git a/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
index 19b79835825..f151780ffd7 100644
--- a/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
+++ b/spec/workers/metrics/dashboard/sync_dashboards_worker_spec.rb
@@ -10,16 +10,34 @@ RSpec.describe Metrics::Dashboard::SyncDashboardsWorker do
let(:dashboard_path) { '.gitlab/dashboards/test.yml' }
describe ".perform" do
- it 'imports metrics' do
- expect { worker.perform(project.id) }.to change(PrometheusMetric, :count).by(3)
+ context 'with valid dashboard hash' do
+ it 'imports metrics' do
+ expect { worker.perform(project.id) }.to change(PrometheusMetric, :count).by(3)
+ end
+
+ it 'is idempotent' do
+ 2.times do
+ worker.perform(project.id)
+ end
+
+ expect(PrometheusMetric.count).to eq(3)
+ end
end
- it 'is idempotent' do
- 2.times do
- worker.perform(project.id)
+ context 'with invalid dashboard hash' do
+ before do
+ allow_next_instance_of(Gitlab::Metrics::Dashboard::Importer) do |instance|
+ allow(instance).to receive(:dashboard_hash).and_return({})
+ end
end
- expect(PrometheusMetric.count).to eq(3)
+ it 'does not import metrics' do
+ expect { worker.perform(project.id) }.not_to change(PrometheusMetric, :count)
+ end
+
+ it 'does not raise an error' do
+ expect { worker.perform(project.id) }.not_to raise_error
+ end
end
end
end
diff --git a/spec/workers/packages/cleanup_package_file_worker_spec.rb b/spec/workers/packages/cleanup_package_file_worker_spec.rb
new file mode 100644
index 00000000000..b423c4d3f06
--- /dev/null
+++ b/spec/workers/packages/cleanup_package_file_worker_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::CleanupPackageFileWorker do
+ let_it_be(:package) { create(:package) }
+
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ subject { worker.perform_work }
+
+ context 'with no work to do' do
+ it { is_expected.to be_nil }
+ end
+
+ context 'with work to do' do
+ let_it_be(:package_file1) { create(:package_file, package: package) }
+ let_it_be(:package_file2) { create(:package_file, :pending_destruction, package: package) }
+ let_it_be(:package_file3) { create(:package_file, :pending_destruction, package: package, updated_at: 1.year.ago, created_at: 1.year.ago) }
+
+ it 'deletes the oldest package file pending destruction based on id', :aggregate_failures do
+ expect(worker).to receive(:log_extra_metadata_on_done).twice
+
+ expect { subject }.to change { Packages::PackageFile.count }.by(-1)
+ end
+ end
+
+ context 'with an error during the destroy' do
+ let_it_be(:package_file) { create(:package_file, :pending_destruction) }
+
+ before do
+ expect(worker).to receive(:log_metadata).and_raise('Error!')
+ end
+
+ it 'handles the error' do
+ expect { subject }.to change { Packages::PackageFile.error.count }.from(0).to(1)
+ expect(package_file.reload).to be_error
+ end
+ end
+ end
+
+ describe '#max_running_jobs' do
+ let(:capacity) { 5 }
+
+ subject { worker.max_running_jobs }
+
+ before do
+ stub_application_setting(packages_cleanup_package_file_worker_capacity: capacity)
+ end
+
+ it { is_expected.to eq(capacity) }
+ end
+
+ describe '#remaining_work_count' do
+ before(:context) do
+ create_list(:package_file, 3, :pending_destruction, package: package)
+ end
+
+ subject { worker.remaining_work_count }
+
+ it { is_expected.to eq(3) }
+ end
+end
diff --git a/spec/workers/packages/cleanup_package_registry_worker_spec.rb b/spec/workers/packages/cleanup_package_registry_worker_spec.rb
new file mode 100644
index 00000000000..e43864975f6
--- /dev/null
+++ b/spec/workers/packages/cleanup_package_registry_worker_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Packages::CleanupPackageRegistryWorker do
+ describe '#perform' do
+ let_it_be_with_reload(:package_files) { create_list(:package_file, 2, :pending_destruction) }
+
+ let(:worker) { described_class.new }
+
+ subject(:perform) { worker.perform }
+
+ context 'with package files pending destruction' do
+ it_behaves_like 'an idempotent worker'
+
+ it 'queues the cleanup job' do
+ expect(Packages::CleanupPackageFileWorker).to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ context 'with no package files pending destruction' do
+ before do
+ ::Packages::PackageFile.update_all(status: :default)
+ end
+
+ it_behaves_like 'an idempotent worker'
+
+ it 'does not queue the cleanup job' do
+ expect(Packages::CleanupPackageFileWorker).not_to receive(:perform_with_capacity)
+
+ perform
+ end
+ end
+
+ describe 'counts logging' do
+ let_it_be(:processing_package_file) { create(:package_file, status: :processing) }
+
+ it 'logs all the counts', :aggregate_failures do
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:pending_destruction_package_files_count, 2)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:processing_package_files_count, 1)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:error_package_files_count, 0)
+
+ perform
+ end
+
+ context 'with load balancing enabled', :db_load_balancing do
+ it 'reads the count from the replica' do
+ expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_replicas_for_read_queries).and_call_original
+
+ perform
+ end
+ end
+ end
+ end
+end
diff --git a/spec/workers/pages_update_configuration_worker_spec.rb b/spec/workers/pages_update_configuration_worker_spec.rb
index 7cceeaa52d6..af71f6b3cca 100644
--- a/spec/workers/pages_update_configuration_worker_spec.rb
+++ b/spec/workers/pages_update_configuration_worker_spec.rb
@@ -5,59 +5,8 @@ RSpec.describe PagesUpdateConfigurationWorker do
let_it_be(:project) { create(:project) }
describe "#perform" do
- it "does not break if the project doesn't exist" do
+ it "does not break" do
expect { subject.perform(-1) }.not_to raise_error
end
-
- it "calls the correct service" do
- expect_next_instance_of(Projects::UpdatePagesConfigurationService, project) do |service|
- expect(service).to receive(:execute).and_return({})
- end
-
- subject.perform(project.id)
- end
-
- it_behaves_like "an idempotent worker" do
- let(:job_args) { [project.id] }
- let(:pages_dir) { Dir.mktmpdir }
- let(:config_path) { File.join(pages_dir, "config.json") }
-
- before do
- allow(Project).to receive(:find_by_id).with(project.id).and_return(project)
- allow(project).to receive(:pages_path).and_return(pages_dir)
-
- # Make sure _some_ config exists
- FileUtils.touch(config_path)
- end
-
- after do
- FileUtils.remove_entry(pages_dir)
- end
-
- it "only updates the config file once" do
- described_class.new.perform(project.id)
-
- expect(File.mtime(config_path)).not_to be_nil
- expect { subject }.not_to change { File.mtime(config_path) }
- end
- end
- end
-
- describe '#perform_async' do
- it "calls the correct service", :sidekiq_inline do
- expect_next_instance_of(Projects::UpdatePagesConfigurationService, project) do |service|
- expect(service).to receive(:execute).and_return(status: :success)
- end
-
- described_class.perform_async(project.id)
- end
-
- it "doesn't schedule a worker if updates on legacy storage are disabled", :sidekiq_inline do
- allow(Settings.pages.local_store).to receive(:enabled).and_return(false)
-
- expect(Projects::UpdatePagesConfigurationService).not_to receive(:new)
-
- described_class.perform_async(project.id)
- end
end
end
diff --git a/spec/workers/pages_worker_spec.rb b/spec/workers/pages_worker_spec.rb
new file mode 100644
index 00000000000..5ddfd5b43b9
--- /dev/null
+++ b/spec/workers/pages_worker_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PagesWorker, :sidekiq_inline do
+ let(:project) { create(:project) }
+ let(:ci_build) { create(:ci_build, project: project)}
+
+ it 'calls UpdatePagesService' do
+ expect_next_instance_of(Projects::UpdatePagesService, project, ci_build) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ described_class.perform_async(:deploy, ci_build.id)
+ end
+end
diff --git a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
index b928104fb58..3de59670f8d 100644
--- a/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
+++ b/spec/workers/purge_dependency_proxy_cache_worker_spec.rb
@@ -25,11 +25,11 @@ RSpec.describe PurgeDependencyProxyCacheWorker do
include_examples 'an idempotent worker' do
let(:job_args) { [user.id, group_id] }
- it 'expires the blobs and returns ok', :aggregate_failures do
+ it 'marks the blobs as pending_destruction and returns ok', :aggregate_failures do
subject
- expect(blob).to be_expired
- expect(manifest).to be_expired
+ expect(blob).to be_pending_destruction
+ expect(manifest).to be_pending_destruction
end
end
end
diff --git a/spec/workers/web_hook_worker_spec.rb b/spec/workers/web_hook_worker_spec.rb
index 0f40177eb7d..bbb8844a447 100644
--- a/spec/workers/web_hook_worker_spec.rb
+++ b/spec/workers/web_hook_worker_spec.rb
@@ -19,6 +19,15 @@ RSpec.describe WebHookWorker do
expect { subject.perform(non_existing_record_id, data, hook_name) }.not_to raise_error
end
+ it 'retrieves recursion detection data, reinstates it, and cleans it from payload', :request_store, :aggregate_failures do
+ uuid = SecureRandom.uuid
+ full_data = data.merge({ _gitlab_recursion_detection_request_uuid: uuid })
+
+ expect_next(WebHookService, project_hook, data.with_indifferent_access, hook_name, anything).to receive(:execute)
+ expect { subject.perform(project_hook.id, full_data, hook_name) }
+ .to change { Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid }.to(uuid)
+ end
+
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :delayed