diff options
Diffstat (limited to 'spec/lib/gitlab/ci')
-rw-r--r-- | spec/lib/gitlab/ci/artifact_file_reader_spec.rb | 100 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/bridge_spec.rb | 2 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/job_spec.rb | 16 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/jobs_spec.rb | 1 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/processable_spec.rb | 105 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/entry/root_spec.rb | 17 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/artifact_spec.rb | 167 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/local_spec.rb | 17 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/project_spec.rb | 17 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config_spec.rb | 88 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/yaml_processor_spec.rb | 76 |
11 files changed, 544 insertions, 62 deletions
diff --git a/spec/lib/gitlab/ci/artifact_file_reader_spec.rb b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb new file mode 100644 index 00000000000..04017b9ae3e --- /dev/null +++ b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Ci::ArtifactFileReader do + let(:job) { create(:ci_build) } + let(:path) { 'generated.yml' } # included in the ci_build_artifacts.zip + + describe '#read' do + subject { described_class.new(job).read(path) } + + context 'when job has artifacts and metadata' do + let!(:artifacts) { create(:ci_job_artifact, :archive, job: job) } + let!(:metadata) { create(:ci_job_artifact, :metadata, job: job) } + + it 'returns the content at the path' do + is_expected.to be_present + expect(YAML.safe_load(subject).keys).to contain_exactly('rspec', 'time', 'custom') + end + + context 'when path does not exist' do + let(:path) { 'file/does/not/exist.txt' } + let(:expected_error) do + "Path `#{path}` does not exist inside the `#{job.name}` artifacts archive!" + end + + it 'raises an error' do + expect { subject }.to raise_error(described_class::Error, expected_error) + end + end + + context 'when path points to a directory' do + let(:path) { 'other_artifacts_0.1.2' } + let(:expected_error) do + "Path `#{path}` was expected to be a file but it was a directory!" + end + + it 'raises an error' do + expect { subject }.to raise_error(described_class::Error, expected_error) + end + end + + context 'when path is nested' do + # path exists in ci_build_artifacts.zip + let(:path) { 'other_artifacts_0.1.2/doc_sample.txt' } + + it 'returns the content at the nested path' do + is_expected.to be_present + end + end + + context 'when artifact archive size is greater than the limit' do + let(:expected_error) do + "Artifacts archive for job `#{job.name}` is too large: max 1 KB" + end + + before do + stub_const("#{described_class}::MAX_ARCHIVE_SIZE", 1.kilobyte) + end + + it 'raises an error' do + expect { subject }.to raise_error(described_class::Error, expected_error) + end + end + + context 'when metadata entry shows size greater than the limit' do + let(:expected_error) do + "Artifacts archive for job `#{job.name}` is too large: max 5 MB" + end + + before do + expect_next_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Entry) do |entry| + expect(entry).to receive(:total_size).and_return(10.megabytes) + end + end + + it 'raises an error' do + expect { subject }.to raise_error(described_class::Error, expected_error) + end + end + end + + context 'when job does not have metadata artifacts' do + let!(:artifacts) { create(:ci_job_artifact, :archive, job: job) } + let(:expected_error) do + "Job `#{job.name}` has missing artifacts metadata and cannot be extracted!" + end + + it 'raises an error' do + expect { subject }.to raise_error(described_class::Error, expected_error) + end + end + + context 'when job does not have artifacts' do + it 'raises ArgumentError' do + expect { subject }.to raise_error(ArgumentError, 'Job does not have artifacts') + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb index ad388886681..d08ce30618d 100644 --- a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb @@ -106,6 +106,7 @@ describe Gitlab::Ci::Config::Entry::Bridge do ignore: false, stage: 'test', only: { refs: %w[branches tags] }, + variables: {}, scheduling_type: :stage) end end @@ -128,6 +129,7 @@ describe Gitlab::Ci::Config::Entry::Bridge do ignore: false, stage: 'test', only: { refs: %w[branches tags] }, + variables: {}, scheduling_type: :stage) end end diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb index 313b504ab59..7df0eccb3ed 100644 --- a/spec/lib/gitlab/ci/config/entry/job_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb @@ -6,6 +6,7 @@ describe Gitlab::Ci::Config::Entry::Job do let(:entry) { described_class.new(config, name: :rspec) } it_behaves_like 'with inheritable CI config' do + let(:config) { { script: 'echo' } } let(:inheritable_key) { 'default' } let(:inheritable_class) { Gitlab::Ci::Config::Entry::Default } @@ -15,6 +16,10 @@ describe Gitlab::Ci::Config::Entry::Job do let(:ignored_inheritable_columns) do %i[] end + + before do + allow(entry).to receive_message_chain(:inherit_entry, :default_value).and_return(true) + end end describe '.nodes' do @@ -24,7 +29,8 @@ describe Gitlab::Ci::Config::Entry::Job do let(:result) do %i[before_script script stage type after_script cache image services only except rules needs variables artifacts - environment coverage retry interruptible timeout release tags] + environment coverage retry interruptible timeout release tags + inherit] end it { is_expected.to match_array result } @@ -500,7 +506,13 @@ describe Gitlab::Ci::Config::Entry::Job do let(:unspecified) { double('unspecified', 'specified?' => false) } let(:default) { double('default', '[]' => unspecified) } let(:workflow) { double('workflow', 'has_rules?' => false) } - let(:deps) { double('deps', 'default' => default, '[]' => unspecified, 'workflow' => workflow) } + + let(:deps) do + double('deps', + 'default_entry' => default, + 'workflow_entry' => workflow, + 'variables_value' => nil) + end context 'when job config overrides default config' do before do diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb index c8c188d71bf..203342ab620 100644 --- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb @@ -99,6 +99,7 @@ describe Gitlab::Ci::Config::Entry::Jobs do only: { refs: %w[branches tags] }, stage: 'test', trigger: { project: 'my/project' }, + variables: {}, scheduling_type: :stage }, regular_job: { diff --git a/spec/lib/gitlab/ci/config/entry/processable_spec.rb b/spec/lib/gitlab/ci/config/entry/processable_spec.rb index 410aef1cd53..5c2c6520f25 100644 --- a/spec/lib/gitlab/ci/config/entry/processable_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/processable_spec.rb @@ -7,6 +7,10 @@ describe Gitlab::Ci::Config::Entry::Processable do Class.new(::Gitlab::Config::Entry::Node) do include Gitlab::Ci::Config::Entry::Processable + entry :tags, ::Gitlab::Config::Entry::ArrayOfStrings, + description: 'Set the default tags.', + inherit: true + def self.name 'job' end @@ -189,14 +193,17 @@ describe Gitlab::Ci::Config::Entry::Processable do end describe '#compose!' do - let(:specified) do - double('specified', 'specified?' => true, value: 'specified') - end - let(:unspecified) { double('unspecified', 'specified?' => false) } let(:default) { double('default', '[]' => unspecified) } let(:workflow) { double('workflow', 'has_rules?' => false) } - let(:deps) { double('deps', 'default' => default, '[]' => unspecified, 'workflow' => workflow) } + let(:variables) { } + + let(:deps) do + double('deps', + default_entry: default, + workflow_entry: workflow, + variables_value: variables) + end context 'with workflow rules' do using RSpec::Parameterized::TableSyntax @@ -240,6 +247,84 @@ describe Gitlab::Ci::Config::Entry::Processable do end end end + + context 'with inheritance' do + context 'of variables' do + let(:config) do + { variables: { A: 'job', B: 'job' } } + end + + before do + entry.compose!(deps) + end + + context 'with only job variables' do + it 'does return defined variables' do + expect(entry.value).to include( + variables: { 'A' => 'job', 'B' => 'job' } + ) + end + end + + context 'when root yaml variables are used' do + let(:variables) do + Gitlab::Ci::Config::Entry::Variables.new( + A: 'root', C: 'root' + ).value + end + + it 'does return all variables and overwrite them' do + expect(entry.value).to include( + variables: { 'A' => 'job', 'B' => 'job', 'C' => 'root' } + ) + end + + context 'when inherit of defaults is disabled' do + let(:config) do + { + variables: { A: 'job', B: 'job' }, + inherit: { variables: false } + } + end + + it 'does return only job variables' do + expect(entry.value).to include( + variables: { 'A' => 'job', 'B' => 'job' } + ) + end + end + end + end + + context 'of default:tags' do + using RSpec::Parameterized::TableSyntax + + where(:default_tags, :tags, :inherit_default, :result) do + nil | %w[a b] | nil | %w[a b] + nil | %w[a b] | true | %w[a b] + nil | %w[a b] | false | %w[a b] + %w[b c] | %w[a b] | nil | %w[a b] + %w[b c] | %w[a b] | true | %w[a b] + %w[b c] | %w[a b] | false | %w[a b] + %w[b c] | nil | nil | %w[b c] + %w[b c] | nil | true | %w[b c] + %w[b c] | nil | false | nil + end + + with_them do + let(:config) { { tags: tags, inherit: { default: inherit_default } } } + let(:default_specified_tags) { double('tags', 'specified?' => true, 'valid?' => true, 'value' => default_tags) } + + before do + allow(default).to receive('[]').with(:tags).and_return(default_specified_tags) + + entry.compose!(deps) + end + + it { expect(entry.tags_value).to eq(result) } + end + end + end end context 'when composed' do @@ -254,10 +339,12 @@ describe Gitlab::Ci::Config::Entry::Processable do end it 'returns correct value' do - expect(entry.value) - .to eq(name: :rspec, - stage: 'test', - only: { refs: %w[branches tags] }) + expect(entry.value).to eq( + name: :rspec, + stage: 'test', + only: { refs: %w[branches tags] }, + variables: {} + ) end end end diff --git a/spec/lib/gitlab/ci/config/entry/root_spec.rb b/spec/lib/gitlab/ci/config/entry/root_spec.rb index cf0a3cfa963..c3871b6b3cf 100644 --- a/spec/lib/gitlab/ci/config/entry/root_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/root_spec.rb @@ -32,7 +32,7 @@ describe Gitlab::Ci::Config::Entry::Root do image: 'ruby:2.2', default: {}, services: ['postgres:9.1', 'mysql:5.5'], - variables: { VAR: 'value' }, + variables: { VAR: 'root' }, after_script: ['make clean'], stages: %w(build pages release), cache: { key: 'k', untracked: true, paths: ['public/'] }, @@ -42,6 +42,7 @@ describe Gitlab::Ci::Config::Entry::Root do stage: 'release', before_script: [], after_script: [], + variables: { 'VAR' => 'job' }, script: ["make changelog | tee release_changelog.txt"], release: { tag_name: 'v0.06', @@ -127,7 +128,7 @@ describe Gitlab::Ci::Config::Entry::Root do services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' }, - variables: {}, + variables: { 'VAR' => 'root' }, ignore: false, after_script: ['make clean'], only: { refs: %w[branches tags] }, @@ -141,7 +142,7 @@ describe Gitlab::Ci::Config::Entry::Root do services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'], policy: 'pull-push' }, - variables: {}, + variables: { 'VAR' => 'root' }, ignore: false, after_script: ['make clean'], only: { refs: %w[branches tags] }, @@ -157,7 +158,7 @@ describe Gitlab::Ci::Config::Entry::Root do services: [{ name: "postgres:9.1" }, { name: "mysql:5.5" }], cache: { key: "k", untracked: true, paths: ["public/"], policy: "pull-push" }, only: { refs: %w(branches tags) }, - variables: {}, + variables: { 'VAR' => 'job' }, after_script: [], ignore: false, scheduling_type: :stage } @@ -175,11 +176,11 @@ describe Gitlab::Ci::Config::Entry::Root do image: 'ruby:2.1', services: ['postgres:9.1', 'mysql:5.5'] }, - variables: { VAR: 'value' }, + variables: { VAR: 'root' }, stages: %w(build pages), cache: { key: 'k', untracked: true, paths: ['public/'] }, rspec: { script: %w[rspec ls] }, - spinach: { before_script: [], variables: { VAR: 'AA' }, script: 'spinach' } } + spinach: { before_script: [], variables: { VAR: 'job' }, script: 'spinach' } } end context 'when composed' do @@ -203,7 +204,7 @@ describe Gitlab::Ci::Config::Entry::Root do services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'], policy: "pull-push" }, - variables: {}, + variables: { 'VAR' => 'root' }, ignore: false, after_script: ['make clean'], only: { refs: %w[branches tags] }, @@ -215,7 +216,7 @@ describe Gitlab::Ci::Config::Entry::Root do services: [{ name: 'postgres:9.1' }, { name: 'mysql:5.5' }], stage: 'test', cache: { key: 'k', untracked: true, paths: ['public/'], policy: "pull-push" }, - variables: { 'VAR' => 'AA' }, + variables: { 'VAR' => 'job' }, ignore: false, after_script: ['make clean'], only: { refs: %w[branches tags] }, diff --git a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb new file mode 100644 index 00000000000..a8eb13c47bc --- /dev/null +++ b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Ci::Config::External::File::Artifact do + let(:parent_pipeline) { create(:ci_pipeline) } + let(:context) do + Gitlab::Ci::Config::External::Context.new(parent_pipeline: parent_pipeline) + end + + let(:external_file) { described_class.new(params, context) } + + describe '#matching?' do + context 'when params contain artifact location' do + let(:params) { { artifact: 'generated.yml' } } + + it 'returns true' do + expect(external_file).to be_matching + end + end + + context 'when params does not contain artifact location' do + let(:params) { {} } + + it 'returns false' do + expect(external_file).not_to be_matching + end + end + end + + describe '#valid?' do + shared_examples 'is invalid' do + it 'is not valid' do + expect(external_file).not_to be_valid + end + + it 'sets the expected error' do + expect(external_file.errors) + .to contain_exactly(expected_error) + end + end + + describe 'when used in non child pipeline context' do + let(:parent_pipeline) { nil } + let(:params) { { artifact: 'generated.yml' } } + + let(:expected_error) do + 'Including configs from artifacts is only allowed when triggering child pipelines' + end + + it_behaves_like 'is invalid' + end + + context 'when used in child pipeline context' do + let(:parent_pipeline) { create(:ci_pipeline) } + + context 'when job is not provided' do + let(:params) { { artifact: 'generated.yml' } } + + let(:expected_error) do + 'Job must be provided when including configs from artifacts' + end + + it_behaves_like 'is invalid' + end + + context 'when job is provided' do + let(:params) { { artifact: 'generated.yml', job: 'generator' } } + + context 'when job does not exist in the parent pipeline' do + let(:expected_error) do + 'Job `generator` not found in parent pipeline or does not have artifacts!' + end + + it_behaves_like 'is invalid' + end + + context 'when job exists in the parent pipeline' do + let!(:generator_job) { create(:ci_build, name: 'generator', pipeline: parent_pipeline) } + + context 'when job does not have artifacts' do + let(:expected_error) do + 'Job `generator` not found in parent pipeline or does not have artifacts!' + end + + it_behaves_like 'is invalid' + end + + context 'when job has archive artifacts' do + let!(:artifacts) do + create(:ci_job_artifact, :archive, + job: generator_job, + file: fixture_file_upload(Rails.root.join('spec/fixtures/pages.zip'), 'application/zip')) + end + + let(:expected_error) do + 'Job `generator` has missing artifacts metadata and cannot be extracted!' + end + + it_behaves_like 'is invalid' + + context 'when job has artifacts exceeding the max allowed size' do + let(:expected_error) do + "Artifacts archive for job `generator` is too large: max 1 KB" + end + + before do + stub_const("#{Gitlab::Ci::ArtifactFileReader}::MAX_ARCHIVE_SIZE", 1.kilobyte) + end + + it_behaves_like 'is invalid' + end + + context 'when job has artifacts metadata' do + let!(:metadata) do + create(:ci_job_artifact, :metadata, job: generator_job) + end + + let(:expected_error) do + 'Path `generated.yml` does not exist inside the `generator` artifacts archive!' + end + + it_behaves_like 'is invalid' + + context 'when file is found in metadata' do + let!(:artifacts) { create(:ci_job_artifact, :archive, job: generator_job) } + let!(:metadata) { create(:ci_job_artifact, :metadata, job: generator_job) } + + context 'when file is empty' do + before do + allow_next_instance_of(Gitlab::Ci::ArtifactFileReader) do |reader| + allow(reader).to receive(:read).and_return('') + end + end + + let(:expected_error) do + 'File `generated.yml` is empty!' + end + + it_behaves_like 'is invalid' + end + + context 'when file is not empty' do + it 'is valid' do + expect(external_file).to be_valid + expect(external_file.content).to be_present + end + + it 'propagates parent_pipeline to nested includes' do + expected_attrs = { + parent_pipeline: parent_pipeline, + project: anything, + sha: anything, + user: anything + } + expect(context).to receive(:mutate).with(expected_attrs).and_call_original + external_file.content + end + end + end + end + end + end + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/external/file/local_spec.rb b/spec/lib/gitlab/ci/config/external/file/local_spec.rb index 53205a18762..c9851239859 100644 --- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb @@ -6,10 +6,19 @@ describe Gitlab::Ci::Config::External::File::Local do let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { create(:user) } let(:sha) { '12345' } - let(:context_params) { { project: project, sha: sha, user: user } } let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:params) { { local: location } } let(:local_file) { described_class.new(params, context) } + let(:parent_pipeline) { double(:parent_pipeline) } + + let(:context_params) do + { + project: project, + sha: sha, + user: user, + parent_pipeline: parent_pipeline + } + end before do allow_any_instance_of(Gitlab::Ci::Config::External::Context) @@ -117,7 +126,11 @@ describe Gitlab::Ci::Config::External::File::Local do subject { local_file.send(:expand_context_attrs) } it 'inherits project, user and sha' do - is_expected.to include(user: user, project: project, sha: sha) + is_expected.to include( + user: user, + project: project, + sha: sha, + parent_pipeline: parent_pipeline) end end diff --git a/spec/lib/gitlab/ci/config/external/file/project_spec.rb b/spec/lib/gitlab/ci/config/external/file/project_spec.rb index 77a71f9972b..b2924ae9d91 100644 --- a/spec/lib/gitlab/ci/config/external/file/project_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/project_spec.rb @@ -7,10 +7,19 @@ describe Gitlab::Ci::Config::External::File::Project do let_it_be(:project) { create(:project, :repository) } let_it_be(:user) { create(:user) } let(:context_user) { user } - let(:context_params) { { project: context_project, sha: '12345', user: context_user } } + let(:parent_pipeline) { double(:parent_pipeline) } let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:project_file) { described_class.new(params, context) } + let(:context_params) do + { + project: context_project, + sha: '12345', + user: context_user, + parent_pipeline: parent_pipeline + } + end + before do project.add_developer(user) @@ -152,7 +161,11 @@ describe Gitlab::Ci::Config::External::File::Project do subject { project_file.send(:expand_context_attrs) } it 'inherits user, and target project and sha' do - is_expected.to include(user: user, project: project, sha: project.commit('master').id) + is_expected.to include( + user: user, + project: project, + sha: project.commit('master').id, + parent_pipeline: parent_pipeline) end end diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 525335cfea9..82ca8a29c5a 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -376,23 +376,6 @@ describe Gitlab::Ci::Config do end end - context 'when context expansion timeout is disabled' do - before do - allow_next_instance_of(Gitlab::Ci::Config::External::Context) do |instance| - allow(instance).to receive(:check_execution_time!).and_call_original - end - - allow(Feature) - .to receive(:enabled?) - .with(:ci_limit_yaml_expansion, project, default_enabled: true) - .and_return(false) - end - - it 'does not raises errors' do - expect { config }.not_to raise_error - end - end - describe 'external file version' do context 'when external local file SHA is defined' do it 'is using a defined value' do @@ -541,5 +524,76 @@ describe Gitlab::Ci::Config do end end end + + context 'when including file from artifact' do + let(:config) do + described_class.new( + gitlab_ci_yml, + project: nil, + sha: nil, + user: nil, + parent_pipeline: parent_pipeline) + end + + let(:gitlab_ci_yml) do + <<~HEREDOC + include: + - artifact: generated.yml + job: rspec + HEREDOC + end + + let(:parent_pipeline) { nil } + + context 'when used in the context of a child pipeline' do + # This job has ci_build_artifacts.zip artifact archive which + # contains generated.yml + let!(:job) { create(:ci_build, :artifacts, name: 'rspec', pipeline: parent_pipeline) } + let(:parent_pipeline) { create(:ci_pipeline) } + + it 'returns valid config' do + expect(config).to be_valid + end + + context 'when job key is missing' do + let(:gitlab_ci_yml) do + <<~HEREDOC + include: + - artifact: generated.yml + HEREDOC + end + + it 'raises an error' do + expect { config }.to raise_error( + described_class::ConfigError, + 'Job must be provided when including configs from artifacts' + ) + end + end + + context 'when artifact key is missing' do + let(:gitlab_ci_yml) do + <<~HEREDOC + include: + - job: rspec + HEREDOC + end + + it 'raises an error' do + expect { config }.to raise_error( + described_class::ConfigError, + /needs to match exactly one accessor!/ + ) + end + end + end + + it 'disallows the use in parent pipelines' do + expect { config }.to raise_error( + described_class::ConfigError, + 'Including configs from artifacts is only allowed when triggering child pipelines' + ) + end + end end end diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb index e303557bd00..5c85a136972 100644 --- a/spec/lib/gitlab/ci/yaml_processor_spec.rb +++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb @@ -509,28 +509,44 @@ module Gitlab describe "before_script" do context "in global context" do - let(:config) do - { - before_script: ["global script"], - test: { script: ["script"] } - } + using RSpec::Parameterized::TableSyntax + + where(:inherit, :result) do + nil | ["global script"] + { default: false } | nil + { default: true } | ["global script"] end - it "return commands with scripts concatenated" do - expect(subject[:options][:before_script]).to eq(["global script"]) + with_them do + let(:config) do + { + before_script: ["global script"], + test: { script: ["script"], inherit: inherit } + } + end + + it { expect(subject[:options][:before_script]).to eq(result) } end end context "in default context" do - let(:config) do - { - default: { before_script: ["global script"] }, - test: { script: ["script"] } - } + using RSpec::Parameterized::TableSyntax + + where(:inherit, :result) do + nil | ["global script"] + { default: false } | nil + { default: true } | ["global script"] end - it "return commands with scripts concatenated" do - expect(subject[:options][:before_script]).to eq(["global script"]) + with_them do + let(:config) do + { + default: { before_script: ["global script"] }, + test: { script: ["script"], inherit: inherit } + } + end + + it { expect(subject[:options][:before_script]).to eq(result) } end end @@ -793,7 +809,7 @@ module Gitlab context 'when job and global variables are defined' do let(:global_variables) do - { 'VAR1' => 'global1', 'VAR3' => 'global3' } + { 'VAR1' => 'global1', 'VAR3' => 'global3', 'VAR4' => 'global4' } end let(:job_variables) do { 'VAR1' => 'value1', 'VAR2' => 'value2' } @@ -802,16 +818,32 @@ module Gitlab { before_script: ['pwd'], variables: global_variables, - rspec: { script: 'rspec', variables: job_variables } + rspec: { script: 'rspec', variables: job_variables, inherit: inherit } } end - it 'returns all unique variables' do - expect(subject).to contain_exactly( - { key: 'VAR3', value: 'global3', public: true }, - { key: 'VAR1', value: 'value1', public: true }, - { key: 'VAR2', value: 'value2', public: true } - ) + context 'when no inheritance is specified' do + let(:inherit) { } + + it 'returns all unique variables' do + expect(subject).to contain_exactly( + { key: 'VAR4', value: 'global4', public: true }, + { key: 'VAR3', value: 'global3', public: true }, + { key: 'VAR1', value: 'value1', public: true }, + { key: 'VAR2', value: 'value2', public: true } + ) + end + end + + context 'when inheritance is disabled' do + let(:inherit) { { variables: false } } + + it 'does not inherit variables' do + expect(subject).to contain_exactly( + { key: 'VAR1', value: 'value1', public: true }, + { key: 'VAR2', value: 'value2', public: true } + ) + end end end |