diff options
Diffstat (limited to 'spec/workers')
31 files changed, 576 insertions, 270 deletions
diff --git a/spec/workers/build_finished_worker_spec.rb b/spec/workers/build_finished_worker_spec.rb index 4adb795b1d6..849563d9608 100644 --- a/spec/workers/build_finished_worker_spec.rb +++ b/spec/workers/build_finished_worker_spec.rb @@ -3,7 +3,11 @@ require 'spec_helper' describe BuildFinishedWorker do + subject { described_class.new.perform(build.id) } + describe '#perform' do + let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline)) } + context 'when build exists' do let!(:build) { create(:ci_build) } @@ -18,8 +22,10 @@ describe BuildFinishedWorker do expect(BuildHooksWorker).to receive(:perform_async) expect(ArchiveTraceWorker).to receive(:perform_async) expect(ExpirePipelineCacheWorker).to receive(:perform_async) + expect(ChatNotificationWorker).not_to receive(:perform_async) + expect(Ci::BuildReportResultWorker).not_to receive(:perform) - described_class.new.perform(build.id) + subject end end @@ -30,23 +36,26 @@ describe BuildFinishedWorker do end end - it 'schedules a ChatNotification job for a chat build' do - build = create(:ci_build, :success, pipeline: create(:ci_pipeline, source: :chat)) + context 'when build has a chat' do + let(:build) { create(:ci_build, :success, pipeline: create(:ci_pipeline, source: :chat)) } - expect(ChatNotificationWorker) - .to receive(:perform_async) - .with(build.id) + it 'schedules a ChatNotification job' do + expect(ChatNotificationWorker).to receive(:perform_async).with(build.id) - described_class.new.perform(build.id) + subject + end end - it 'does not schedule a ChatNotification job for a regular build' do - build = create(:ci_build, :success, pipeline: create(:ci_pipeline)) + context 'when build has a test report' do + let(:build) { create(:ci_build, :test_reports) } - expect(ChatNotificationWorker) - .not_to receive(:perform_async) + it 'schedules a BuildReportResult job' do + expect_next_instance_of(Ci::BuildReportResultWorker) do |worker| + expect(worker).to receive(:perform).with(build.id) + end - described_class.new.perform(build.id) + subject + end end end end diff --git a/spec/workers/ci/build_report_result_worker_spec.rb b/spec/workers/ci/build_report_result_worker_spec.rb new file mode 100644 index 00000000000..290a98366b4 --- /dev/null +++ b/spec/workers/ci/build_report_result_worker_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Ci::BuildReportResultWorker do + subject { described_class.new.perform(build_id) } + + context 'when build exists' do + let(:build) { create(:ci_build) } + let(:build_id) { build.id } + + it 'calls build report result service' do + expect_next_instance_of(Ci::BuildReportResultService) do |build_report_result_service| + expect(build_report_result_service).to receive(:execute) + end + + subject + end + end + + context 'when build does not exist' do + let(:build_id) { -1 } + + it 'does not call build report result service' do + expect(Ci::BuildReportResultService).not_to receive(:execute) + + subject + end + end +end diff --git a/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb new file mode 100644 index 00000000000..a09b9ec4165 --- /dev/null +++ b/spec/workers/clusters/applications/check_prometheus_health_worker_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Clusters::Applications::CheckPrometheusHealthWorker, '#perform' do + subject { described_class.new.perform } + + it 'triggers health service' do + cluster = create(:cluster) + allow(Gitlab::Monitor::DemoProjects).to receive(:primary_keys) + allow(Clusters::Cluster).to receive_message_chain(:with_application_prometheus, :with_project_alert_service_data).and_return([cluster]) + + service_instance = instance_double(Clusters::Applications::PrometheusHealthCheckService) + expect(Clusters::Applications::PrometheusHealthCheckService).to receive(:new).with(cluster).and_return(service_instance) + expect(service_instance).to receive(:execute) + + subject + end +end diff --git a/spec/workers/concerns/application_worker_spec.rb b/spec/workers/concerns/application_worker_spec.rb index ae311a54cd1..087a36d2bd0 100644 --- a/spec/workers/concerns/application_worker_spec.rb +++ b/spec/workers/concerns/application_worker_spec.rb @@ -118,5 +118,45 @@ describe ApplicationWorker do .to raise_error(ArgumentError) end end + + context 'with batches' do + let(:batch_delay) { 1.minute } + + it 'correctly schedules jobs' do + expect(Sidekiq::Client).to( + receive(:push_bulk).with(hash_including('args' => [['Foo', [1]], ['Foo', [2]]])) + .ordered + .and_call_original) + expect(Sidekiq::Client).to( + receive(:push_bulk).with(hash_including('args' => [['Foo', [3]], ['Foo', [4]]])) + .ordered + .and_call_original) + expect(Sidekiq::Client).to( + receive(:push_bulk).with(hash_including('args' => [['Foo', [5]]])) + .ordered + .and_call_original) + + worker.bulk_perform_in( + 1.minute, + [['Foo', [1]], ['Foo', [2]], ['Foo', [3]], ['Foo', [4]], ['Foo', [5]]], + batch_size: 2, batch_delay: batch_delay) + + expect(worker.jobs.count).to eq 5 + expect(worker.jobs[0]['at']).to eq(worker.jobs[1]['at']) + expect(worker.jobs[2]['at']).to eq(worker.jobs[3]['at']) + expect(worker.jobs[2]['at'] - worker.jobs[1]['at']).to eq(batch_delay) + expect(worker.jobs[4]['at'] - worker.jobs[3]['at']).to eq(batch_delay) + end + + context 'when batch_size is invalid' do + it 'raises an ArgumentError exception' do + expect do + worker.bulk_perform_in(1.minute, + [['Foo']], + batch_size: -1, batch_delay: batch_delay) + end.to raise_error(ArgumentError) + end + end + end end end diff --git a/spec/workers/concerns/project_import_options_spec.rb b/spec/workers/concerns/project_import_options_spec.rb index 3ccfb21b653..c56dcc5ed82 100644 --- a/spec/workers/concerns/project_import_options_spec.rb +++ b/spec/workers/concerns/project_import_options_spec.rb @@ -17,7 +17,7 @@ describe ProjectImportOptions do end it 'sets default status expiration' do - expect(worker_class.sidekiq_options['status_expiration']).to eq(StuckImportJobsWorker::IMPORT_JOBS_EXPIRATION) + expect(worker_class.sidekiq_options['status_expiration']).to eq(Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION) end describe '.sidekiq_retries_exhausted' do diff --git a/spec/workers/container_expiration_policy_worker_spec.rb b/spec/workers/container_expiration_policy_worker_spec.rb index 48ab1614633..b15a28dcdca 100644 --- a/spec/workers/container_expiration_policy_worker_spec.rb +++ b/spec/workers/container_expiration_policy_worker_spec.rb @@ -53,5 +53,22 @@ describe ContainerExpirationPolicyWorker do subject end end + + context 'an invalid policy' do + let_it_be(:container_expiration_policy) { create(:container_expiration_policy, :runnable) } + let_it_be(:user) {container_expiration_policy.project.owner } + + before do + container_expiration_policy.update_column(:name_regex, '*production') + end + + it 'runs the policy and tracks an error' do + expect(ContainerExpirationPolicyService) + .to receive(:new).with(container_expiration_policy.project, user).and_call_original + expect(Gitlab::ErrorTracking).to receive(:log_exception).with(instance_of(ContainerExpirationPolicyService::InvalidPolicyError), container_expiration_policy_id: container_expiration_policy.id) + + expect { subject }.to change { container_expiration_policy.reload.enabled }.from(true).to(false) + end + end end end diff --git a/spec/workers/create_evidence_worker_spec.rb b/spec/workers/create_evidence_worker_spec.rb index 9b8314122cd..b8c622f7d1d 100644 --- a/spec/workers/create_evidence_worker_spec.rb +++ b/spec/workers/create_evidence_worker_spec.rb @@ -3,9 +3,24 @@ require 'spec_helper' describe CreateEvidenceWorker do - let!(:release) { create(:release) } + let(:project) { create(:project, :repository) } + let(:release) { create(:release, project: project) } + let(:pipeline) { create(:ci_empty_pipeline, sha: release.sha, project: project) } + # support old scheduled workers without pipeline it 'creates a new Evidence record' do + expect_next_instance_of(::Releases::CreateEvidenceService, release, pipeline: nil) do |service| + expect(service).to receive(:execute).and_call_original + end + expect { described_class.new.perform(release.id) }.to change(Releases::Evidence, :count).by(1) end + + it 'creates a new Evidence record with pipeline' do + expect_next_instance_of(::Releases::CreateEvidenceService, release, pipeline: pipeline) do |service| + expect(service).to receive(:execute).and_call_original + end + + expect { described_class.new.perform(release.id, pipeline.id) }.to change(Releases::Evidence, :count).by(1) + end end diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb index d6e867ee407..195783c74df 100644 --- a/spec/workers/every_sidekiq_worker_spec.rb +++ b/spec/workers/every_sidekiq_worker_spec.rb @@ -40,6 +40,12 @@ describe 'Every Sidekiq worker' do end end + it 'has a value for loggable_arguments' do + workers_without_defaults.each do |worker| + expect(worker.klass.loggable_arguments).to be_an(Array) + end + end + describe "feature category declarations" do let(:feature_categories) do YAML.load_file(Rails.root.join('config', 'feature_categories.yml')).map(&:to_sym).to_set diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb index 804a50e89fe..062926cf7aa 100644 --- a/spec/workers/expire_job_cache_worker_spec.rb +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -13,7 +13,7 @@ describe ExpireJobCacheWorker do include_examples 'an idempotent worker' do it 'invalidates Etag caching for the job path' do - pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" + pipeline_path = "/#{project.full_path}/-/pipelines/#{pipeline.id}.json" job_path = "/#{project.full_path}/builds/#{job.id}.json" spy_store = Gitlab::EtagCaching::Store.new diff --git a/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb b/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb new file mode 100644 index 00000000000..5afc5717b82 --- /dev/null +++ b/spec/workers/gitlab/import/stuck_project_import_jobs_worker_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Import::StuckProjectImportJobsWorker do + let(:worker) { described_class.new } + + describe 'with scheduled import_status' do + it_behaves_like 'stuck import job detection' do + let(:import_state) { create(:project, :import_scheduled).import_state } + + before do + import_state.update(jid: '123') + end + end + end + + describe 'with started import_status' do + it_behaves_like 'stuck import job detection' do + let(:import_state) { create(:project, :import_started).import_state } + + before do + import_state.update(jid: '123') + end + end + end +end diff --git a/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb index 4cb6f5e28b8..084302be7d8 100644 --- a/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/finish_import_worker_spec.rb @@ -11,47 +11,33 @@ describe Gitlab::JiraImport::Stage::FinishImportWorker do end describe '#perform' do - context 'when feature flag enabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + context 'when import did not start' do it_behaves_like 'cannot do Jira import' end - context 'when feature flag enabled' do - let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + context 'when import started' do + let_it_be(:import_label) { create(:label, project: project, title: 'jira-import') } + let_it_be(:imported_issues) { create_list(:labeled_issue, 3, project: project, labels: [import_label]) } before do - stub_feature_flags(jira_issue_import: true) - end + expect(Gitlab::JiraImport).to receive(:get_import_label_id).and_return(import_label.id) + expect(Gitlab::JiraImport).to receive(:issue_failures).and_return(2) - context 'when import did not start' do - it_behaves_like 'cannot do Jira import' + jira_import.start! + worker.perform(project.id) end - context 'when import started' do - let_it_be(:import_label) { create(:label, project: project, title: 'jira-import') } - let_it_be(:imported_issues) { create_list(:labeled_issue, 3, project: project, labels: [import_label]) } - - before do - expect(Gitlab::JiraImport).to receive(:get_import_label_id).and_return(import_label.id) - expect(Gitlab::JiraImport).to receive(:issue_failures).and_return(2) - - jira_import.start! - worker.perform(project.id) - end - - it 'changes import state to finished' do - expect(project.jira_import_status).to eq('finished') - end + it 'changes import state to finished' do + expect(project.jira_import_status).to eq('finished') + end - it 'saves imported issues counts' do - latest_jira_import = project.latest_jira_import - expect(latest_jira_import.total_issue_count).to eq(5) - expect(latest_jira_import.failed_to_import_count).to eq(2) - expect(latest_jira_import.imported_issues_count).to eq(3) - end + it 'saves imported issues counts' do + latest_jira_import = project.latest_jira_import + expect(latest_jira_import.total_issue_count).to eq(5) + expect(latest_jira_import.failed_to_import_count).to eq(2) + expect(latest_jira_import.imported_issues_count).to eq(3) end end end diff --git a/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb index e6d41ae8bb4..34981d974cd 100644 --- a/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_attachments_worker_spec.rb @@ -10,34 +10,19 @@ describe Gitlab::JiraImport::Stage::ImportAttachmentsWorker do end describe '#perform' do - context 'when feature flag disabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) } + context 'when import did not start' do it_behaves_like 'cannot do Jira import' it_behaves_like 'does not advance to next stage' end - context 'when feature flag enabled' do - let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) } - + context 'when import started' do before do - stub_feature_flags(jira_issue_import: true) + jira_import.start! end - context 'when import did not start' do - it_behaves_like 'cannot do Jira import' - it_behaves_like 'does not advance to next stage' - end - - context 'when import started' do - before do - jira_import.start! - end - - it_behaves_like 'advance to next stage', :notes - end + it_behaves_like 'advance to next stage', :notes end end end diff --git a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb index f2067522af4..40f6cf75412 100644 --- a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb @@ -13,65 +13,53 @@ describe Gitlab::JiraImport::Stage::ImportIssuesWorker do end describe '#perform' do - context 'when feature flag disabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + + before do + stub_jira_service_test + end + context 'when import did not start' do it_behaves_like 'cannot do Jira import' it_behaves_like 'does not advance to next stage' end - context 'when feature flag enabled' do - let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + context 'when import started', :clean_gitlab_redis_cache do + let_it_be(:jira_service) { create(:jira_service, project: project) } before do - stub_feature_flags(jira_issue_import: true) - stub_jira_service_test + jira_import.start! + allow_next_instance_of(Gitlab::JiraImport::IssuesImporter) do |instance| + allow(instance).to receive(:fetch_issues).and_return([]) + end end - context 'when import did not start' do - it_behaves_like 'cannot do Jira import' - it_behaves_like 'does not advance to next stage' + context 'when start_at is nil' do + it_behaves_like 'advance to next stage', :attachments end - context 'when import started', :clean_gitlab_redis_cache do - let_it_be(:jira_service) { create(:jira_service, project: project) } - + context 'when start_at is zero' do before do - jira_import.start! - allow_next_instance_of(Gitlab::JiraImport::IssuesImporter) do |instance| - allow(instance).to receive(:fetch_issues).and_return([]) - end - end - - context 'when start_at is nil' do - it_behaves_like 'advance to next stage', :attachments + allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(0) end - context 'when start_at is zero' do - before do - allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(0) - end + it_behaves_like 'advance to next stage', :issues + end - it_behaves_like 'advance to next stage', :issues + context 'when start_at is greater than zero' do + before do + allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(25) end - context 'when start_at is greater than zero' do - before do - allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(25) - end + it_behaves_like 'advance to next stage', :issues + end - it_behaves_like 'advance to next stage', :issues + context 'when start_at is below zero' do + before do + allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(-1) end - context 'when start_at is below zero' do - before do - allow(Gitlab::Cache::Import::Caching).to receive(:read).and_return(-1) - end - - it_behaves_like 'advance to next stage', :attachments - end + it_behaves_like 'advance to next stage', :attachments end end end diff --git a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb index 7f289de5422..1215b41bd9f 100644 --- a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb @@ -13,48 +13,33 @@ describe Gitlab::JiraImport::Stage::ImportLabelsWorker do end describe '#perform' do - context 'when feature flag disabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + context 'when import did not start' do it_behaves_like 'cannot do Jira import' it_behaves_like 'does not advance to next stage' end - context 'when feature flag enabled' do - let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } + context 'when import started' do + let!(:jira_service) { create(:jira_service, project: project) } before do - stub_feature_flags(jira_issue_import: true) - end - - context 'when import did not start' do - it_behaves_like 'cannot do Jira import' - it_behaves_like 'does not advance to next stage' - end + stub_jira_service_test - context 'when import started' do - let!(:jira_service) { create(:jira_service, project: project) } + jira_import.start! - before do - stub_jira_service_test + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/label?maxResults=500&startAt=0') + .to_return(body: {}.to_json ) + end - jira_import.start! + it_behaves_like 'advance to next stage', :issues - WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/label?maxResults=500&startAt=0') - .to_return(body: {}.to_json ) + it 'executes labels importer' do + expect_next_instance_of(Gitlab::JiraImport::LabelsImporter) do |instance| + expect(instance).to receive(:execute).and_return(Gitlab::JobWaiter.new) end - it_behaves_like 'advance to next stage', :issues - - it 'executes labels importer' do - expect_next_instance_of(Gitlab::JiraImport::LabelsImporter) do |instance| - expect(instance).to receive(:execute).and_return(Gitlab::JobWaiter.new) - end - - described_class.new.perform(project.id) - end + described_class.new.perform(project.id) end end end diff --git a/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb index f9bdbd669d8..a0a9ad6f695 100644 --- a/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_notes_worker_spec.rb @@ -10,34 +10,19 @@ describe Gitlab::JiraImport::Stage::ImportNotesWorker do end describe '#perform' do - context 'when feature flag disabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) } + context 'when import did not start' do it_behaves_like 'cannot do Jira import' it_behaves_like 'does not advance to next stage' end - context 'when feature flag enabled' do - let_it_be(:jira_import) { create(:jira_import_state, :scheduled, project: project) } - + context 'when import started' do before do - stub_feature_flags(jira_issue_import: true) + jira_import.start! end - context 'when import did not start' do - it_behaves_like 'cannot do Jira import' - it_behaves_like 'does not advance to next stage' - end - - context 'when import started' do - before do - jira_import.start! - end - - it_behaves_like 'advance to next stage', :finish - end + it_behaves_like 'advance to next stage', :finish end end end diff --git a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb index 9cffe6e4ff7..a4fc761accf 100644 --- a/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/start_import_worker_spec.rb @@ -12,80 +12,62 @@ describe Gitlab::JiraImport::Stage::StartImportWorker do end describe '#perform' do - context 'when feature flag not disabled' do - before do - stub_feature_flags(jira_issue_import: false) - end + let_it_be(:jira_import, reload: true) { create(:jira_import_state, project: project, jid: jid) } - it 'exits because import not allowed' do + context 'when import is not scheduled' do + it 'exits because import not started' do expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) worker.perform(project.id) end end - context 'when feature flag enabled' do - let_it_be(:jira_import, reload: true) { create(:jira_import_state, project: project, jid: jid) } - + context 'when import is scheduled' do before do - stub_feature_flags(jira_issue_import: true) + jira_import.schedule! end - context 'when import is not scheduled' do - it 'exits because import not started' do - expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) + it 'advances to importing labels' do + expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async) - worker.perform(project.id) - end + worker.perform(project.id) end + end - context 'when import is scheduled' do - before do - jira_import.schedule! - end + context 'when import is started' do + before do + jira_import.update!(status: :started) + end + context 'when this is the same worker that stated import' do it 'advances to importing labels' do + allow(worker).to receive(:jid).and_return(jid) expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async) worker.perform(project.id) end end - context 'when import is started' do - before do - jira_import.update!(status: :started) - end - - context 'when this is the same worker that stated import' do - it 'advances to importing labels' do - allow(worker).to receive(:jid).and_return(jid) - expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).to receive(:perform_async) - - worker.perform(project.id) - end - end - - context 'when this is a different worker that stated import' do - it 'advances to importing labels' do - allow(worker).to receive(:jid).and_return('87654321') - expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) + context 'when this is a different worker that stated import' do + it 'advances to importing labels' do + allow(worker).to receive(:jid).and_return('87654321') + expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) - worker.perform(project.id) - end + worker.perform(project.id) end end + end - context 'when import is finished' do - before do - jira_import.update!(status: :finished) - end + context 'when import is finished' do + before do + jira_import.update!(status: :finished) + end - it 'advances to importing labels' do - allow(worker).to receive(:jid).and_return(jid) - expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) + it 'advances to importing labels' do + allow(worker).to receive(:jid).and_return(jid) + expect(Gitlab::JiraImport::Stage::ImportLabelsWorker).not_to receive(:perform_async) - worker.perform(project.id) - end + worker.perform(project.id) end end end diff --git a/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb new file mode 100644 index 00000000000..fae52cec2b4 --- /dev/null +++ b/spec/workers/gitlab/jira_import/stuck_jira_import_jobs_worker_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ::Gitlab::JiraImport::StuckJiraImportJobsWorker do + let_it_be(:current_user) { create(:user) } + let_it_be(:project) { create(:project) } + let(:worker) { described_class.new } + + describe 'with scheduled Jira import' do + it_behaves_like 'stuck import job detection' do + let(:import_state) { create(:jira_import_state, :scheduled, project: project) } + + before do + import_state.update(jid: '123') + end + end + end + + describe 'with started jira import' do + it_behaves_like 'stuck import job detection' do + let(:import_state) { create(:jira_import_state, :started, project: project) } + + before do + import_state.update(jid: '123') + end + end + end + + describe 'with failed jira import' do + let(:import_state) { create(:jira_import_state, :failed, project: project) } + + it 'detects no stuck jobs' do + expect(worker).to receive(:track_metrics).with(0, 0) + + worker.perform + end + end +end diff --git a/spec/workers/group_import_worker_spec.rb b/spec/workers/group_import_worker_spec.rb index bb7dc116a08..324a5fa6978 100644 --- a/spec/workers/group_import_worker_spec.rb +++ b/spec/workers/group_import_worker_spec.rb @@ -26,7 +26,7 @@ describe GroupImportWorker do subject.perform(user.id, group.id) end - context 'import state' do + context 'when the import state does not exist' do it 'creates group import' do expect(group.import_state).to be_nil @@ -54,6 +54,17 @@ describe GroupImportWorker do subject.perform(user.id, group.id) end end + + context 'when the import state already exists' do + it 'updates the existing state' do + existing_state = create(:group_import_state, group: group) + + expect { subject.perform(user.id, group.id) } + .not_to change { GroupImportState.count } + + expect(existing_state.reload).to be_finished + end + end end context 'when it fails' do diff --git a/spec/workers/incident_management/process_alert_worker_spec.rb b/spec/workers/incident_management/process_alert_worker_spec.rb index 2d17a59c76f..0470552d933 100644 --- a/spec/workers/incident_management/process_alert_worker_spec.rb +++ b/spec/workers/incident_management/process_alert_worker_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' describe IncidentManagement::ProcessAlertWorker do let_it_be(:project) { create(:project) } + let_it_be(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) } describe '#perform' do let(:alert_management_alert_id) { nil } @@ -71,11 +72,7 @@ describe IncidentManagement::ProcessAlertWorker do end context 'when alert cannot be updated' do - before do - # invalidate alert - too_many_hosts = Array.new(AlertManagement::Alert::HOSTS_MAX_LENGTH + 1) { |_| 'host' } - alert.update_columns(hosts: too_many_hosts) - end + let(:alert) { create(:alert_management_alert, :with_validation_errors, project: project) } it 'updates AlertManagement::Alert#issue_id' do expect { subject }.not_to change { alert.reload.issue_id } diff --git a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb index 5fbc39cad4e..c9ea96df5c2 100644 --- a/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb +++ b/spec/workers/incident_management/process_prometheus_alert_worker_spec.rb @@ -6,8 +6,9 @@ describe IncidentManagement::ProcessPrometheusAlertWorker do describe '#perform' do let_it_be(:project) { create(:project) } let_it_be(:prometheus_alert) { create(:prometheus_alert, project: project) } - let_it_be(:payload_key) { PrometheusAlertEvent.payload_key_for(prometheus_alert.prometheus_metric_id, prometheus_alert.created_at.rfc3339) } + let(:payload_key) { Gitlab::Alerting::Alert.new(project: project, payload: alert_params).gitlab_fingerprint } let!(:prometheus_alert_event) { create(:prometheus_alert_event, prometheus_alert: prometheus_alert, payload_key: payload_key) } + let!(:settings) { create(:project_incident_management_setting, project: project, create_issue: true) } let(:alert_params) do { @@ -107,7 +108,6 @@ describe IncidentManagement::ProcessPrometheusAlertWorker do let(:starts_at) { Time.now.rfc3339 } let!(:prometheus_alert_event) do - payload_key = SelfManagedPrometheusAlertEvent.payload_key_for(starts_at, alert_name, 'vector(1)') create(:self_managed_prometheus_alert_event, project: project, payload_key: payload_key) end diff --git a/spec/workers/irker_worker_spec.rb b/spec/workers/irker_worker_spec.rb new file mode 100644 index 00000000000..6b58c04d909 --- /dev/null +++ b/spec/workers/irker_worker_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe IrkerWorker, '#perform' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user) } + let_it_be(:push_data) { HashWithIndifferentAccess.new(Gitlab::DataBuilder::Push.build_sample(project, user)) } + let_it_be(:channels) { ['irc://test.net/#test'] } + + let_it_be(:server_settings) do + { + server_host: 'localhost', + server_port: 6659 + } + end + + let_it_be(:arguments) do + [ + project.id, + channels, + false, + push_data, + server_settings + ] + end + + let(:tcp_socket) { double('socket') } + + subject(:worker) { described_class.new } + + before do + allow(TCPSocket).to receive(:new).and_return(tcp_socket) + allow(tcp_socket).to receive(:puts).and_return(true) + allow(tcp_socket).to receive(:close).and_return(true) + end + + context 'connection fails' do + before do + allow(TCPSocket).to receive(:new).and_raise(Errno::ECONNREFUSED.new('test')) + end + + it { expect(subject.perform(*arguments)).to be_falsey } + end + + context 'connection successful' do + it { expect(subject.perform(*arguments)).to be_truthy } + + context 'new branch' do + it 'sends a correct message with branches url' do + branches_url = Gitlab::Routing.url_helpers + .project_branches_url(project) + + push_data['before'] = '0000000000000000000000000000000000000000' + + message = "has created a new branch master: #{branches_url}" + + expect(tcp_socket).to receive(:puts).with(wrap_message(message)) + + subject.perform(*arguments) + end + end + + context 'deleted branch' do + it 'sends a correct message' do + push_data['after'] = '0000000000000000000000000000000000000000' + + message = "has deleted the branch master" + + expect(tcp_socket).to receive(:puts).with(wrap_message(message)) + + subject.perform(*arguments) + end + end + + context 'new commits to existing branch' do + it 'sends a correct message with a compare url' do + compare_url = Gitlab::Routing.url_helpers + .project_compare_url(project, + from: Commit.truncate_sha(push_data[:before]), + to: Commit.truncate_sha(push_data[:after])) + + message = "pushed #{push_data['total_commits_count']} " \ + "new commits to master: #{compare_url}" + + expect(tcp_socket).to receive(:puts).with(wrap_message(message)) + + subject.perform(*arguments) + end + end + end + + def wrap_message(text) + message = "[#{project.path}] #{push_data['user_name']} #{text}" + to_send = { to: channels, privmsg: message } + + Gitlab::Json.dump(to_send) + end +end diff --git a/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb b/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb new file mode 100644 index 00000000000..bab5a5d8740 --- /dev/null +++ b/spec/workers/metrics/dashboard/prune_old_annotations_worker_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Metrics::Dashboard::PruneOldAnnotationsWorker do + let_it_be(:now) { DateTime.parse('2020-06-02T00:12:00Z') } + let_it_be(:two_weeks_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(weeks: -2)) } + let_it_be(:one_day_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(days: -1)) } + let_it_be(:month_old_annotation) { create(:metrics_dashboard_annotation, starting_at: now.advance(months: -1)) } + + describe '#perform' do + it 'removes all annotations older than cut off', :aggregate_failures do + Timecop.freeze(now) do + described_class.new.perform + + expect(Metrics::Dashboard::Annotation.all).to match_array([one_day_old_annotation, two_weeks_old_annotation]) + + # is idempotent in the scope of 24h + expect { described_class.new.perform }.not_to change { Metrics::Dashboard::Annotation.all.to_a } + Timecop.travel(24.hours.from_now) do + described_class.new.perform + expect(Metrics::Dashboard::Annotation.all).to match_array([one_day_old_annotation]) + end + end + end + + context 'batch to be deleted is bigger than upper limit' do + it 'schedules second job to clear remaining records' do + Timecop.freeze(now) do + create(:metrics_dashboard_annotation, starting_at: 1.month.ago) + stub_const("#{described_class}::DELETE_LIMIT", 1) + + expect(described_class).to receive(:perform_async) + + described_class.new.perform + end + end + end + end +end diff --git a/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb b/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb new file mode 100644 index 00000000000..bfe6fe3a90e --- /dev/null +++ b/spec/workers/metrics/dashboard/schedule_annotations_prune_worker_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Metrics::Dashboard::ScheduleAnnotationsPruneWorker do + describe '#perform' do + it 'schedules annotations prune job with default cut off date' do + expect(Metrics::Dashboard::PruneOldAnnotationsWorker).to receive(:perform_async) + + described_class.new.perform + end + end +end diff --git a/spec/workers/new_note_worker_spec.rb b/spec/workers/new_note_worker_spec.rb index 387a0958d6b..57269355180 100644 --- a/spec/workers/new_note_worker_spec.rb +++ b/spec/workers/new_note_worker_spec.rb @@ -27,7 +27,7 @@ describe NewNoteWorker do let(:unexistent_note_id) { non_existing_record_id } it 'logs NewNoteWorker process skipping' do - expect(Rails.logger).to receive(:error) + expect(Gitlab::AppLogger).to receive(:error) .with("NewNoteWorker: couldn't find note with ID=#{unexistent_note_id}, skipping job") described_class.new.perform(unexistent_note_id) @@ -49,4 +49,14 @@ describe NewNoteWorker do described_class.new.perform(unexistent_note_id) end end + + context 'when note is with review' do + it 'does not create a new note notification' do + note = create(:note, :with_review) + + expect_any_instance_of(NotificationService).not_to receive(:new_note) + + subject.perform(note.id) + end + end end diff --git a/spec/workers/personal_access_tokens/expiring_worker_spec.rb b/spec/workers/personal_access_tokens/expiring_worker_spec.rb index fcc09e2705c..c8bdf02f4d3 100644 --- a/spec/workers/personal_access_tokens/expiring_worker_spec.rb +++ b/spec/workers/personal_access_tokens/expiring_worker_spec.rb @@ -7,7 +7,7 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do describe '#perform' do context 'when a token needs to be notified' do - let!(:pat) { create(:personal_access_token, expires_at: 5.days.from_now) } + let_it_be(:pat) { create(:personal_access_token, expires_at: 5.days.from_now) } it 'uses notification service to send the email' do expect_next_instance_of(NotificationService) do |notification_service| @@ -23,7 +23,7 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do end context 'when no tokens need to be notified' do - let!(:pat) { create(:personal_access_token, expires_at: 5.days.from_now, expire_notification_delivered: true) } + let_it_be(:pat) { create(:personal_access_token, expires_at: 5.days.from_now, expire_notification_delivered: true) } it "doesn't use notification service to send the email" do expect_next_instance_of(NotificationService) do |notification_service| @@ -33,7 +33,23 @@ RSpec.describe PersonalAccessTokens::ExpiringWorker, type: :worker do worker.perform end - it "doesn't change the notificationd delivered of the token" do + it "doesn't change the notification delivered of the token" do + expect { worker.perform }.not_to change { pat.reload.expire_notification_delivered } + end + end + + context 'when a token is an impersonation token' do + let_it_be(:pat) { create(:personal_access_token, :impersonation, expires_at: 5.days.from_now) } + + it "doesn't use notification service to send the email" do + expect_next_instance_of(NotificationService) do |notification_service| + expect(notification_service).not_to receive(:access_token_about_to_expire).with(pat.user) + end + + worker.perform + end + + it "doesn't change the notification delivered of the token" do expect { worker.perform }.not_to change { pat.reload.expire_notification_delivered } end end diff --git a/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb b/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb index 7228de4f895..3fe8aa55142 100644 --- a/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb +++ b/spec/workers/pipeline_update_ci_ref_status_worker_service_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' +# NOTE: This class is unused and to be removed in 13.1~ describe PipelineUpdateCiRefStatusWorker do let(:worker) { described_class.new } let(:pipeline) { create(:ci_pipeline) } diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index aab7a36189a..18e06332eb3 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -355,7 +355,7 @@ describe PostReceive do context "webhook" do it "fetches the correct project" do - expect(Project).to receive(:find_by).with(id: project.id.to_s) + expect(Project).to receive(:find_by).with(id: project.id) perform end diff --git a/spec/workers/propagate_integration_worker_spec.rb b/spec/workers/propagate_integration_worker_spec.rb new file mode 100644 index 00000000000..e49869a38e9 --- /dev/null +++ b/spec/workers/propagate_integration_worker_spec.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe PropagateIntegrationWorker do + describe '#perform' do + let(:integration) do + PushoverService.create( + template: true, + active: true, + device: 'MyDevice', + sound: 'mic', + priority: 4, + user_key: 'asdf', + api_key: '123456789' + ) + end + + it 'calls the propagate service with the integration' do + expect(Admin::PropagateIntegrationService).to receive(:propagate) + .with(integration: integration, overwrite: true) + + subject.perform(integration.id, true) + end + end +end diff --git a/spec/workers/remove_expired_group_links_worker_spec.rb b/spec/workers/remove_expired_group_links_worker_spec.rb index 9557aa3086c..b637802cd78 100644 --- a/spec/workers/remove_expired_group_links_worker_spec.rb +++ b/spec/workers/remove_expired_group_links_worker_spec.rb @@ -23,30 +23,53 @@ describe RemoveExpiredGroupLinksWorker do subject.perform expect(non_expiring_project_group_link.reload).to be_present end - end - context 'GroupGroupLinks' do - let(:mock_destroy_service) { instance_double(Groups::GroupLinks::DestroyService) } + it 'removes project authorization' do + user = create(:user) + + project = expired_project_group_link.project + group = expired_project_group_link.group + + group.add_maintainer(user) - before do - allow(Groups::GroupLinks::DestroyService).to( - receive(:new).and_return(mock_destroy_service)) + expect { subject.perform }.to( + change { user.can?(:read_project, project) }.from(true).to(false)) end + end + context 'GroupGroupLinks' do context 'expired GroupGroupLink exists' do - before do - create(:group_group_link, expires_at: 1.hour.ago) - end + let!(:group_group_link) { create(:group_group_link, expires_at: 1.hour.ago) } it 'calls Groups::GroupLinks::DestroyService' do + mock_destroy_service = instance_double(Groups::GroupLinks::DestroyService) + allow(Groups::GroupLinks::DestroyService).to( + receive(:new).and_return(mock_destroy_service)) + expect(mock_destroy_service).to receive(:execute).once subject.perform end + + it 'removes project authorization' do + shared_group = group_group_link.shared_group + shared_with_group = group_group_link.shared_with_group + project = create(:project, group: shared_group) + + user = create(:user) + shared_with_group.add_maintainer(user) + + expect { subject.perform }.to( + change { user.can?(:read_project, project) }.from(true).to(false)) + end end context 'expired GroupGroupLink does not exist' do it 'does not call Groups::GroupLinks::DestroyService' do + mock_destroy_service = instance_double(Groups::GroupLinks::DestroyService) + allow(Groups::GroupLinks::DestroyService).to( + receive(:new).and_return(mock_destroy_service)) + expect(mock_destroy_service).not_to receive(:execute) subject.perform diff --git a/spec/workers/repository_check/single_repository_worker_spec.rb b/spec/workers/repository_check/single_repository_worker_spec.rb index 6870e15424f..43998f912ef 100644 --- a/spec/workers/repository_check/single_repository_worker_spec.rb +++ b/spec/workers/repository_check/single_repository_worker_spec.rb @@ -8,7 +8,7 @@ describe RepositoryCheck::SingleRepositoryWorker do it 'skips when the project has no push events' do project = create(:project, :repository, :wiki_disabled) - project.events.destroy_all # rubocop: disable DestroyAll + project.events.destroy_all # rubocop: disable Cop/DestroyAll break_project(project) expect(worker).not_to receive(:git_fsck) @@ -86,7 +86,7 @@ describe RepositoryCheck::SingleRepositoryWorker do end def create_push_event(project) - project.events.create(action: Event::PUSHED, author_id: create(:user).id) + project.events.create(action: :pushed, author_id: create(:user).id) end def break_wiki(project) diff --git a/spec/workers/stuck_import_jobs_worker_spec.rb b/spec/workers/stuck_import_jobs_worker_spec.rb index dcb8e59ed28..f8d7f8747d5 100644 --- a/spec/workers/stuck_import_jobs_worker_spec.rb +++ b/spec/workers/stuck_import_jobs_worker_spec.rb @@ -5,51 +5,8 @@ require 'spec_helper' describe StuckImportJobsWorker do let(:worker) { described_class.new } - shared_examples 'project import job detection' do - context 'when the job has completed' do - context 'when the import status was already updated' do - before do - allow(Gitlab::SidekiqStatus).to receive(:completed_jids) do - import_state.start - import_state.finish - - [import_state.jid] - end - end - - it 'does not mark the project as failed' do - worker.perform - - expect(import_state.reload.status).to eq('finished') - end - end - - context 'when the import status was not updated' do - before do - allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([import_state.jid]) - end - - it 'marks the project as failed' do - worker.perform - - expect(import_state.reload.status).to eq('failed') - end - end - end - - context 'when the job is still in Sidekiq' do - before do - allow(Gitlab::SidekiqStatus).to receive(:completed_jids).and_return([]) - end - - it 'does not mark the project as failed' do - expect { worker.perform }.not_to change { import_state.reload.status } - end - end - end - describe 'with scheduled import_status' do - it_behaves_like 'project import job detection' do + it_behaves_like 'stuck import job detection' do let(:import_state) { create(:project, :import_scheduled).import_state } before do @@ -59,7 +16,7 @@ describe StuckImportJobsWorker do end describe 'with started import_status' do - it_behaves_like 'project import job detection' do + it_behaves_like 'stuck import job detection' do let(:import_state) { create(:project, :import_started).import_state } before do |