summaryrefslogtreecommitdiff
path: root/spec/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-24 18:06:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-24 18:06:05 +0000
commit2ed368929ab5094fec5da8038f723463596a80cf (patch)
treeaec98d50349b0e9a490db0099253b801b2d1a9ea /spec/lib
parentf1a5755898e865428c923587402fd965b601c4ea (diff)
downloadgitlab-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.rb128
-rw-r--r--spec/lib/gitlab/ci/config/external/file/base_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/config/external/file/local_spec.rb11
-rw-r--r--spec/lib/gitlab/ci/config/external/file/project_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/external/file/remote_spec.rb12
-rw-r--r--spec/lib/gitlab/ci/config/external/file/template_spec.rb12
-rw-r--r--spec/lib/gitlab/ci/config/external/mapper_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config/external/processor_spec.rb8
-rw-r--r--spec/lib/gitlab/ci/config_spec.rb48
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