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:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-19 17:16:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-19 17:16:28 +0300
commite4384360a16dd9a19d4d2d25d0ef1f2b862ed2a6 (patch)
tree2fcdfa7dcdb9db8f5208b2562f4b4e803d671243 /spec/lib/gitlab/ci
parentffda4e7bcac36987f936b4ba515995a6698698f0 (diff)
Add latest changes from gitlab-org/gitlab@16-2-stable-eev16.2.0-rc42
Diffstat (limited to 'spec/lib/gitlab/ci')
-rw-r--r--spec/lib/gitlab/ci/artifact_file_reader_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/build/rules_spec.rb53
-rw-r--r--spec/lib/gitlab/ci/components/instance_path_spec.rb26
-rw-r--r--spec/lib/gitlab/ci/config/external/file/artifact_spec.rb5
-rw-r--r--spec/lib/gitlab/ci/config/external/file/base_spec.rb40
-rw-r--r--spec/lib/gitlab/ci/config/external/file/component_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/external/mapper/filter_spec.rb13
-rw-r--r--spec/lib/gitlab/ci/config/external/processor_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/external/rules_spec.rb40
-rw-r--r--spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb144
-rw-r--r--spec/lib/gitlab/ci/config/yaml/loader_spec.rb165
-rw-r--r--spec/lib/gitlab/ci/config/yaml_spec.rb172
-rw-r--r--spec/lib/gitlab/ci/jwt_v2_spec.rb56
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/reports/sbom/source_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/status/stage/factory_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/status/stage/play_manual_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/tags/bulk_insert_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/variables/builder_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/variables/collection/sort_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/variables/collection_spec.rb60
-rw-r--r--spec/lib/gitlab/ci/variables/downstream/expandable_variable_generator_spec.rb38
-rw-r--r--spec/lib/gitlab/ci/variables/downstream/generator_spec.rb85
-rw-r--r--spec/lib/gitlab/ci/variables/downstream/raw_variable_generator_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb58
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