summaryrefslogtreecommitdiff
path: root/spec/models/ci/pipeline_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/ci/pipeline_spec.rb')
-rw-r--r--spec/models/ci/pipeline_spec.rb217
1 files changed, 198 insertions, 19 deletions
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 3f9e882ea52..013581c0d94 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -35,6 +35,7 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to have_one(:source_pipeline) }
it { is_expected.to have_one(:triggered_by_pipeline) }
it { is_expected.to have_one(:source_job) }
+ it { is_expected.to have_one(:pipeline_config) }
it { is_expected.to validate_presence_of(:sha) }
it { is_expected.to validate_presence_of(:status) }
@@ -1007,22 +1008,22 @@ describe Ci::Pipeline, :mailer do
end
end
- describe '#duration', :sidekiq_might_not_need_inline do
+ describe '#duration', :sidekiq_inline do
context 'when multiple builds are finished' do
before do
travel_to(current + 30) do
build.run!
- build.success!
+ build.reload.success!
build_b.run!
build_c.run!
end
travel_to(current + 40) do
- build_b.drop!
+ build_b.reload.drop!
end
travel_to(current + 70) do
- build_c.success!
+ build_c.reload.success!
end
end
@@ -1043,7 +1044,7 @@ describe Ci::Pipeline, :mailer do
end
travel_to(current + 5.minutes) do
- build.success!
+ build.reload.success!
end
end
@@ -1182,6 +1183,38 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe 'auto devops pipeline metrics' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:pipeline) { create(:ci_empty_pipeline, config_source: config_source) }
+ let(:config_source) { :auto_devops_source }
+
+ where(:action, :status) do
+ :succeed | 'success'
+ :drop | 'failed'
+ :skip | 'skipped'
+ :cancel | 'canceled'
+ end
+
+ with_them do
+ context "when pipeline receives action '#{params[:action]}'" do
+ subject { pipeline.public_send(action) }
+
+ it { expect { subject }.to change { auto_devops_pipelines_completed_total(status) }.by(1) }
+
+ context 'when not auto_devops_source?' do
+ let(:config_source) { :repository_source }
+
+ it { expect { subject }.not_to change { auto_devops_pipelines_completed_total(status) } }
+ end
+ end
+ end
+
+ def auto_devops_pipelines_completed_total(status)
+ Gitlab::Metrics.counter(:auto_devops_pipelines_completed_total, 'Number of completed auto devops pipelines').get(status: status)
+ end
+ end
+
def create_build(name, *traits, queued_at: current, started_from: 0, **opts)
create(:ci_build, *traits,
name: name,
@@ -1552,6 +1585,30 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#needs_processing?' do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { pipeline.needs_processing? }
+
+ where(:processed, :result) do
+ nil | true
+ false | true
+ true | false
+ end
+
+ with_them do
+ let(:build) do
+ create(:ci_build, :success, pipeline: pipeline, name: 'rubocop')
+ end
+
+ before do
+ build.update_column(:processed, processed)
+ end
+
+ it { is_expected.to eq(result) }
+ end
+ end
+
shared_context 'with some outdated pipelines' do
before do
create_pipeline(:canceled, 'ref', 'A', project)
@@ -1749,16 +1806,27 @@ describe Ci::Pipeline, :mailer do
subject { described_class.bridgeable_statuses }
it { is_expected.to be_an(Array) }
- it { is_expected.not_to include('created', 'preparing', 'pending') }
+ it { is_expected.not_to include('created', 'waiting_for_resource', 'preparing', 'pending') }
end
- describe '#status', :sidekiq_might_not_need_inline do
+ describe '#status', :sidekiq_inline do
let(:build) do
create(:ci_build, :created, pipeline: pipeline, name: 'test')
end
subject { pipeline.reload.status }
+ context 'on waiting for resource' do
+ before do
+ allow(build).to receive(:requires_resource?) { true }
+ allow(Ci::ResourceGroups::AssignResourceFromResourceGroupWorker).to receive(:perform_async)
+
+ build.enqueue
+ end
+
+ it { is_expected.to eq('waiting_for_resource') }
+ end
+
context 'on prepare' do
before do
# Prevent skipping directly to 'pending'
@@ -1782,7 +1850,7 @@ describe Ci::Pipeline, :mailer do
context 'on run' do
before do
build.enqueue
- build.run
+ build.reload.run
end
it { is_expected.to eq('running') }
@@ -1841,7 +1909,7 @@ describe Ci::Pipeline, :mailer do
it 'updates does not change pipeline status' do
expect(pipeline.statuses.latest.slow_composite_status).to be_nil
- expect { pipeline.update_status }
+ expect { pipeline.update_legacy_status }
.to change { pipeline.reload.status }
.from('created')
.to('skipped')
@@ -1854,7 +1922,7 @@ describe Ci::Pipeline, :mailer do
end
it 'updates pipeline status to running' do
- expect { pipeline.update_status }
+ expect { pipeline.update_legacy_status }
.to change { pipeline.reload.status }
.from('created')
.to('running')
@@ -1867,7 +1935,7 @@ describe Ci::Pipeline, :mailer do
end
it 'updates pipeline status to scheduled' do
- expect { pipeline.update_status }
+ expect { pipeline.update_legacy_status }
.to change { pipeline.reload.status }
.from('created')
.to('scheduled')
@@ -1882,7 +1950,7 @@ describe Ci::Pipeline, :mailer do
end
it 'raises an exception' do
- expect { pipeline.update_status }
+ expect { pipeline.update_legacy_status }
.to raise_error(HasStatus::UnknownStatusError)
end
end
@@ -2170,11 +2238,11 @@ describe Ci::Pipeline, :mailer do
stub_full_request(hook.url, method: :post)
end
- context 'with multiple builds', :sidekiq_might_not_need_inline do
+ context 'with multiple builds', :sidekiq_inline do
context 'when build is queued' do
before do
- build_a.enqueue
- build_b.enqueue
+ build_a.reload.enqueue
+ build_b.reload.enqueue
end
it 'receives a pending event once' do
@@ -2184,10 +2252,10 @@ describe Ci::Pipeline, :mailer do
context 'when build is run' do
before do
- build_a.enqueue
- build_a.run
- build_b.enqueue
- build_b.run
+ build_a.reload.enqueue
+ build_a.reload.run!
+ build_b.reload.enqueue
+ build_b.reload.run!
end
it 'receives a running event once' do
@@ -2248,6 +2316,7 @@ describe Ci::Pipeline, :mailer do
:created,
pipeline: pipeline,
name: name,
+ stage: "stage:#{stage_idx}",
stage_idx: stage_idx)
end
end
@@ -2704,4 +2773,114 @@ describe Ci::Pipeline, :mailer do
end
end
end
+
+ describe '#parent_pipeline' do
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ context 'when pipeline is triggered by a pipeline from the same project' do
+ let(:upstream_pipeline) { create(:ci_pipeline, project: pipeline.project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_pipeline: upstream_pipeline,
+ source_project: project,
+ pipeline: pipeline,
+ project: project)
+ end
+
+ it 'returns the parent pipeline' do
+ expect(pipeline.parent_pipeline).to eq(upstream_pipeline)
+ end
+
+ it 'is child' do
+ expect(pipeline).to be_child
+ end
+ end
+
+ context 'when pipeline is triggered by a pipeline from another project' do
+ let(:upstream_pipeline) { create(:ci_pipeline) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_pipeline: upstream_pipeline,
+ source_project: upstream_pipeline.project,
+ pipeline: pipeline,
+ project: project)
+ end
+
+ it 'returns nil' do
+ expect(pipeline.parent_pipeline).to be_nil
+ end
+
+ it 'is not child' do
+ expect(pipeline).not_to be_child
+ end
+ end
+
+ context 'when pipeline is not triggered by a pipeline' do
+ it 'returns nil' do
+ expect(pipeline.parent_pipeline).to be_nil
+ end
+
+ it 'is not child' do
+ expect(pipeline).not_to be_child
+ end
+ end
+ end
+
+ describe '#child_pipelines' do
+ let(:project) { create(:project) }
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ context 'when pipeline triggered other pipelines on same project' do
+ let(:downstream_pipeline) { create(:ci_pipeline, project: pipeline.project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_pipeline: pipeline,
+ source_project: pipeline.project,
+ pipeline: downstream_pipeline,
+ project: pipeline.project)
+ end
+
+ it 'returns the child pipelines' do
+ expect(pipeline.child_pipelines).to eq [downstream_pipeline]
+ end
+
+ it 'is parent' do
+ expect(pipeline).to be_parent
+ end
+ end
+
+ context 'when pipeline triggered other pipelines on another project' do
+ let(:downstream_pipeline) { create(:ci_pipeline) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_pipeline: pipeline,
+ source_project: pipeline.project,
+ pipeline: downstream_pipeline,
+ project: downstream_pipeline.project)
+ end
+
+ it 'returns empty array' do
+ expect(pipeline.child_pipelines).to be_empty
+ end
+
+ it 'is not parent' do
+ expect(pipeline).not_to be_parent
+ end
+ end
+
+ context 'when pipeline did not trigger any pipelines' do
+ it 'returns empty array' do
+ expect(pipeline.child_pipelines).to be_empty
+ end
+
+ it 'is not parent' do
+ expect(pipeline).not_to be_parent
+ end
+ end
+ end
end