diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-19 17:16:28 +0300 |
commit | e4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch) | |
tree | 2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /spec/lib/gitlab/ci | |
parent | ffda4e7bcac36987f936b4ba515995a6698698f0 (diff) |
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'spec/lib/gitlab/ci')
25 files changed, 387 insertions, 637 deletions
diff --git a/spec/lib/gitlab/ci/artifact_file_reader_spec.rb b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb index 76a596e1db3..ff918bbe558 100644 --- a/spec/lib/gitlab/ci/artifact_file_reader_spec.rb +++ b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::ArtifactFileReader do +RSpec.describe Gitlab::Ci::ArtifactFileReader, feature_category: :pipeline_composition do let(:job) { create(:ci_build) } let(:path) { 'generated.yml' } # included in the ci_build_artifacts.zip @@ -138,8 +138,8 @@ RSpec.describe Gitlab::Ci::ArtifactFileReader do end context 'when job does not have artifacts' do - it 'raises ArgumentError' do - expect { subject }.to raise_error(ArgumentError, 'Job does not have artifacts') + it 'raises an Error' do + expect { subject }.to raise_error(described_class::Error, 'Job does not have artifacts') end end end diff --git a/spec/lib/gitlab/ci/build/rules_spec.rb b/spec/lib/gitlab/ci/build/rules_spec.rb index 9f191fed581..99577539798 100644 --- a/spec/lib/gitlab/ci/build/rules_spec.rb +++ b/spec/lib/gitlab/ci/build/rules_spec.rb @@ -244,59 +244,6 @@ RSpec.describe Gitlab::Ci::Build::Rules, feature_category: :pipeline_composition when: 'never' }])) } end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(introduce_rules_with_needs: false) - end - - context 'with needs' do - context 'when single need is specified' do - let(:rule_list) do - [{ if: '$VAR == null', needs: [{ name: 'test', artifacts: true, optional: false }] }] - end - - it { - is_expected.to eq(described_class::Result.new(when: 'on_success')) - } - end - - context 'when multiple needs are specified' do - let(:rule_list) do - [{ if: '$VAR == null', - needs: [{ name: 'test', artifacts: true, optional: false }, - { name: 'rspec', artifacts: true, optional: false }] }] - end - - it { - is_expected.to eq(described_class::Result.new(when: 'on_success')) - } - end - - context 'when there are no needs specified' do - let(:rule_list) { [{ if: '$VAR == null' }] } - - it { - is_expected.to eq(described_class::Result.new(when: 'on_success')) - } - end - - context 'when need is specified with additional attibutes' do - let(:rule_list) do - [{ if: '$VAR == null', needs: [{ - artifacts: false, - name: 'test', - optional: true, - when: 'never' - }] }] - end - - it { - is_expected.to eq(described_class::Result.new(when: 'on_success')) - } - end - end - end end context 'with variables' do diff --git a/spec/lib/gitlab/ci/components/instance_path_spec.rb b/spec/lib/gitlab/ci/components/instance_path_spec.rb index b80422d03e5..511036efd37 100644 --- a/spec/lib/gitlab/ci/components/instance_path_spec.rb +++ b/spec/lib/gitlab/ci/components/instance_path_spec.rb @@ -101,30 +101,22 @@ RSpec.describe Gitlab::Ci::Components::InstancePath, feature_category: :pipeline context 'when version is `~latest`' do let(:version) { '~latest' } - context 'when project is a catalog resource' do - before do - create(:catalog_resource, project: existing_project) + context 'when project has releases' do + let_it_be(:latest_release) do + create(:release, project: existing_project, sha: 'sha-1', released_at: Time.zone.now) end - context 'when project has releases' do - let_it_be(:releases) do - [ - create(:release, project: existing_project, sha: 'sha-1', released_at: Time.zone.now - 1.day), - create(:release, project: existing_project, sha: 'sha-2', released_at: Time.zone.now) - ] - end - - it 'returns the sha of the latest release' do - expect(path.sha).to eq(releases.last.sha) - end + before(:all) do + # Previous release + create(:release, project: existing_project, sha: 'sha-2', released_at: Time.zone.now - 1.day) end - context 'when project does not have releases' do - it { expect(path.sha).to be_nil } + it 'returns the sha of the latest release' do + expect(path.sha).to eq(latest_release.sha) end end - context 'when project is not a catalog resource' do + context 'when project does not have releases' do it { expect(path.sha).to be_nil } end end diff --git a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb index 1f4586bd5a9..c7f18f0d01a 100644 --- a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb @@ -41,6 +41,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : it 'sets the expected error' do expect(valid?).to be_falsy expect(external_file.errors).to contain_exactly(expected_error) + expect(external_file.content).to eq(nil) end end @@ -139,7 +140,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : before do allow_next_instance_of(Gitlab::Ci::ArtifactFileReader) do |reader| - allow(reader).to receive(:read).and_return('') + allow(reader).to receive(:read).and_return(nil) end end @@ -165,8 +166,8 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : } expect(context).to receive(:mutate).with(expected_attrs).and_call_original - expect(valid?).to be_truthy external_file.content + expect(valid?).to be_truthy end end end diff --git a/spec/lib/gitlab/ci/config/external/file/base_spec.rb b/spec/lib/gitlab/ci/config/external/file/base_spec.rb index 1c5918f77ca..d6dd75f4b10 100644 --- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb @@ -106,7 +106,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base, feature_category: :pipe it 'is not a valid file' do expect(valid?).to be_falsy expect(file.error_message) - .to eq('`some/file/xxxxxxxxxxxxxxxx.yml`: content does not have a valid YAML syntax') + .to eq('`some/file/xxxxxxxxxxxxxxxx.yml`: Invalid configuration format') end end @@ -128,31 +128,6 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base, feature_category: :pipe end end - context 'when interpolation is disabled but there is a spec header' do - before do - stub_feature_flags(ci_includable_files_interpolation: false) - end - - let(:location) { 'some-location.yml' } - - let(:content) do - <<~YAML - spec: - include: - website: - --- - run: - script: deploy $[[ inputs.website ]] - YAML - end - - it 'returns an error saying that interpolation is disabled' do - expect(valid?).to be_falsy - expect(file.errors) - .to include('`some-location.yml`: can not evaluate included file because interpolation is disabled') - end - end - context 'when interpolation was unsuccessful' do let(:location) { 'some-location.yml' } @@ -275,4 +250,17 @@ RSpec.describe Gitlab::Ci::Config::External::File::Base, feature_category: :pipe it { is_expected.to eq([{ location: location, content: content }, nil, 'HEAD'].hash) } end end + + describe '#load_and_validate_expanded_hash!' do + let(:location) { 'some/file/config.yml' } + let(:logger) { instance_double(::Gitlab::Ci::Pipeline::Logger, :instrument) } + let(:context_params) { { sha: 'HEAD', variables: variables, project: project, logger: logger } } + + it 'includes instrumentation for loading and expanding the content' do + expect(logger).to receive(:instrument).once.ordered.with(:config_file_fetch_content_hash).and_yield + expect(logger).to receive(:instrument).once.ordered.with(:config_file_expand_content_includes).and_yield + + file.load_and_validate_expanded_hash! + end + end end diff --git a/spec/lib/gitlab/ci/config/external/file/component_spec.rb b/spec/lib/gitlab/ci/config/external/file/component_spec.rb index fe811bce9fe..7e3406413d0 100644 --- a/spec/lib/gitlab/ci/config/external/file/component_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/component_spec.rb @@ -121,7 +121,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Component, feature_category: it 'is invalid' do expect(subject).to be_falsy - expect(external_resource.error_message).to match(/does not have a valid YAML syntax/) + expect(external_resource.error_message).to match(/Invalid configuration format/) end end end diff --git a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb index 4da3e7e51a7..1a2a6c5beeb 100644 --- a/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb @@ -29,18 +29,5 @@ RSpec.describe Gitlab::Ci::Config::External::Mapper::Filter, feature_category: : [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }] ) end - - context 'when FF `ci_support_include_rules_when_never` is disabled' do - before do - stub_feature_flags(ci_support_include_rules_when_never: false) - end - - it 'filters locations according to rules ignoring when:' do - is_expected.to eq( - [{ local: 'config/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1' }] }, - { remote: 'https://testing.com/.gitlab-ci.yml', rules: [{ if: '$VARIABLE1', when: 'never' }] }] - ) - end - end end end diff --git a/spec/lib/gitlab/ci/config/external/processor_spec.rb b/spec/lib/gitlab/ci/config/external/processor_spec.rb index 74afb3b1e97..935b6989dd7 100644 --- a/spec/lib/gitlab/ci/config/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/config/external/processor_spec.rb @@ -221,7 +221,7 @@ RSpec.describe Gitlab::Ci::Config::External::Processor, feature_category: :pipel it 'raises an error' do expect { processor.perform }.to raise_error( described_class::IncludeError, - '`lib/gitlab/ci/templates/template.yml`: content does not have a valid YAML syntax' + '`lib/gitlab/ci/templates/template.yml`: Invalid configuration format' ) end end diff --git a/spec/lib/gitlab/ci/config/external/rules_spec.rb b/spec/lib/gitlab/ci/config/external/rules_spec.rb index 1ba5caa1d4b..25b7998ef5e 100644 --- a/spec/lib/gitlab/ci/config/external/rules_spec.rb +++ b/spec/lib/gitlab/ci/config/external/rules_spec.rb @@ -3,8 +3,7 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_composition do - # Remove `project` property when FF `ci_support_include_rules_when_never` is removed - let(:context) { double(variables_hash: {}, project: nil) } + let(:context) { double(variables_hash: {}) } let(:rule_hashes) { [{ if: '$MY_VAR == "hello"' }] } subject(:rules) { described_class.new(rule_hashes) } @@ -19,11 +18,6 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_ end shared_examples 'when there is a rule with if' do |rule_matched_result = true, rule_not_matched_result = false| - # Remove this `before` block when FF `ci_support_include_rules_when_never` is removed - before do - allow(context).to receive(:project).and_return(nil) - end - context 'when the rule matches' do let(:context) { double(variables_hash: { 'MY_VAR' => 'hello' }) } @@ -70,28 +64,12 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_ let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'never' }] } it_behaves_like 'when there is a rule with if', false, false - - context 'when FF `ci_support_include_rules_when_never` is disabled' do - before do - stub_feature_flags(ci_support_include_rules_when_never: false) - end - - it_behaves_like 'when there is a rule with if' - end end context 'with when: always' do let(:rule_hashes) { [{ if: '$MY_VAR == "hello"', when: 'always' }] } it_behaves_like 'when there is a rule with if' - - context 'when FF `ci_support_include_rules_when_never` is disabled' do - before do - stub_feature_flags(ci_support_include_rules_when_never: false) - end - - it_behaves_like 'when there is a rule with if' - end end context 'with when: <invalid string>' do @@ -115,28 +93,12 @@ RSpec.describe Gitlab::Ci::Config::External::Rules, feature_category: :pipeline_ let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'never' }] } it_behaves_like 'when there is a rule with exists', false, false - - context 'when FF `ci_support_include_rules_when_never` is disabled' do - before do - stub_feature_flags(ci_support_include_rules_when_never: false) - end - - it_behaves_like 'when there is a rule with exists' - end end context 'with when: always' do let(:rule_hashes) { [{ exists: 'Dockerfile', when: 'always' }] } it_behaves_like 'when there is a rule with exists' - - context 'when FF `ci_support_include_rules_when_never` is disabled' do - before do - stub_feature_flags(ci_support_include_rules_when_never: false) - end - - it_behaves_like 'when there is a rule with exists' - end end context 'with when: <invalid string>' do diff --git a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb index 726ed6d95a0..888756a3eb1 100644 --- a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb +++ b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb @@ -5,10 +5,10 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeline_composition do let_it_be(:project) { create(:project) } - let(:ctx) { instance_double(Gitlab::Ci::Config::External::Context, project: project, user: build(:user, id: 1234)) } + let(:current_user) { build(:user, id: 1234) } let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(config: [header, content]) } - subject { described_class.new(result, arguments, ctx) } + subject { described_class.new(result, arguments, current_user: current_user) } context 'when input data is valid' do let(:header) do @@ -39,7 +39,7 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli end context 'when config has a syntax error' do - let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: ArgumentError.new) } + let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: 'Invalid configuration format') } let(:arguments) do { website: 'gitlab.com' } @@ -50,7 +50,7 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli expect(subject).not_to be_valid expect(subject.error_message).to eq subject.errors.first - expect(subject.errors).to include 'content does not have a valid YAML syntax' + expect(subject.errors).to include 'Invalid configuration format' end end @@ -142,28 +142,6 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli end describe '#to_hash' do - context 'when interpolation is disabled' do - before do - stub_feature_flags(ci_includable_files_interpolation: false) - end - - let(:header) do - { spec: { inputs: { website: nil } } } - end - - let(:content) do - { test: 'deploy $[[ inputs.website ]]' } - end - - let(:arguments) { {} } - - it 'returns an empty hash' do - subject.interpolate! - - expect(subject.to_hash).to be_empty - end - end - context 'when interpolation is not used' do let(:result) do ::Gitlab::Ci::Config::Yaml::Result.new(config: content) @@ -202,118 +180,4 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli end end end - - describe '#ready?' do - let(:header) do - { spec: { inputs: { website: nil } } } - end - - let(:content) do - { test: 'deploy $[[ inputs.website ]]' } - end - - let(:arguments) do - { website: 'gitlab.com' } - end - - it 'returns false if interpolation has not been done yet' do - expect(subject).not_to be_ready - end - - it 'returns true if interpolation has been performed' do - subject.interpolate! - - expect(subject).to be_ready - end - - context 'when interpolation can not be performed' do - let(:result) do - ::Gitlab::Ci::Config::Yaml::Result.new(error: ArgumentError.new) - end - - it 'returns true if interpolator has preliminary errors' do - expect(subject).to be_ready - end - - it 'returns true if interpolation has been attempted' do - subject.interpolate! - - expect(subject).to be_ready - end - end - end - - describe '#interpolate?' do - let(:header) do - { spec: { inputs: { website: nil } } } - end - - let(:content) do - { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' } - end - - let(:arguments) do - { website: 'gitlab.com' } - end - - context 'when interpolation can be performed' do - it 'will perform interpolation' do - expect(subject.interpolate?).to eq true - end - end - - context 'when interpolation is disabled' do - before do - stub_feature_flags(ci_includable_files_interpolation: false) - end - - it 'will not perform interpolation' do - expect(subject.interpolate?).to eq false - end - end - - context 'when an interpolation header is missing' do - let(:header) { nil } - - it 'will not perform interpolation' do - expect(subject.interpolate?).to eq false - end - end - - context 'when interpolator has preliminary errors' do - let(:result) do - ::Gitlab::Ci::Config::Yaml::Result.new(error: ArgumentError.new) - end - - it 'will not perform interpolation' do - expect(subject.interpolate?).to eq false - end - end - end - - describe '#has_header?' do - let(:content) do - { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' } - end - - let(:arguments) do - { website: 'gitlab.com' } - end - - context 'when header is an empty hash' do - let(:header) { {} } - - it 'does not have a header available' do - expect(subject).not_to have_header - end - end - - context 'when header is not specified' do - let(:header) { nil } - - it 'does not have a header available' do - expect(subject).not_to have_header - end - end - end end diff --git a/spec/lib/gitlab/ci/config/yaml/loader_spec.rb b/spec/lib/gitlab/ci/config/yaml/loader_spec.rb index 1e417bcd8af..4e6151677e6 100644 --- a/spec/lib/gitlab/ci/config/yaml/loader_spec.rb +++ b/spec/lib/gitlab/ci/config/yaml/loader_spec.rb @@ -2,151 +2,58 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::Config::Yaml::Loader, feature_category: :pipeline_composition do - describe '#to_result' do +RSpec.describe ::Gitlab::Ci::Config::Yaml::Loader, feature_category: :pipeline_composition do + describe '#load' do let_it_be(:project) { create(:project) } - subject(:result) { described_class.new(yaml, project: project).to_result } - - context 'when syntax is invalid' do - let(:yaml) { 'some: invalid: syntax' } - - it 'returns an invalid result object' do - expect(result).not_to be_valid - expect(result.error).to be_a ::Gitlab::Config::Loader::FormatError - end + let(:inputs) { { test_input: 'hello test' } } + + let(:yaml) do + <<~YAML + --- + spec: + inputs: + test_input: + --- + test_job: + script: + - echo "$[[ inputs.test_input ]]" + YAML end - context 'when the first document is a header' do - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - spec: - --- - b: 2 - YAML - end - - it 'considers the first document as header and the second as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result.header).to eq({ spec: nil }) - expect(result.content).to eq({ b: 2 }) - end - end - end + subject(:result) { described_class.new(yaml, inputs: inputs, current_user: project.creator).load } - context 'when first document is empty' do - let(:yaml) do - <<~YAML - --- - --- - b: 2 - YAML - end - - it 'considers the first document as header and the second as content' do - expect(result).not_to have_header - end - end - - context 'when first document is an empty hash' do - let(:yaml) do - <<~YAML - {} - --- - b: 2 - YAML - end + it 'loads and interpolates CI config YAML' do + expected_config = { test_job: { script: ['echo "hello test"'] } } - it 'returns second document as a content' do - expect(result).not_to have_header - expect(result.content).to eq({ b: 2 }) - end + expect(result).to be_valid + expect(result.content).to eq(expected_config) end - context 'when first an array' do - let(:yaml) do - <<~YAML - --- - - a - - b - --- - b: 2 - YAML - end + it 'allows the use of YAML reference tags' do + expect(Psych).to receive(:add_tag).once.with( + ::Gitlab::Ci::Config::Yaml::Tags::Reference.tag, + ::Gitlab::Ci::Config::Yaml::Tags::Reference + ) - it 'considers the first document as header and the second as content' do - expect(result).not_to have_header - end + result end - context 'when the first document is not a header' do - let(:yaml) do - <<~YAML - a: 1 - --- - b: 2 - YAML - end - - it 'considers the first document as content for backwards compatibility' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end - - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - a: 1 - --- - b: 2 - YAML - end + context 'when there is an error loading the YAML' do + let(:yaml) { 'invalid...yaml' } - it 'considers the first document as content for backwards compatibility' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end + it 'returns an error result' do + expect(result).not_to be_valid + expect(result.error).to eq('Invalid configuration format') end end - context 'when the first document is not a header and second document is empty' do - let(:yaml) do - <<~YAML - a: 1 - --- - YAML - end - - it 'considers the first document as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end - - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - a: 1 - --- - YAML - end + context 'when there is an error interpolating the YAML' do + let(:inputs) { {} } - it 'considers the first document as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end + it 'returns an error result' do + expect(result).not_to be_valid + expect(result.error).to eq('`test_input` input: required value has not been provided') end end end diff --git a/spec/lib/gitlab/ci/config/yaml_spec.rb b/spec/lib/gitlab/ci/config/yaml_spec.rb index 3576dd481c6..27d93d555f1 100644 --- a/spec/lib/gitlab/ci/config/yaml_spec.rb +++ b/spec/lib/gitlab/ci/config/yaml_spec.rb @@ -3,18 +3,20 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Config::Yaml, feature_category: :pipeline_composition do - describe '.load!' do - it 'loads a YAML file' do - yaml = <<~YAML - image: 'image:1.0' - texts: - nested_key: 'value1' - more_text: - more_nested_key: 'value2' - YAML + let(:yaml) do + <<~YAML + image: 'image:1.0' + texts: + nested_key: 'value1' + more_text: + more_nested_key: 'value2' + YAML + end - config = described_class.load!(yaml) + describe '.load!' do + subject(:config) { described_class.load!(yaml) } + it 'loads a YAML file' do expect(config).to eq({ image: 'image:1.0', texts: { @@ -30,156 +32,20 @@ RSpec.describe Gitlab::Ci::Config::Yaml, feature_category: :pipeline_composition let(:yaml) { 'some: invalid: syntax' } it 'raises an error' do - expect { described_class.load!(yaml) } + expect { config } .to raise_error ::Gitlab::Config::Loader::FormatError, /mapping values are not allowed in this context/ end end - end - - describe '.load_result!' do - let_it_be(:project) { create(:project) } - - subject(:result) { described_class.load_result!(yaml, project: project) } - - context 'when syntax is invalid' do - let(:yaml) { 'some: invalid: syntax' } - - it 'returns an invalid result object' do - expect(result).not_to be_valid - expect(result.error).to be_a ::Gitlab::Config::Loader::FormatError - end - end - - context 'when the first document is a header' do - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - spec: - --- - b: 2 - YAML - end - - it 'considers the first document as header and the second as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result.header).to eq({ spec: nil }) - expect(result.content).to eq({ b: 2 }) - end - end - end - - context 'when first document is empty' do - let(:yaml) do - <<~YAML - --- - --- - b: 2 - YAML - end - - it 'considers the first document as header and the second as content' do - expect(result).not_to have_header - end - end - - context 'when first document is an empty hash' do - let(:yaml) do - <<~YAML - {} - --- - b: 2 - YAML - end - it 'returns second document as a content' do - expect(result).not_to have_header - expect(result.content).to eq({ b: 2 }) - end - end + context 'when given a user' do + let(:user) { instance_double(User) } - context 'when first an array' do - let(:yaml) do - <<~YAML - --- - - a - - b - --- - b: 2 - YAML - end - - it 'considers the first document as header and the second as content' do - expect(result).not_to have_header - end - end - - context 'when the first document is not a header' do - let(:yaml) do - <<~YAML - a: 1 - --- - b: 2 - YAML - end - - it 'considers the first document as content for backwards compatibility' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end - - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - a: 1 - --- - b: 2 - YAML - end - - it 'considers the first document as content for backwards compatibility' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end - end - end - - context 'when the first document is not a header and second document is empty' do - let(:yaml) do - <<~YAML - a: 1 - --- - YAML - end - - it 'considers the first document as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end + subject(:config) { described_class.load!(yaml, current_user: user) } - context 'with explicit document start marker' do - let(:yaml) do - <<~YAML - --- - a: 1 - --- - YAML - end + it 'passes it to Loader' do + expect(::Gitlab::Ci::Config::Yaml::Loader).to receive(:new).with(yaml, current_user: user).and_call_original - it 'considers the first document as content' do - expect(result).to be_valid - expect(result.error).to be_nil - expect(result).not_to have_header - expect(result.content).to eq({ a: 1 }) - end + config end end end diff --git a/spec/lib/gitlab/ci/jwt_v2_spec.rb b/spec/lib/gitlab/ci/jwt_v2_spec.rb index 15be67329a8..575f174f737 100644 --- a/spec/lib/gitlab/ci/jwt_v2_spec.rb +++ b/spec/lib/gitlab/ci/jwt_v2_spec.rb @@ -62,6 +62,23 @@ RSpec.describe Gitlab::Ci::JwtV2, feature_category: :continuous_integration do end describe 'custom claims' do + let(:project_config) do + instance_double( + Gitlab::Ci::ProjectConfig, + url: 'gitlab.com/gitlab-org/gitlab//.gitlab-ci.yml', + source: :repository_source + ) + end + + before do + allow(Gitlab::Ci::ProjectConfig).to receive(:new).with( + project: project, + sha: pipeline.sha, + pipeline_source: pipeline.source.to_sym, + pipeline_source_bridge: pipeline.source_bridge + ).and_return(project_config) + end + describe 'runner_id' do it 'is the ID of the runner executing the job' do expect(payload[:runner_id]).to eq(runner.id) @@ -113,23 +130,6 @@ RSpec.describe Gitlab::Ci::JwtV2, feature_category: :continuous_integration do end describe 'ci_config_ref_uri' do - let(:project_config) do - instance_double( - Gitlab::Ci::ProjectConfig, - url: 'gitlab.com/gitlab-org/gitlab//.gitlab-ci.yml', - source: :repository_source - ) - end - - before do - allow(Gitlab::Ci::ProjectConfig).to receive(:new).with( - project: project, - sha: pipeline.sha, - pipeline_source: pipeline.source.to_sym, - pipeline_source_bridge: pipeline.source_bridge - ).and_return(project_config) - end - it 'joins project_config.url and pipeline.source_ref_path with @' do expect(payload[:ci_config_ref_uri]).to eq('gitlab.com/gitlab-org/gitlab//.gitlab-ci.yml' \ '@refs/heads/auto-deploy-2020-03-19') @@ -165,15 +165,31 @@ RSpec.describe Gitlab::Ci::JwtV2, feature_category: :continuous_integration do end end - context 'when ci_jwt_v2_ci_config_ref_uri_claim flag is disabled' do + context 'when config source is not repository' do before do - stub_feature_flags(ci_jwt_v2_ref_uri_claim: false) + allow(project_config).to receive(:source).and_return(:auto_devops_source) end it 'is nil' do expect(payload[:ci_config_ref_uri]).to be_nil end end + end + + describe 'ci_config_sha' do + it 'is the SHA of the pipeline' do + expect(payload[:ci_config_sha]).to eq(pipeline.sha) + end + + context 'when project config is nil' do + before do + allow(Gitlab::Ci::ProjectConfig).to receive(:new).and_return(nil) + end + + it 'is nil' do + expect(payload[:ci_config_sha]).to be_nil + end + end context 'when config source is not repository' do before do @@ -181,7 +197,7 @@ RSpec.describe Gitlab::Ci::JwtV2, feature_category: :continuous_integration do end it 'is nil' do - expect(payload[:ci_config_ref_uri]).to be_nil + expect(payload[:ci_config_sha]).to be_nil end end end diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb index a9a52972294..9c268d9039e 100644 --- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb +++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb @@ -26,7 +26,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Config::Content, feature_category: : expect(pipeline.config_source).to eq 'bridge_source' expect(command.config_content).to eq 'the-yaml' - expect(command.pipeline_config.internal_include_prepended?).to eq(false) + expect(command.pipeline_config.internal_include_prepended?).to eq(true) end end diff --git a/spec/lib/gitlab/ci/reports/sbom/source_spec.rb b/spec/lib/gitlab/ci/reports/sbom/source_spec.rb index 63b8e5fdf01..c1eaea511b7 100644 --- a/spec/lib/gitlab/ci/reports/sbom/source_spec.rb +++ b/spec/lib/gitlab/ci/reports/sbom/source_spec.rb @@ -24,4 +24,28 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Source, feature_category: :dependency_ data: attributes[:data] ) end + + describe '#source_file_path' do + it 'returns the correct source_file_path' do + expect(subject.source_file_path).to eq('package.json') + end + end + + describe '#input_file_path' do + it 'returns the correct input_file_path' do + expect(subject.input_file_path).to eq("package-lock.json") + end + end + + describe '#packager' do + it 'returns the correct package manager name' do + expect(subject.packager).to eq("npm") + end + end + + describe '#language' do + it 'returns the correct langauge' do + expect(subject.language).to eq("JavaScript") + end + end end diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index 35d44281072..702341a7ea7 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::Status::Stage::Factory do +RSpec.describe Gitlab::Ci::Status::Stage::Factory, feature_category: :continuous_integration do let(:user) { create(:user) } let(:project) { create(:project) } let(:pipeline) { create(:ci_empty_pipeline, project: project) } @@ -62,7 +62,7 @@ RSpec.describe Gitlab::Ci::Status::Stage::Factory do end context 'when stage has manual builds' do - (Ci::HasStatus::BLOCKED_STATUS + ['skipped']).each do |core_status| + Ci::HasStatus::BLOCKED_STATUS.each do |core_status| context "when status is #{core_status}" do let(:stage) { create(:ci_stage, pipeline: pipeline, status: core_status) } diff --git a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb index 9fdaddc083e..e23645c106b 100644 --- a/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/play_manual_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::Status::Stage::PlayManual do +RSpec.describe Gitlab::Ci::Status::Stage::PlayManual, feature_category: :continuous_integration do let(:stage) { double('stage') } let(:play_manual) { described_class.new(stage) } @@ -48,7 +48,7 @@ RSpec.describe Gitlab::Ci::Status::Stage::PlayManual do context 'when stage is skipped' do let(:stage) { create(:ci_stage, status: :skipped) } - it { is_expected.to be_truthy } + it { is_expected.to be_falsy } end context 'when stage is manual' do diff --git a/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb b/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb index 5ab859241c6..b72a818c16c 100644 --- a/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb +++ b/spec/lib/gitlab/ci/tags/bulk_insert_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Gitlab::Ci::Tags::BulkInsert do let(:inserter) { instance_double(described_class) } it 'delegates to bulk insert class' do - expect(Gitlab::Ci::Tags::BulkInsert) + expect(described_class) .to receive(:new) .with(statuses) .and_return(inserter) diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb index 6b296924b6d..28c9bdc4c4b 100644 --- a/spec/lib/gitlab/ci/variables/builder_spec.rb +++ b/spec/lib/gitlab/ci/variables/builder_spec.rb @@ -98,7 +98,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder, :clean_gitlab_redis_cache, featur { key: 'CI_PAGES_DOMAIN', value: Gitlab.config.pages.host }, { key: 'CI_PAGES_URL', - value: project.pages_url }, + value: Gitlab::Pages::UrlBuilder.new(project).pages_url }, { key: 'CI_API_V4_URL', value: API::Helpers::Version.new('v4').root_url }, { key: 'CI_API_GRAPHQL_URL', diff --git a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb index 432225c53f0..f798945f64f 100644 --- a/spec/lib/gitlab/ci/variables/collection/sort_spec.rb +++ b/spec/lib/gitlab/ci/variables/collection/sort_spec.rb @@ -6,7 +6,7 @@ require 'tsort' RSpec.describe Gitlab::Ci::Variables::Collection::Sort do describe '#initialize with non-Collection value' do - subject { Gitlab::Ci::Variables::Collection::Sort.new([]) } + subject { described_class.new([]) } it 'raises ArgumentError' do expect { subject }.to raise_error(ArgumentError, /Collection object was expected/) @@ -167,7 +167,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection::Sort do let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) } - subject { Gitlab::Ci::Variables::Collection::Sort.new(collection).tsort } + subject { described_class.new(collection).tsort } it 'raises TSort::Cyclic' do expect { subject }.to raise_error(TSort::Cyclic) diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb index 181e37de9b9..d21190ae297 100644 --- a/spec/lib/gitlab/ci/variables/collection_spec.rb +++ b/spec/lib/gitlab/ci/variables/collection_spec.rb @@ -3,6 +3,62 @@ require 'spec_helper' RSpec.describe Gitlab::Ci::Variables::Collection, feature_category: :secrets_management do + describe '.fabricate' do + using RSpec::Parameterized::TableSyntax + + where do + { + "given an array of variables": { + input: [ + { key: 'VAR1', value: 'value1' }, + { key: 'VAR2', value: 'value2' } + ] + }, + "given a hash of variables": { + input: { 'VAR1' => 'value1', 'VAR2' => 'value2' } + }, + "given a proc that evaluates to an array": { + input: -> do + [ + { key: 'VAR1', value: 'value1' }, + { key: 'VAR2', value: 'value2' } + ] + end + }, + "given a proc that evaluates to a hash": { + input: -> do + { 'VAR1' => 'value1', 'VAR2' => 'value2' } + end + }, + "given a collection": { + input: Gitlab::Ci::Variables::Collection.new( + [ + { key: 'VAR1', value: 'value1' }, + { key: 'VAR2', value: 'value2' } + ] + ) + } + } + end + + with_them do + subject(:collection) { Gitlab::Ci::Variables::Collection.fabricate(input) } + + it 'returns a collection' do + expect(collection).to be_a(Gitlab::Ci::Variables::Collection) + expect(collection.size).to eq(2) + expect(collection.map(&:key)).to contain_exactly('VAR1', 'VAR2') + expect(collection.map(&:value)).to contain_exactly('value1', 'value2') + end + end + + context 'when given an unrecognized type' do + it 'raises error' do + expect { described_class.fabricate(1) }.to raise_error(ArgumentError) + end + end + end + describe '.new' do it 'can be initialized with an array' do variable = { key: 'VAR', value: 'value', public: true, masked: false } @@ -123,7 +179,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection, feature_category: :secrets_man end describe '#[]' do - subject { Gitlab::Ci::Variables::Collection.new(variables)[var_name] } + subject { described_class.new(variables)[var_name] } shared_examples 'an array access operator' do context 'for a non-existent variable name' do @@ -570,7 +626,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection, feature_category: :secrets_man end let(:errors) { 'circular variable reference detected' } - let(:collection) { Gitlab::Ci::Variables::Collection.new(variables, errors) } + let(:collection) { described_class.new(variables, errors) } subject(:result) { collection.to_s } diff --git a/spec/lib/gitlab/ci/variables/downstream/expandable_variable_generator_spec.rb b/spec/lib/gitlab/ci/variables/downstream/expandable_variable_generator_spec.rb new file mode 100644 index 00000000000..5b33527e06c --- /dev/null +++ b/spec/lib/gitlab/ci/variables/downstream/expandable_variable_generator_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +RSpec.describe Gitlab::Ci::Variables::Downstream::ExpandableVariableGenerator, feature_category: :secrets_management do + let(:all_bridge_variables) do + Gitlab::Ci::Variables::Collection.fabricate( + [ + { key: 'REF1', value: 'ref 1' }, + { key: 'REF2', value: 'ref 2' } + ] + ) + end + + let(:context) do + Gitlab::Ci::Variables::Downstream::Generator::Context.new(all_bridge_variables: all_bridge_variables) + end + + subject(:generator) { described_class.new(context) } + + describe '#for' do + context 'when given a variable without interpolation' do + it 'returns an array containing the variable' do + var = Gitlab::Ci::Variables::Collection::Item.fabricate({ key: 'VAR1', value: 'variable 1' }) + + expect(generator.for(var)).to match_array([{ key: 'VAR1', value: 'variable 1' }]) + end + end + + context 'when given a variable with interpolation' do + it 'returns an array containing the expanded variables' do + var = Gitlab::Ci::Variables::Collection::Item.fabricate({ key: 'VAR1', value: '$REF1 $REF2 $REF3' }) + + expect(generator.for(var)).to match_array([{ key: 'VAR1', value: 'ref 1 ref 2 ' }]) + end + end + end +end diff --git a/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb b/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb new file mode 100644 index 00000000000..61e8b9a8c4a --- /dev/null +++ b/spec/lib/gitlab/ci/variables/downstream/generator_spec.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Ci::Variables::Downstream::Generator, feature_category: :secrets_management do + let(:bridge_variables) do + Gitlab::Ci::Variables::Collection.fabricate( + [ + { key: 'REF1', value: 'ref 1' }, + { key: 'REF2', value: 'ref 2' } + ] + ) + end + + let(:yaml_variables) do + [ + { key: 'VAR1', value: 'variable 1' }, + { key: 'VAR2', value: 'variable 2' }, + { key: 'RAW_VAR3', value: '$REF1', raw: true }, + { key: 'INTERPOLATION_VAR4', value: 'interpolate $REF1 $REF2' } + ] + end + + let(:pipeline_variables) do + [ + { key: 'PIPELINE_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_INTERPOLATION_VAR4', value: 'interpolate $REF1 $REF2' } + ] + end + + let(:pipeline_schedule_variables) do + [ + { key: 'PIPELINE_SCHEDULE_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_SCHEDULE_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_SCHEDULE_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR4', value: 'interpolate $REF1 $REF2' } + ] + end + + let(:bridge) do + instance_double( + 'Ci::Bridge', + variables: bridge_variables, + forward_yaml_variables?: true, + forward_pipeline_variables?: true, + yaml_variables: yaml_variables, + pipeline_variables: pipeline_variables, + pipeline_schedule_variables: pipeline_schedule_variables + ) + end + + subject(:generator) { described_class.new(bridge) } + + describe '#calculate' do + it 'creates attributes for downstream pipeline variables from the ' \ + 'given yaml variables, pipeline variables and pipeline schedule variables' do + expected = [ + { key: 'VAR1', value: 'variable 1' }, + { key: 'VAR2', value: 'variable 2' }, + { key: 'RAW_VAR3', value: '$REF1', raw: true }, + { key: 'INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' }, + { key: 'PIPELINE_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' }, + { key: 'PIPELINE_SCHEDULE_VAR1', value: 'variable 1' }, + { key: 'PIPELINE_SCHEDULE_VAR2', value: 'variable 2' }, + { key: 'PIPELINE_SCHEDULE_RAW_VAR3', value: '$REF1', raw: true }, + { key: 'PIPELINE_SCHEDULE_INTERPOLATION_VAR4', value: 'interpolate ref 1 ref 2' } + ] + + expect(generator.calculate).to contain_exactly(*expected) + end + + it 'returns empty array when bridge has no variables' do + allow(bridge).to receive(:yaml_variables).and_return([]) + allow(bridge).to receive(:pipeline_variables).and_return([]) + allow(bridge).to receive(:pipeline_schedule_variables).and_return([]) + + expect(generator.calculate).to be_empty + end + end +end diff --git a/spec/lib/gitlab/ci/variables/downstream/raw_variable_generator_spec.rb b/spec/lib/gitlab/ci/variables/downstream/raw_variable_generator_spec.rb new file mode 100644 index 00000000000..12249071486 --- /dev/null +++ b/spec/lib/gitlab/ci/variables/downstream/raw_variable_generator_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +RSpec.describe Gitlab::Ci::Variables::Downstream::RawVariableGenerator, feature_category: :secrets_management do + let(:context) { Gitlab::Ci::Variables::Downstream::Generator::Context.new } + + subject(:generator) { described_class.new(context) } + + describe '#for' do + it 'returns an array containing the unexpanded raw variable' do + var = Gitlab::Ci::Variables::Collection::Item.fabricate({ key: 'VAR1', value: '$REF1', raw: true }) + + expect(generator.for(var)).to match_array([{ key: 'VAR1', value: '$REF1', raw: true }]) + end + end +end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index 2c020e76cb6..c4e27d0e420 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -152,7 +152,7 @@ module Gitlab config = YAML.dump({ default: { interruptible: true }, rspec: { script: "rspec" } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute builds = config_processor.builds.select { |b| b[:stage] == "test" } expect(builds.size).to eq(1) @@ -851,7 +851,7 @@ module Gitlab context 'when `only` has an invalid value' do let(:config) { { rspec: { script: "rspec", stage: "test", only: only } } } - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } context 'when it is integer' do let(:only) { 1 } @@ -875,7 +875,7 @@ module Gitlab context 'when `except` has an invalid value' do let(:config) { { rspec: { script: "rspec", except: except } } } - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } context 'when it is integer' do let(:except) { 1 } @@ -899,7 +899,7 @@ module Gitlab describe "Scripts handling" do let(:config_data) { YAML.dump(config) } - let(:config_processor) { Gitlab::Ci::YamlProcessor.new(config_data).execute } + let(:config_processor) { described_class.new(config_data).execute } subject(:test_build) { config_processor.builds.find { |build| build[:name] == 'test' } } @@ -1131,7 +1131,7 @@ module Gitlab before_script: ["pwd"], rspec: { script: "rspec" } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build).to eq({ @@ -1165,7 +1165,7 @@ module Gitlab command: ["/usr/local/bin/init", "run"] }, "docker:dind"], script: "rspec" } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build).to eq({ @@ -1197,7 +1197,7 @@ module Gitlab before_script: ["pwd"], rspec: { script: "rspec" } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build).to eq({ @@ -1225,7 +1225,7 @@ module Gitlab before_script: ["pwd"], rspec: { image: "image:1.0", services: ["postgresql", "docker:dind"], script: "rspec" } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build).to eq({ @@ -1492,7 +1492,7 @@ module Gitlab end context 'when using `extends`' do - let(:config_processor) { Gitlab::Ci::YamlProcessor.new(config).execute } + let(:config_processor) { described_class.new(config).execute } subject { config_processor.builds.first } @@ -1612,7 +1612,7 @@ module Gitlab } end - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config), opts).execute } + subject { described_class.new(YAML.dump(config), opts).execute } context "when validating a ci config file with no project context" do context "when a single string is provided" do @@ -1744,7 +1744,7 @@ module Gitlab variables: { 'VAR1' => 1 } }) end - let(:config_processor) { Gitlab::Ci::YamlProcessor.new(config).execute } + let(:config_processor) { described_class.new(config).execute } let(:builds) { config_processor.builds } context 'when job is parallelized' do @@ -1860,7 +1860,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -1886,7 +1886,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -1913,7 +1913,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -1952,7 +1952,7 @@ module Gitlab } ) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -1979,7 +1979,7 @@ module Gitlab } ) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -2004,7 +2004,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build[:cache]).to eq( @@ -2039,7 +2039,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute rspec_build = config_processor.builds.find { |build| build[:name] == 'rspec' } expect(rspec_build).to eq({ @@ -2076,7 +2076,7 @@ module Gitlab } }) - config_processor = Gitlab::Ci::YamlProcessor.new(config).execute + config_processor = described_class.new(config).execute builds = config_processor.builds expect(builds.size).to eq(1) @@ -2133,7 +2133,7 @@ module Gitlab end describe "release" do - let(:processor) { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + let(:processor) { described_class.new(YAML.dump(config)).execute } let(:config) do { stages: %w[build test release], @@ -2179,7 +2179,7 @@ module Gitlab } end - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } let(:builds) { subject.builds } @@ -2289,7 +2289,7 @@ module Gitlab } end - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } let(:builds) { subject.builds } @@ -2331,7 +2331,7 @@ module Gitlab } end - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } context 'no dependencies' do let(:dependencies) {} @@ -2404,7 +2404,7 @@ module Gitlab } end - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } context 'no needs' do it { is_expected.to be_valid } @@ -2678,7 +2678,7 @@ module Gitlab end context 'with when/rules' do - subject { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)).execute } + subject { described_class.new(YAML.dump(config)).execute } let(:config) do { @@ -2798,7 +2798,7 @@ module Gitlab end describe "Hidden jobs" do - let(:config_processor) { Gitlab::Ci::YamlProcessor.new(config).execute } + let(:config_processor) { described_class.new(config).execute } subject { config_processor.builds } @@ -2846,7 +2846,7 @@ module Gitlab end describe "YAML Alias/Anchor" do - let(:config_processor) { Gitlab::Ci::YamlProcessor.new(config).execute } + let(:config_processor) { described_class.new(config).execute } subject { config_processor.builds } @@ -3390,7 +3390,7 @@ module Gitlab end describe '#execute' do - subject { Gitlab::Ci::YamlProcessor.new(content).execute } + subject { described_class.new(content).execute } context 'when the YAML could not be parsed' do let(:content) { YAML.dump('invalid: yaml: test') } @@ -3435,7 +3435,7 @@ module Gitlab it 'returns errors and empty configuration' do expect(subject.valid?).to eq(false) - expect(subject.errors).to eq(['Unknown alias: bad_alias']) + expect(subject.errors).to all match(%r{unknown .+ bad_alias}i) end end |