diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-24 18:06:05 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-09-24 18:06:05 +0000 |
commit | 2ed368929ab5094fec5da8038f723463596a80cf (patch) | |
tree | aec98d50349b0e9a490db0099253b801b2d1a9ea /spec/lib | |
parent | f1a5755898e865428c923587402fd965b601c4ea (diff) | |
download | gitlab-ce-2ed368929ab5094fec5da8038f723463596a80cf.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib')
-rw-r--r-- | spec/lib/gitlab/ci/config/external/context_spec.rb | 128 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/base_spec.rb | 10 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/local_spec.rb | 11 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/project_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/remote_spec.rb | 12 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/file/template_spec.rb | 12 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/mapper_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config/external/processor_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/config_spec.rb | 48 |
9 files changed, 228 insertions, 17 deletions
diff --git a/spec/lib/gitlab/ci/config/external/context_spec.rb b/spec/lib/gitlab/ci/config/external/context_spec.rb new file mode 100644 index 00000000000..610646ca85a --- /dev/null +++ b/spec/lib/gitlab/ci/config/external/context_spec.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +describe Gitlab::Ci::Config::External::Context do + let(:project) { double('Project') } + let(:user) { double('User') } + let(:sha) { '12345' } + let(:attributes) { { project: project, user: user, sha: sha } } + + subject(:subject) { described_class.new(**attributes) } + + describe 'attributes' do + context 'with values' do + it { is_expected.to have_attributes(**attributes) } + it { expect(subject.expandset).to eq(Set.new) } + it { expect(subject.execution_deadline).to eq(0) } + end + + context 'without values' do + let(:attributes) { { project: nil, user: nil, sha: nil } } + + it { is_expected.to have_attributes(**attributes) } + it { expect(subject.expandset).to eq(Set.new) } + it { expect(subject.execution_deadline).to eq(0) } + end + end + + describe '#set_deadline' do + let(:stubbed_time) { 1 } + + before do + allow(subject).to receive(:current_monotonic_time).and_return(stubbed_time) + end + + context 'with a float value' do + let(:timeout_seconds) { 10.5.seconds } + + it 'updates execution_deadline' do + expect { subject.set_deadline(timeout_seconds) } + .to change { subject.execution_deadline } + .to(timeout_seconds + stubbed_time) + end + end + + context 'with nil as a value' do + let(:timeout_seconds) {} + + it 'updates execution_deadline' do + expect { subject.set_deadline(timeout_seconds) } + .to change { subject.execution_deadline } + .to(stubbed_time) + end + end + end + + describe '#check_execution_time!' do + before do + allow(subject).to receive(:current_monotonic_time).and_return(stubbed_time) + allow(subject).to receive(:execution_deadline).and_return(stubbed_deadline) + end + + context 'when execution is expired' do + let(:stubbed_time) { 2 } + let(:stubbed_deadline) { 1 } + + it 'raises an error' do + expect { subject.check_execution_time! } + .to raise_error(described_class::TimeoutError) + end + end + + context 'when execution is not expired' do + let(:stubbed_time) { 1 } + let(:stubbed_deadline) { 2 } + + it 'does not raises any errors' do + expect { subject.check_execution_time! }.not_to raise_error + end + end + + context 'without setting a deadline' do + let(:stubbed_time) { 2 } + let(:stubbed_deadline) { 1 } + + before do + allow(subject).to receive(:execution_deadline).and_call_original + end + + it 'does not raises any errors' do + expect { subject.check_execution_time! }.not_to raise_error + end + end + end + + describe '#mutate' do + shared_examples 'a mutated context' do + let(:mutated) { subject.mutate(new_attributes) } + + before do + subject.expandset << :a_file + subject.set_deadline(15.seconds) + end + + it { expect(mutated).not_to eq(subject) } + it { expect(mutated).to be_a(described_class) } + it { expect(mutated).to have_attributes(new_attributes) } + it { expect(mutated.expandset).to eq(subject.expandset) } + it { expect(mutated.execution_deadline).to eq(mutated.execution_deadline) } + end + + context 'with attributes' do + let(:new_attributes) { { project: double, user: double, sha: '56789' } } + + it_behaves_like 'a mutated context' + end + + context 'without attributes' do + let(:new_attributes) { {} } + + it_behaves_like 'a mutated context' + end + end + + describe '#sentry_payload' do + it { expect(subject.sentry_payload).to match(a_hash_including(:project, :user)) } + 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 af995f4869a..d472d6527e2 100644 --- a/spec/lib/gitlab/ci/config/external/file/base_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/base_spec.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true -require 'fast_spec_helper' +require 'spec_helper' describe Gitlab::Ci::Config::External::File::Base do - let(:context) { described_class::Context.new(nil, 'HEAD', nil, Set.new) } + let(:context_params) { { sha: 'HEAD' } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:test_class) do Class.new(described_class) do - def initialize(params, context = {}) + def initialize(params, context) @location = params super @@ -20,6 +21,9 @@ describe Gitlab::Ci::Config::External::File::Base do before do allow_any_instance_of(test_class) .to receive(:content).and_return('key: value') + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) end describe '#matching?' do 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 9451db9522a..95f0c93e758 100644 --- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb @@ -7,10 +7,17 @@ describe Gitlab::Ci::Config::External::File::Local do set(:user) { create(:user) } let(:sha) { '12345' } - let(:context) { described_class::Context.new(project, sha, user, Set.new) } + 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) } + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + end + describe '#matching?' do context 'when a local is specified' do let(:params) { { local: 'file' } } @@ -109,7 +116,7 @@ describe Gitlab::Ci::Config::External::File::Local do describe '#expand_context' do let(:location) { 'location.yml' } - subject { local_file.send(:expand_context) } + subject { local_file.send(:expand_context_attrs) } it 'inherits project, user and sha' do is_expected.to include(user: user, project: project, sha: sha) 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 4acb4f324d3..dd869c227a1 100644 --- a/spec/lib/gitlab/ci/config/external/file/project_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/project_spec.rb @@ -8,11 +8,15 @@ describe Gitlab::Ci::Config::External::File::Project do set(:user) { create(:user) } let(:context_user) { user } - let(:context) { described_class::Context.new(context_project, '12345', context_user, Set.new) } + let(:context_params) { { project: context_project, sha: '12345', user: context_user } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:project_file) { described_class.new(params, context) } before do project.add_developer(user) + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) end describe '#matching?' do @@ -145,7 +149,7 @@ describe Gitlab::Ci::Config::External::File::Project do describe '#expand_context' do let(:params) { { file: 'file.yml', project: project.full_path, ref: 'master' } } - subject { project_file.send(:expand_context) } + 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) 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 4a097b59216..08db00dda9d 100644 --- a/spec/lib/gitlab/ci/config/external/file/remote_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/remote_spec.rb @@ -5,7 +5,8 @@ require 'spec_helper' describe Gitlab::Ci::Config::External::File::Remote do include StubRequests - let(:context) { described_class::Context.new(nil, '12345', nil, Set.new) } + let(:context_params) { { sha: '12345' } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:params) { { remote: location } } let(:remote_file) { described_class.new(params, context) } let(:location) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' } @@ -19,6 +20,11 @@ describe Gitlab::Ci::Config::External::File::Remote do HEREDOC end + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + end + describe '#matching?' do context 'when a remote is specified' do let(:params) { { remote: 'http://remote' } } @@ -187,10 +193,10 @@ describe Gitlab::Ci::Config::External::File::Remote do describe '#expand_context' do let(:params) { { remote: 'http://remote' } } - subject { remote_file.send(:expand_context) } + subject { remote_file.send(:expand_context_attrs) } it 'drops all parameters' do - is_expected.to include(user: nil, project: nil, sha: nil) + is_expected.to be_empty end end end diff --git a/spec/lib/gitlab/ci/config/external/file/template_spec.rb b/spec/lib/gitlab/ci/config/external/file/template_spec.rb index 1609b8fd66b..164b5800abf 100644 --- a/spec/lib/gitlab/ci/config/external/file/template_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/template_spec.rb @@ -6,12 +6,18 @@ describe Gitlab::Ci::Config::External::File::Template do set(:project) { create(:project) } set(:user) { create(:user) } - let(:context) { described_class::Context.new(project, '12345', user, Set.new) } + let(:context_params) { { project: project, sha: '12345', user: user } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:template) { 'Auto-DevOps.gitlab-ci.yml' } let(:params) { { template: template } } let(:template_file) { described_class.new(params, context) } + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + end + describe '#matching?' do context 'when a template is specified' do let(:params) { { template: 'some-template' } } @@ -97,10 +103,10 @@ describe Gitlab::Ci::Config::External::File::Template do describe '#expand_context' do let(:location) { 'location.yml' } - subject { template_file.send(:expand_context) } + subject { template_file.send(:expand_context_attrs) } it 'drops all parameters' do - is_expected.to include(user: nil, project: nil, sha: nil) + is_expected.to be_empty 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 43708852594..8d09aa47f12 100644 --- a/spec/lib/gitlab/ci/config/external/mapper_spec.rb +++ b/spec/lib/gitlab/ci/config/external/mapper_spec.rb @@ -11,7 +11,8 @@ describe Gitlab::Ci::Config::External::Mapper do let(:local_file) { '/lib/gitlab/ci/templates/non-existent-file.yml' } let(:remote_url) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' } let(:template_file) { 'Auto-DevOps.gitlab-ci.yml' } - let(:expandset) { Set.new } + let(:context_params) { { project: project, sha: '123456', user: user } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } let(:file_content) do <<~HEREDOC @@ -21,10 +22,13 @@ describe Gitlab::Ci::Config::External::Mapper do before do stub_full_request(remote_url).to_return(body: file_content) + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) end describe '#process' do - subject { described_class.new(values, project: project, sha: '123456', user: user, expandset: expandset).process } + subject { described_class.new(values, context).process } context "when single 'include' keyword is defined" do context 'when the string is a local file' do diff --git a/spec/lib/gitlab/ci/config/external/processor_spec.rb b/spec/lib/gitlab/ci/config/external/processor_spec.rb index 3b1a1e804f0..bb2d3f66972 100644 --- a/spec/lib/gitlab/ci/config/external/processor_spec.rb +++ b/spec/lib/gitlab/ci/config/external/processor_spec.rb @@ -9,12 +9,16 @@ describe Gitlab::Ci::Config::External::Processor do set(:another_project) { create(:project, :repository) } set(:user) { create(:user) } - let(:expandset) { Set.new } let(:sha) { '12345' } - let(:processor) { described_class.new(values, project: project, sha: '12345', user: user, expandset: expandset) } + let(:context_params) { { project: project, sha: sha, user: user } } + let(:context) { Gitlab::Ci::Config::External::Context.new(**context_params) } + let(:processor) { described_class.new(values, context) } before do project.add_developer(user) + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) end describe "#perform" do diff --git a/spec/lib/gitlab/ci/config_spec.rb b/spec/lib/gitlab/ci/config_spec.rb index 839b4f9261d..68c38644b5c 100644 --- a/spec/lib/gitlab/ci/config_spec.rb +++ b/spec/lib/gitlab/ci/config_spec.rb @@ -7,6 +7,11 @@ describe Gitlab::Ci::Config do set(:user) { create(:user) } + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + end + let(:config) do described_class.new(yml, project: nil, sha: nil, user: nil) end @@ -303,6 +308,49 @@ describe Gitlab::Ci::Config do end end + context "when it takes too long to evaluate includes" do + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + .and_call_original + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:set_deadline) + .with(described_class::TIMEOUT_SECONDS) + .and_call_original + + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:execution_expired?) + .and_return(true) + end + + it 'raises error TimeoutError' do + expect(Gitlab::Sentry).to receive(:track_exception) + + expect { config }.to raise_error( + described_class::ConfigError, + 'Resolving config took longer than expected' + ) + end + end + + context 'when context expansion timeout is disabled' do + before do + allow_any_instance_of(Gitlab::Ci::Config::External::Context) + .to receive(:check_execution_time!) + .and_call_original + + 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 |