diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 09:16:11 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-20 09:16:11 +0000 |
commit | edaa33dee2ff2f7ea3fac488d41558eb5f86d68c (patch) | |
tree | 11f143effbfeba52329fb7afbd05e6e2a3790241 /spec/workers | |
parent | d8a5691316400a0f7ec4f83832698f1988eb27c1 (diff) | |
download | gitlab-ce-edaa33dee2ff2f7ea3fac488d41558eb5f86d68c.tar.gz |
Add latest changes from gitlab-org/gitlab@14-7-stable-eev14.7.0-rc42
Diffstat (limited to 'spec/workers')
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 |