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:
Diffstat (limited to 'spec/lib/gitlab/ci/pipeline')
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb21
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb64
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/populate_metadata_spec.rb172
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb25
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb7
6 files changed, 280 insertions, 24 deletions
diff --git a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
index 31bffcbeb2a..00f834fcf80 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines, feature_category: :continuous_integration do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
- let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project) }
let_it_be(:command) { Gitlab::Ci::Pipeline::Chain::Command.new(project: project, current_user: user) }
let_it_be(:step) { described_class.new(pipeline, command) }
@@ -17,5 +17,18 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines, feature_cate
subject
end
+
+ context 'with scheduled pipelines' do
+ before do
+ pipeline.source = :schedule
+ end
+
+ it 'enqueues LowUrgencyCancelRedundantPipelinesWorker' do
+ expect(Ci::LowUrgencyCancelRedundantPipelinesWorker)
+ .to receive(:perform_async).with(pipeline.id)
+
+ subject
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb
index eb5a37f19f4..44ccb1eeae1 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb
@@ -12,10 +12,13 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules do
end
let(:step) { described_class.new(pipeline, command) }
+ let(:ff_always_set_pipeline_failure_reason) { true }
describe '#perform!' do
context 'when pipeline has been skipped by workflow configuration' do
before do
+ stub_feature_flags(always_set_pipeline_failure_reason: ff_always_set_pipeline_failure_reason)
+
allow(step).to receive(:workflow_rules_result)
.and_return(
double(pass?: false, variables: {})
@@ -39,6 +42,20 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules do
it 'saves workflow_rules_result' do
expect(command.workflow_rules_result.variables).to eq({})
end
+
+ it 'sets the failure reason', :aggregate_failures do
+ expect(pipeline).to be_failed
+ expect(pipeline).to be_filtered_by_workflow_rules
+ end
+
+ context 'when always_set_pipeline_failure_reason is disabled' do
+ let(:ff_always_set_pipeline_failure_reason) { false }
+
+ it 'does not set the failure reason', :aggregate_failures do
+ expect(pipeline).not_to be_failed
+ expect(pipeline.failure_reason).to be_blank
+ end
+ end
end
context 'when pipeline has not been skipped by workflow configuration' do
@@ -67,6 +84,10 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules do
it 'saves workflow_rules_result' do
expect(command.workflow_rules_result.variables).to eq({ 'VAR1' => 'val2', 'VAR2' => 3 })
end
+
+ it 'does not set a failure reason' do
+ expect(pipeline).not_to be_filtered_by_workflow_rules
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb
index 96ada90b4e1..84c2fb6525e 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Pipeline::Chain::Helpers do
+RSpec.describe Gitlab::Ci::Pipeline::Chain::Helpers, feature_category: :continuous_integration do
let(:helper_class) do
Class.new do
include Gitlab::Ci::Pipeline::Chain::Helpers
@@ -38,14 +38,35 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Helpers do
describe '.error' do
shared_examples 'error function' do
specify do
- expect(pipeline).to receive(:drop!).with(drop_reason).and_call_original
expect(pipeline).to receive(:add_error_message).with(message).and_call_original
- expect(pipeline).to receive(:ensure_project_iid!).twice.and_call_original
+
+ if command.save_incompleted
+ expect(pipeline).to receive(:ensure_project_iid!).twice.and_call_original
+ expect(pipeline).to receive(:drop!).with(drop_reason).and_call_original
+ end
subject.error(message, config_error: config_error, drop_reason: drop_reason)
expect(pipeline.yaml_errors).to eq(yaml_error)
expect(pipeline.errors[:base]).to include(message)
+ expect(pipeline.status).to eq 'failed'
+ expect(pipeline.failure_reason).to eq drop_reason.to_s
+ end
+
+ context 'when feature flag always_set_pipeline_failure_reason is false' do
+ before do
+ stub_feature_flags(always_set_pipeline_failure_reason: false)
+ end
+
+ specify do
+ subject.error(message, config_error: config_error, drop_reason: drop_reason)
+
+ if command.save_incompleted
+ expect(pipeline.failure_reason).to eq drop_reason.to_s
+ else
+ expect(pipeline.failure_reason).not_to be_present
+ end
+ end
end
end
@@ -79,6 +100,43 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Helpers do
let(:yaml_error) { nil }
it_behaves_like "error function"
+
+ specify do
+ subject.error(message, config_error: config_error, drop_reason: drop_reason)
+
+ expect(pipeline).to be_persisted
+ end
+
+ context ' when the drop reason is not persistable' do
+ let(:drop_reason) { :filtered_by_rules }
+ let(:command) { double(project: nil) }
+
+ specify do
+ expect(command).to receive(:increment_pipeline_failure_reason_counter)
+
+ subject.error(message, config_error: config_error, drop_reason: drop_reason)
+
+ expect(pipeline).to be_failed
+ expect(pipeline.failure_reason).to eq drop_reason.to_s
+ expect(pipeline).not_to be_persisted
+ end
+ end
+
+ context 'when save_incompleted is false' do
+ let(:command) { double(save_incompleted: false, project: nil) }
+
+ before do
+ allow(command).to receive(:increment_pipeline_failure_reason_counter)
+ end
+
+ it_behaves_like "error function"
+
+ specify do
+ subject.error(message, config_error: config_error, drop_reason: drop_reason)
+
+ expect(pipeline).not_to be_persisted
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/populate_metadata_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/populate_metadata_spec.rb
index 00200b57b1e..732748d8c8b 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/populate_metadata_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/populate_metadata_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Pipeline::Chain::PopulateMetadata do
+RSpec.describe Gitlab::Ci::Pipeline::Chain::PopulateMetadata, feature_category: :pipeline_composition do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
@@ -43,16 +43,28 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::PopulateMetadata do
stub_ci_pipeline_yaml_file(YAML.dump(config))
end
- context 'with pipeline name' do
- let(:config) do
- { workflow: { name: ' Pipeline name ' }, rspec: { script: 'rspec' } }
- end
-
+ shared_examples 'not breaking the chain' do
it 'does not break the chain' do
run_chain
expect(step.break?).to be false
end
+ end
+
+ shared_examples 'not saving pipeline metadata' do
+ it 'does not save pipeline metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata).to be_nil
+ end
+ end
+
+ context 'with pipeline name' do
+ let(:config) do
+ { workflow: { name: ' Pipeline name ' }, rspec: { script: 'rspec' } }
+ end
+
+ it_behaves_like 'not breaking the chain'
it 'builds pipeline_metadata' do
run_chain
@@ -67,22 +79,14 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::PopulateMetadata do
{ workflow: { name: ' ' }, rspec: { script: 'rspec' } }
end
- it 'strips whitespace from name' do
- run_chain
-
- expect(pipeline.pipeline_metadata).to be_nil
- end
+ it_behaves_like 'not saving pipeline metadata'
context 'with empty name after variable substitution' do
let(:config) do
{ workflow: { name: '$VAR1' }, rspec: { script: 'rspec' } }
end
- it 'does not save empty name' do
- run_chain
-
- expect(pipeline.pipeline_metadata).to be_nil
- end
+ it_behaves_like 'not saving pipeline metadata'
end
end
@@ -127,4 +131,140 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::PopulateMetadata do
end
end
end
+
+ context 'with auto_cancel' do
+ let(:on_new_commit) { 'interruptible' }
+ let(:on_job_failure) { 'all' }
+ let(:auto_cancel) { { on_new_commit: on_new_commit, on_job_failure: on_job_failure } }
+ let(:config) { { workflow: { auto_cancel: auto_cancel }, rspec: { script: 'rspec' } } }
+
+ it_behaves_like 'not breaking the chain'
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('interruptible')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('all')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+
+ context 'with no auto_cancel' do
+ let(:config) do
+ { rspec: { script: 'rspec' } }
+ end
+
+ it_behaves_like 'not saving pipeline metadata'
+ end
+
+ context 'with auto_cancel: nil' do
+ let(:auto_cancel) { nil }
+
+ it_behaves_like 'not saving pipeline metadata'
+ end
+
+ context 'with auto_cancel_on_new_commit and no auto_cancel_on_job_failure' do
+ let(:auto_cancel) { { on_new_commit: on_new_commit } }
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('interruptible')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('none')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+
+ context 'with auto_cancel_on_job_failure and no auto_cancel_on_new_commit' do
+ let(:auto_cancel) { { on_job_failure: on_job_failure } }
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('conservative')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('all')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+
+ context 'with auto_cancel_on_new_commit: nil and auto_cancel_on_job_failure: nil' do
+ let(:on_new_commit) { nil }
+ let(:on_job_failure) { nil }
+
+ it_behaves_like 'not saving pipeline metadata'
+ end
+
+ context 'with auto_cancel_on_new_commit valid and auto_cancel_on_job_failure: nil' do
+ let(:on_job_failure) { nil }
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('interruptible')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('none')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+
+ context 'with auto_cancel_on_new_commit: nil and auto_cancel_on_job_failure valid' do
+ let(:on_new_commit) { nil }
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('conservative')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('all')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+
+ context 'when auto_cancel_on_job_failure: none' do
+ let(:on_job_failure) { 'none' }
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('none')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+
+ context 'when auto_cancel_pipeline_on_job_failure feature is disabled' do
+ before do
+ stub_feature_flags(auto_cancel_pipeline_on_job_failure: false)
+ end
+
+ it 'ignores the auto_cancel_on_job_failure value' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('none')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
+ end
+
+ context 'with both pipeline name and auto_cancel' do
+ let(:config) do
+ {
+ workflow: {
+ name: 'Pipeline name',
+ auto_cancel: {
+ on_new_commit: 'interruptible',
+ on_job_failure: 'none'
+ }
+ },
+ rspec: { script: 'rspec' }
+ }
+ end
+
+ it_behaves_like 'not breaking the chain'
+
+ it 'builds pipeline_metadata' do
+ run_chain
+
+ expect(pipeline.pipeline_metadata.name).to eq('Pipeline name')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_new_commit).to eq('interruptible')
+ expect(pipeline.pipeline_metadata.auto_cancel_on_job_failure).to eq('none')
+ expect(pipeline.pipeline_metadata).not_to be_persisted
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
index 91bb94bbb11..476b1be35a9 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/populate_spec.rb
@@ -34,12 +34,15 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Populate, feature_category: :continu
{ rspec: { script: 'rspec' } }
end
+ let(:ff_always_set_pipeline_failure_reason) { true }
+
def run_chain
dependencies.map(&:perform!)
step.perform!
end
before do
+ stub_feature_flags(always_set_pipeline_failure_reason: ff_always_set_pipeline_failure_reason)
stub_ci_pipeline_yaml_file(YAML.dump(config))
end
@@ -100,7 +103,27 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Populate, feature_category: :continu
it 'increments the error metric' do
counter = Gitlab::Metrics.counter(:gitlab_ci_pipeline_failure_reasons, 'desc')
- expect { run_chain }.to change { counter.get(reason: 'unknown_failure') }.by(1)
+ expect { run_chain }.to change { counter.get(reason: 'filtered_by_rules') }.by(1)
+ end
+
+ it 'sets the failure reason without persisting the pipeline', :aggregate_failures do
+ run_chain
+
+ expect(pipeline).not_to be_persisted
+ expect(pipeline).to be_failed
+ expect(pipeline).to be_filtered_by_rules
+ end
+
+ context 'when ff always_set_pipeline_failure_reason is disabled' do
+ let(:ff_always_set_pipeline_failure_reason) { false }
+
+ it 'sets the failure reason without persisting the pipeline', :aggregate_failures do
+ run_chain
+
+ expect(pipeline).not_to be_persisted
+ expect(pipeline).not_to be_failed
+ expect(pipeline).not_to be_filtered_by_rules
+ end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb
index 52a00e0d501..4017076d29f 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/validate/external_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::External do
+RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::External, feature_category: :continuous_integration do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user, :with_sign_ins) }
@@ -328,11 +328,12 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::External do
context 'when save_incompleted is false' do
let(:save_incompleted) { false }
- it 'adds errors to the pipeline without dropping it' do
+ it 'adds errors to the pipeline without persisting it', :aggregate_failures do
perform!
- expect(pipeline.status).to eq('pending')
expect(pipeline).not_to be_persisted
+ expect(pipeline.status).to eq('failed')
+ expect(pipeline).to be_external_validation_failure
expect(pipeline.errors.to_a).to include('External validation failed')
end