diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/base_spec.rb | 36 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/local_spec.rb | 33 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/remote_spec.rb | 30 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/template_spec.rb | 93 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/mapper_spec.rb | 116 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/processor_spec.rb | 5 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config_spec.rb | 17 |
7 files changed, 287 insertions, 43 deletions
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 2e92d5204d6..ada8775c489 100644 --- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb @@ -3,13 +3,43 @@ require 'fast_spec_helper' describe Gitlab::Ci::Config::External::File::Base do - subject { described_class.new(location) } + let(:context) { described_class::Context.new(nil, 'HEAD') } + + let(:test_class) do + Class.new(described_class) do + def initialize(params, context = {}) + @location = params + + super + end + end + end + + subject { test_class.new(location, context) } before do - allow_any_instance_of(described_class) + allow_any_instance_of(test_class) .to receive(:content).and_return('key: value') end + describe '#matching?' do + context 'when a location is present' do + let(:location) { 'some-location' } + + it 'should return true' do + expect(subject).to be_matching + end + end + + context 'with a location is missing' do + let(:location) { nil } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + end + describe '#valid?' do context 'when location is not a YAML file' do let(:location) { 'some/file.txt' } @@ -39,7 +69,7 @@ describe Gitlab::Ci::Config::External::File::Base do let(:location) { 'some/file/config.yml' } before do - allow_any_instance_of(described_class) + allow_any_instance_of(test_class) .to receive(:content).and_return('invalid_syntax') 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 645db642e29..83be43e240b 100644 --- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb @@ -3,8 +3,37 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::File::Local do - let(:project) { create(:project, :repository) } - let(:local_file) { described_class.new(location, { project: project, sha: '12345' }) } + set(:project) { create(:project, :repository) } + + let(:context) { described_class::Context.new(project, '12345') } + let(:params) { { local: location } } + let(:local_file) { described_class.new(params, context) } + + describe '#matching?' do + context 'when a local is specified' do + let(:params) { { local: 'file' } } + + it 'should return true' do + expect(local_file).to be_matching + end + end + + context 'with a missing local' do + let(:params) { { local: nil } } + + it 'should return false' do + expect(local_file).not_to be_matching + end + end + + context 'with a missing local key' do + let(:params) { {} } + + it 'should return false' do + expect(local_file).not_to be_matching + end + end + end describe '#valid?' do context 'when is a valid local path' do diff --git a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb index eaf621e4140..319e7137f9f 100644 --- a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb @@ -3,7 +3,9 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::File::Remote do - let(:remote_file) { described_class.new(location) } + let(:context) { described_class::Context.new(nil, '12345') } + let(:params) { { remote: location } } + let(:remote_file) { described_class.new(params, context) } let(:location) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } let(:remote_file_content) do <<~HEREDOC @@ -15,6 +17,32 @@ describe Gitlab::Ci::Config::External::File::Remote do HEREDOC end + describe '#matching?' do + context 'when a remote is specified' do + let(:params) { { remote: 'http://remote' } } + + it 'should return true' do + expect(remote_file).to be_matching + end + end + + context 'with a missing remote' do + let(:params) { { remote: nil } } + + it 'should return false' do + expect(remote_file).not_to be_matching + end + end + + context 'with a missing remote key' do + let(:params) { {} } + + it 'should return false' do + expect(remote_file).not_to be_matching + end + end + end + describe "#valid?" do context 'when is a valid remote url' do before do diff --git a/spec/lib/gitlab/ci/config/external/file/template_spec.rb b/spec/lib/gitlab/ci/config/external/file/template_spec.rb new file mode 100644 index 00000000000..1fb5655309a --- /dev/null +++ b/spec/lib/gitlab/ci/config/external/file/template_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Ci::Config::External::File::Template do + let(:context) { described_class::Context.new(nil, '12345') } + let(:template) { 'Auto-DevOps.gitlab-ci.yml' } + let(:params) { { template: template } } + + subject { described_class.new(params, context) } + + describe '#matching?' do + context 'when a template is specified' do + let(:params) { { template: 'some-template' } } + + it 'should return true' do + expect(subject).to be_matching + end + end + + context 'with a missing template' do + let(:params) { { template: nil } } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + + context 'with a missing template key' do + let(:params) { {} } + + it 'should return false' do + expect(subject).not_to be_matching + end + end + end + + describe "#valid?" do + context 'when is a valid template name' do + let(:template) { 'Auto-DevOps.gitlab-ci.yml' } + + it 'should return true' do + expect(subject).to be_valid + end + end + + context 'with invalid template name' do + let(:template) { 'Template.yml' } + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include('Template file `Template.yml` is not a valid location!') + end + end + + context 'with a non-existing template' do + let(:template) { 'I-Do-Not-Have-This-Template.gitlab-ci.yml' } + + it 'should return false' do + expect(subject).not_to be_valid + expect(subject.error_message).to include('Included file `I-Do-Not-Have-This-Template.gitlab-ci.yml` is empty or does not exist!') + end + end + end + + describe '#template_name' do + let(:template_name) { subject.send(:template_name) } + + context 'when template does end with .gitlab-ci.yml' do + let(:template) { 'my-template.gitlab-ci.yml' } + + it 'returns template name' do + expect(template_name).to eq('my-template') + end + end + + context 'when template is nil' do + let(:template) { nil } + + it 'returns nil' do + expect(template_name).to be_nil + end + end + + context 'when template does not end with .gitlab-ci.yml' do + let(:template) { 'my-template' } + + it 'returns nil' do + expect(template_name).to be_nil + end + end + end +end diff --git a/spec/lib/gitlab/ci/config/external/mapper_spec.rb b/spec/lib/gitlab/ci/config/external/mapper_spec.rb index 5b236fe99f1..e27d2cd9422 100644 --- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb @@ -3,84 +3,130 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::Mapper do - let(:project) { create(:project, :repository) } + set(:project) { create(:project, :repository) } + + let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' } + let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } + let(:template_file) { 'Auto-DevOps.gitlab-ci.yml' } + let(:file_content) do <<~HEREDOC image: 'ruby:2.2' HEREDOC end + before do + WebMock.stub_request(:get, remote_url).to_return(body: file_content) + end + describe '#process' do - subject { described_class.new(values, project, '123456').process } + subject { described_class.new(values, project: project, sha: '123456').process } - context "when 'include' keyword is defined as string" do + context "when single 'include' keyword is defined" do context 'when the string is a local file' do let(:values) do - { - include: '/lib/gitlab/ci/templates/non-existent-file.yml', - image: 'ruby:2.2' - } + { include: local_file, + image: 'ruby:2.2' } + end + + it 'returns File instances' do + expect(subject).to contain_exactly( + an_instance_of(Gitlab::Ci::Config::External::File::Local)) end + end - it 'returns an array' do - expect(subject).to be_an(Array) + context 'when the key is a local file hash' do + let(:values) do + { include: { 'local' => local_file }, + image: 'ruby:2.2' } end it 'returns File instances' do - expect(subject.first) - .to be_an_instance_of(Gitlab::Ci::Config::External::File::Local) + expect(subject).to contain_exactly( + an_instance_of(Gitlab::Ci::Config::External::File::Local)) end end context 'when the string is a remote file' do - let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } let(:values) do - { - include: remote_url, - image: 'ruby:2.2' - } + { include: remote_url, image: 'ruby:2.2' } + end + + it 'returns File instances' do + expect(subject).to contain_exactly( + an_instance_of(Gitlab::Ci::Config::External::File::Remote)) + end + end + + context 'when the key is a remote file hash' do + let(:values) do + { include: { 'remote' => remote_url }, + image: 'ruby:2.2' } end - before do - WebMock.stub_request(:get, remote_url).to_return(body: file_content) + it 'returns File instances' do + expect(subject).to contain_exactly( + an_instance_of(Gitlab::Ci::Config::External::File::Remote)) end + end - it 'returns an array' do - expect(subject).to be_an(Array) + context 'when the key is a template file hash' do + let(:values) do + { include: { 'template' => template_file }, + image: 'ruby:2.2' } end it 'returns File instances' do - expect(subject.first) - .to be_an_instance_of(Gitlab::Ci::Config::External::File::Remote) + expect(subject).to contain_exactly( + an_instance_of(Gitlab::Ci::Config::External::File::Template)) + end + end + + context 'when the key is a hash of file and remote' do + let(:values) do + { include: { 'local' => local_file, 'remote' => remote_url }, + image: 'ruby:2.2' } + end + + it 'returns ambigious specification error' do + expect { subject }.to raise_error(described_class::AmbigiousSpecificationError) end end end context "when 'include' is defined as an array" do - let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-ce/blob/1234/.gitlab-ci-1.yml' } let(:values) do - { - include: - [ - remote_url, - '/lib/gitlab/ci/templates/template.yml' - ], - image: 'ruby:2.2' - } + { include: [remote_url, local_file], + image: 'ruby:2.2' } end - before do - WebMock.stub_request(:get, remote_url).to_return(body: file_content) + it 'returns Files instances' do + expect(subject).to all(respond_to(:valid?)) + expect(subject).to all(respond_to(:content)) end + end - it 'returns an array' do - expect(subject).to be_an(Array) + context "when 'include' is defined as an array of hashes" do + let(:values) do + { include: [{ remote: remote_url }, { local: local_file }], + image: 'ruby:2.2' } end it 'returns Files instances' do expect(subject).to all(respond_to(:valid?)) expect(subject).to all(respond_to(:content)) end + + context 'when it has ambigious match' do + let(:values) do + { include: [{ remote: remote_url, local: local_file }], + image: 'ruby:2.2' } + end + + it 'returns ambigious specification error' do + expect { subject }.to raise_error(described_class::AmbigiousSpecificationError) + end + end end context "when 'include' is not defined" do diff --git a/spec/lib/gitlab/ci/config/external/processor_spec.rb b/spec/lib/gitlab/ci/config/external/processor_spec.rb index dbd28e9745c..d2d4fbc5115 100644 --- a/spec/lib/gitlab/ci/config/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/config/external/processor_spec.rb @@ -3,8 +3,9 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::Processor do - let(:project) { create(:project, :repository) } - let(:processor) { described_class.new(values, project, '12345') } + set(:project) { create(:project, :repository) } + + let(:processor) { described_class.new(values, project: project, sha: '12345') } describe "#perform" do context 'when no external files defined' do diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index ea6f1e20014..49988468d1a 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -205,6 +205,23 @@ describe Gitlab::Ci::Config do end end + context "when gitlab_ci.yml has ambigious 'include' defined" do + let(:gitlab_ci_yml) do + <<~HEREDOC + include: + remote: http://url + local: /local/file.yml + HEREDOC + end + + it 'raises error YamlProcessor validationError' do + expect { config }.to raise_error( + described_class::ConfigError, + 'Include `{"remote":"http://url","local":"/local/file.yml"}` needs to match exactly one accessor!' + ) + end + end + describe 'external file version' do context 'when external local file SHA is defined' do it 'is using a defined value' do |