diff options
Diffstat (limited to 'spec/lib/gitlab/ci/pipeline/seed/build_spec.rb')
-rw-r--r-- | spec/lib/gitlab/ci/pipeline/seed/build_spec.rb | 282 |
1 files changed, 221 insertions, 61 deletions
diff --git a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb index 0efc7484699..7ec6949f852 100644 --- a/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/seed/build_spec.rb @@ -85,99 +85,169 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do { key: 'VAR2', value: 'var 2', public: true }, { key: 'VAR3', value: 'var 3', public: true }]) end + end - context 'when FF ci_rules_variables is disabled' do - before do - stub_feature_flags(ci_rules_variables: false) - end + context 'with multiple_cache_per_job FF disabled' do + before do + stub_feature_flags(multiple_cache_per_job: false) + end - it do - is_expected.to include(yaml_variables: [{ key: 'VAR1', value: 'var 1', public: true }, - { key: 'VAR2', value: 'var 2', public: true }]) + context 'with cache:key' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: { + key: 'a-value' + } + } end + + it { is_expected.to include(options: { cache: { key: 'a-value' } }) } end - end - context 'with cache:key' do - let(:attributes) do - { - name: 'rspec', - ref: 'master', - cache: { - key: 'a-value' + context 'with cache:key:files' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: { + key: { + files: ['VERSION'] + } + } } - } - end + end - it { is_expected.to include(options: { cache: { key: 'a-value' } }) } - end + it 'includes cache options' do + cache_options = { + options: { + cache: { key: 'f155568ad0933d8358f66b846133614f76dd0ca4' } + } + } - context 'with cache:key:files' do - let(:attributes) do - { - name: 'rspec', - ref: 'master', - cache: { - key: { - files: ['VERSION'] + is_expected.to include(cache_options) + end + end + + context 'with cache:key:prefix' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: { + key: { + prefix: 'something' + } } } - } + end + + it { is_expected.to include(options: { cache: { key: 'something-default' } }) } end - it 'includes cache options' do - cache_options = { - options: { + context 'with cache:key:files and prefix' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', cache: { - key: 'f155568ad0933d8358f66b846133614f76dd0ca4' + key: { + files: ['VERSION'], + prefix: 'something' + } } } - } + end - is_expected.to include(cache_options) + it 'includes cache options' do + cache_options = { + options: { + cache: { key: 'something-f155568ad0933d8358f66b846133614f76dd0ca4' } + } + } + + is_expected.to include(cache_options) + end end end - context 'with cache:key:prefix' do + context 'with cache:key' do let(:attributes) do { name: 'rspec', ref: 'master', - cache: { - key: { - prefix: 'something' - } - } + cache: [{ + key: 'a-value' + }] } end - it { is_expected.to include(options: { cache: { key: 'something-default' } }) } - end + it { is_expected.to include(options: { cache: [a_hash_including(key: 'a-value')] }) } - context 'with cache:key:files and prefix' do - let(:attributes) do - { - name: 'rspec', - ref: 'master', - cache: { - key: { - files: ['VERSION'], - prefix: 'something' + context 'with cache:key:files' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: [{ + key: { + files: ['VERSION'] + } + }] + } + end + + it 'includes cache options' do + cache_options = { + options: { + cache: [a_hash_including(key: 'f155568ad0933d8358f66b846133614f76dd0ca4')] } } - } + + is_expected.to include(cache_options) + end end - it 'includes cache options' do - cache_options = { - options: { - cache: { - key: 'something-f155568ad0933d8358f66b846133614f76dd0ca4' + context 'with cache:key:prefix' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: [{ + key: { + prefix: 'something' + } + }] + } + end + + it { is_expected.to include(options: { cache: [a_hash_including( key: 'something-default' )] }) } + end + + context 'with cache:key:files and prefix' do + let(:attributes) do + { + name: 'rspec', + ref: 'master', + cache: [{ + key: { + files: ['VERSION'], + prefix: 'something' + } + }] + } + end + + it 'includes cache options' do + cache_options = { + options: { + cache: [a_hash_including(key: 'something-f155568ad0933d8358f66b846133614f76dd0ca4')] } } - } - is_expected.to include(cache_options) + is_expected.to include(cache_options) + end end end @@ -190,7 +260,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do } end - it { is_expected.to include(options: {}) } + it { is_expected.to include({}) } end context 'with allow_failure' do @@ -307,7 +377,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do it 'does not have environment' do expect(subject).not_to be_has_environment expect(subject.environment).to be_nil - expect(subject.metadata.expanded_environment_name).to be_nil + expect(subject.metadata).to be_nil expect(Environment.exists?(name: expected_environment_name)).to eq(false) end end @@ -979,6 +1049,25 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do expect(subject.errors).to contain_exactly( "'rspec' job needs 'build' job, but it was not added to the pipeline") end + + context 'when the needed job is optional' do + let(:needs_attributes) { [{ name: 'build', optional: true }] } + + it "does not return an error" do + expect(subject.errors).to be_empty + end + + context 'when the FF ci_needs_optional is disabled' do + before do + stub_feature_flags(ci_needs_optional: false) + end + + it "returns an error" do + expect(subject.errors).to contain_exactly( + "'rspec' job needs 'build' job, but it was not added to the pipeline") + end + end + end end context 'when build job is part of prior stages' do @@ -1036,4 +1125,75 @@ RSpec.describe Gitlab::Ci::Pipeline::Seed::Build do end end end + + describe 'applying pipeline variables' do + subject { seed_build } + + let(:pipeline_variables) { [] } + let(:pipeline) do + build(:ci_empty_pipeline, project: project, sha: head_sha, variables: pipeline_variables) + end + + context 'containing variable references' do + let(:pipeline_variables) do + [ + build(:ci_pipeline_variable, key: 'A', value: '$B'), + build(:ci_pipeline_variable, key: 'B', value: '$C') + ] + end + + context 'when FF :variable_inside_variable is enabled' do + before do + stub_feature_flags(variable_inside_variable: [project]) + end + + it "does not have errors" do + expect(subject.errors).to be_empty + end + end + end + + context 'containing cyclic reference' do + let(:pipeline_variables) do + [ + build(:ci_pipeline_variable, key: 'A', value: '$B'), + build(:ci_pipeline_variable, key: 'B', value: '$C'), + build(:ci_pipeline_variable, key: 'C', value: '$A') + ] + end + + context 'when FF :variable_inside_variable is disabled' do + before do + stub_feature_flags(variable_inside_variable: false) + end + + it "does not have errors" do + expect(subject.errors).to be_empty + end + end + + context 'when FF :variable_inside_variable is enabled' do + before do + stub_feature_flags(variable_inside_variable: [project]) + end + + it "returns an error" do + expect(subject.errors).to contain_exactly( + 'rspec: circular variable reference detected: ["A", "B", "C"]') + end + + context 'with job:rules:[if:]' do + let(:attributes) { { name: 'rspec', ref: 'master', rules: [{ if: '$C != null', when: 'always' }] } } + + it "included? does not raise" do + expect { subject.included? }.not_to raise_error + end + + it "included? returns true" do + expect(subject.included?).to eq(true) + end + end + end + end + end end |