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>2020-02-11 09:09:46 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-11 09:09:46 +0300
commit55733b19c526145cceb120e8bb874d476a84383a (patch)
treedcde3cfb905516cd1f07ab364a94aff5fddff391 /spec/lib/gitlab/ci
parentea99abb145ed193c2ac5d19efbff3b8990a54c9c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib/gitlab/ci')
-rw-r--r--spec/lib/gitlab/ci/config/entry/bridge_spec.rb227
-rw-r--r--spec/lib/gitlab/ci/config/entry/jobs_spec.rb68
-rw-r--r--spec/lib/gitlab/ci/config/entry/trigger_spec.rb164
3 files changed, 425 insertions, 34 deletions
diff --git a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
new file mode 100644
index 00000000000..07590556db8
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
@@ -0,0 +1,227 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Config::Entry::Bridge do
+ subject { described_class.new(config, name: :my_bridge) }
+
+ it_behaves_like 'with inheritable CI config' do
+ let(:inheritable_key) { 'default' }
+ let(:inheritable_class) { Gitlab::Ci::Config::Entry::Default }
+
+ # These are entries defined in Default
+ # that we know that we don't want to inherit
+ # as they do not have sense in context of Bridge
+ let(:ignored_inheritable_columns) do
+ %i[before_script after_script image services cache interruptible timeout
+ retry tags artifacts]
+ end
+ end
+
+ describe '.matching?' do
+ subject { described_class.matching?(name, config) }
+
+ context 'when config is not a hash' do
+ let(:name) { :my_trigger }
+ let(:config) { 'string' }
+
+ it { is_expected.to be_falsey }
+ end
+
+ context 'when config is a regular job' do
+ let(:name) { :my_trigger }
+ let(:config) do
+ { script: 'ls -al' }
+ end
+
+ it { is_expected.to be_falsey }
+
+ context 'with rules' do
+ let(:config) do
+ {
+ script: 'ls -al',
+ rules: [{ if: '$VAR == "value"', when: 'always' }]
+ }
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ context 'when config is a bridge job' do
+ let(:name) { :my_trigger }
+ let(:config) do
+ { trigger: 'other-project' }
+ end
+
+ it { is_expected.to be_truthy }
+
+ context 'with rules' do
+ let(:config) do
+ {
+ trigger: 'other-project',
+ rules: [{ if: '$VAR == "value"', when: 'always' }]
+ }
+ end
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
+ context 'when config is a hidden job' do
+ let(:name) { '.my_trigger' }
+ let(:config) do
+ { trigger: 'other-project' }
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe '.new' do
+ before do
+ subject.compose!
+ end
+
+ let(:base_config) do
+ {
+ trigger: { project: 'some/project', branch: 'feature' },
+ extends: '.some-key',
+ stage: 'deploy',
+ variables: { VARIABLE: '123' }
+ }
+ end
+
+ context 'when trigger config is a non-empty string' do
+ let(:config) { { trigger: 'some/project' } }
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'is returns a bridge job configuration' do
+ expect(subject.value).to eq(name: :my_bridge,
+ trigger: { project: 'some/project' },
+ ignore: false,
+ stage: 'test',
+ only: { refs: %w[branches tags] })
+ end
+ end
+ end
+
+ context 'when bridge trigger is a hash' do
+ let(:config) do
+ { trigger: { project: 'some/project', branch: 'feature' } }
+ end
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'is returns a bridge job configuration hash' do
+ expect(subject.value).to eq(name: :my_bridge,
+ trigger: { project: 'some/project',
+ branch: 'feature' },
+ ignore: false,
+ stage: 'test',
+ only: { refs: %w[branches tags] })
+ end
+ end
+ end
+
+ context 'when bridge configuration contains trigger, when, extends, stage, only, except, and variables' do
+ let(:config) do
+ base_config.merge({
+ when: 'always',
+ only: { variables: %w[$SOMEVARIABLE] },
+ except: { refs: %w[feature] }
+ })
+ end
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when bridge configuration uses rules' do
+ let(:config) { base_config.merge({ rules: [{ if: '$VAR == null', when: 'never' }] }) }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when bridge configuration uses rules with job:when' do
+ let(:config) do
+ base_config.merge({
+ when: 'always',
+ rules: [{ if: '$VAR == null', when: 'never' }]
+ })
+ end
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when bridge configuration uses rules with only' do
+ let(:config) do
+ base_config.merge({
+ only: { variables: %w[$SOMEVARIABLE] },
+ rules: [{ if: '$VAR == null', when: 'never' }]
+ })
+ end
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when bridge configuration uses rules with except' do
+ let(:config) do
+ base_config.merge({
+ except: { refs: %w[feature] },
+ rules: [{ if: '$VAR == null', when: 'never' }]
+ })
+ end
+
+ it { is_expected.not_to be_valid }
+ end
+
+ context 'when bridge has only job needs' do
+ let(:config) do
+ {
+ needs: ['some_job']
+ }
+ end
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+ end
+
+ context 'when bridge config contains unknown keys' do
+ let(:config) { { unknown: 123 } }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'is returns an error about unknown config key' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: unknown/
+ end
+ end
+ end
+
+ context 'when bridge config contains build-specific attributes' do
+ let(:config) { { script: 'something' } }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'returns an error message' do
+ expect(subject.errors.first)
+ .to match /contains unknown keys: script/
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
index 61c8956d41f..05249b7c717 100644
--- a/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/jobs_spec.rb
@@ -5,27 +5,31 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Jobs do
let(:entry) { described_class.new(config) }
+ let(:config) do
+ {
+ '.hidden_job'.to_sym => { script: 'something' },
+ '.hidden_bridge'.to_sym => { trigger: 'my/project' },
+ regular_job: { script: 'something' },
+ my_trigger: { trigger: 'my/project' }
+ }
+ end
+
describe '.all_types' do
subject { described_class.all_types }
it { is_expected.to include(::Gitlab::Ci::Config::Entry::Hidden) }
it { is_expected.to include(::Gitlab::Ci::Config::Entry::Job) }
+ it { is_expected.to include(::Gitlab::Ci::Config::Entry::Bridge) }
end
describe '.find_type' do
using RSpec::Parameterized::TableSyntax
- let(:config) do
- {
- '.hidden_job'.to_sym => { script: 'something' },
- regular_job: { script: 'something' },
- invalid_job: 'text'
- }
- end
-
where(:name, :type) do
:'.hidden_job' | ::Gitlab::Ci::Config::Entry::Hidden
+ :'.hidden_bridge' | ::Gitlab::Ci::Config::Entry::Hidden
:regular_job | ::Gitlab::Ci::Config::Entry::Job
+ :my_trigger | ::Gitlab::Ci::Config::Entry::Bridge
:invalid_job | nil
end
@@ -42,8 +46,6 @@ describe Gitlab::Ci::Config::Entry::Jobs do
end
context 'when entry config value is correct' do
- let(:config) { { rspec: { script: 'rspec' } } }
-
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
@@ -88,43 +90,41 @@ describe Gitlab::Ci::Config::Entry::Jobs do
entry.compose!
end
- let(:config) do
- { rspec: { script: 'rspec' },
- spinach: { script: 'spinach' },
- '.hidden'.to_sym => {} }
- end
-
describe '#value' do
it 'returns key value' do
expect(entry.value).to eq(
- rspec: { name: :rspec,
- script: %w[rspec],
- ignore: false,
- stage: 'test',
- only: { refs: %w[branches tags] },
- variables: {} },
- spinach: { name: :spinach,
- script: %w[spinach],
- ignore: false,
- stage: 'test',
- only: { refs: %w[branches tags] },
- variables: {} })
+ my_trigger: {
+ ignore: false,
+ name: :my_trigger,
+ only: { refs: %w[branches tags] },
+ stage: 'test',
+ trigger: { project: 'my/project' }
+ },
+ regular_job: {
+ ignore: false,
+ name: :regular_job,
+ only: { refs: %w[branches tags] },
+ script: ['something'],
+ stage: 'test',
+ variables: {}
+ })
end
end
describe '#descendants' do
it 'creates valid descendant nodes' do
- expect(entry.descendants.count).to eq 3
- expect(entry.descendants.first(2))
- .to all(be_an_instance_of(Gitlab::Ci::Config::Entry::Job))
- expect(entry.descendants.last)
- .to be_an_instance_of(Gitlab::Ci::Config::Entry::Hidden)
+ expect(entry.descendants.map(&:class)).to eq [
+ Gitlab::Ci::Config::Entry::Hidden,
+ Gitlab::Ci::Config::Entry::Hidden,
+ Gitlab::Ci::Config::Entry::Job,
+ Gitlab::Ci::Config::Entry::Bridge
+ ]
end
end
describe '#value' do
it 'returns value of visible jobs only' do
- expect(entry.value.keys).to eq [:rspec, :spinach]
+ expect(entry.value.keys).to eq [:regular_job, :my_trigger]
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb
new file mode 100644
index 00000000000..752c3f59a95
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Config::Entry::Trigger do
+ subject { described_class.new(config) }
+
+ context 'when trigger config is a non-empty string' do
+ let(:config) { 'some/project' }
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'returns a trigger configuration hash' do
+ expect(subject.value).to eq(project: 'some/project')
+ end
+ end
+ end
+
+ context 'when trigger config an empty string' do
+ let(:config) { '' }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'returns an error about an empty config' do
+ expect(subject.errors.first)
+ .to match /config can't be blank/
+ end
+ end
+ end
+
+ context 'when trigger is a hash' do
+ context 'when branch is provided' do
+ let(:config) { { project: 'some/project', branch: 'feature' } }
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'returns a trigger configuration hash' do
+ expect(subject.value)
+ .to eq(project: 'some/project', branch: 'feature')
+ end
+ end
+ end
+
+ context 'when strategy is provided' do
+ context 'when strategy is depend' do
+ let(:config) { { project: 'some/project', strategy: 'depend' } }
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'returns a trigger configuration hash' do
+ expect(subject.value)
+ .to eq(project: 'some/project', strategy: 'depend')
+ end
+ end
+ end
+
+ context 'when strategy is invalid' do
+ let(:config) { { project: 'some/project', strategy: 'notdepend' } }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'returns an error about unknown config key' do
+ expect(subject.errors.first)
+ .to match /trigger strategy should be depend/
+ end
+ end
+ end
+ end
+
+ describe '#include' do
+ context 'with simple include' do
+ let(:config) { { include: 'path/to/config.yml' } }
+
+ it { is_expected.to be_valid }
+
+ it 'returns a trigger configuration hash' do
+ expect(subject.value).to eq(include: 'path/to/config.yml' )
+ end
+ end
+
+ context 'with project' do
+ let(:config) { { project: 'some/project', include: 'path/to/config.yml' } }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns an error' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: project/
+ end
+ end
+
+ context 'with branch' do
+ let(:config) { { branch: 'feature', include: 'path/to/config.yml' } }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns an error' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: branch/
+ end
+ end
+
+ context 'when feature flag is off' do
+ before do
+ stub_feature_flags(ci_parent_child_pipeline: false)
+ end
+
+ let(:config) { { include: 'path/to/config.yml' } }
+
+ it 'is returns an error if include is used' do
+ expect(subject.errors.first)
+ .to match /config must specify project/
+ end
+ end
+ end
+
+ context 'when config contains unknown keys' do
+ let(:config) { { project: 'some/project', unknown: 123 } }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'returns an error about unknown config key' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: unknown/
+ end
+ end
+ end
+ end
+
+ context 'when trigger configuration is not valid' do
+ context 'when branch is not provided' do
+ let(:config) { 123 }
+
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
+
+ describe '#errors' do
+ it 'returns an error message' do
+ expect(subject.errors.first)
+ .to match /has to be either a string or a hash/
+ end
+ end
+ end
+ end
+end