summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-06 15:08:05 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-06 15:08:05 +0000
commitf78257cbddd711e18cbce93ad740a4aa0acac347 (patch)
tree7f018abe3ce1c0010879cc480f348a35e616fabb /spec
parentf500600a43b531e2e7a5858b74bd35312b02c349 (diff)
downloadgitlab-ce-f78257cbddd711e18cbce93ad740a4aa0acac347.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/fixtures/ci_build_artifacts.zipbin106365 -> 107464 bytes
-rw-r--r--spec/lib/backup/manager_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/artifact_file_reader_spec.rb100
-rw-r--r--spec/lib/gitlab/ci/config/entry/bridge_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb16
-rw-r--r--spec/lib/gitlab/ci/config/entry/jobs_spec.rb1
-rw-r--r--spec/lib/gitlab/ci/config/entry/processable_spec.rb105
-rw-r--r--spec/lib/gitlab/ci/config/entry/root_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/config/external/file/artifact_spec.rb167
-rw-r--r--spec/lib/gitlab/ci/config/external/file/local_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/config/external/file/project_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/config_spec.rb88
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb76
-rw-r--r--spec/lib/gitlab/config/entry/attributable_spec.rb2
-rw-r--r--spec/models/ci/job_artifact_spec.rb6
-rw-r--r--spec/models/ci/pipeline_spec.rb13
-rw-r--r--spec/models/snippet_spec.rb26
-rw-r--r--spec/requests/api/runner_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/custom_config_content_spec.rb67
-rw-r--r--spec/services/projects/fork_service_spec.rb1
-rw-r--r--spec/services/projects/update_repository_storage_service_spec.rb68
-rw-r--r--spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb46
-rw-r--r--spec/workers/post_receive_spec.rb22
24 files changed, 769 insertions, 115 deletions
diff --git a/spec/fixtures/ci_build_artifacts.zip b/spec/fixtures/ci_build_artifacts.zip
index dae976d918e..91ec9f7dcd0 100644
--- a/spec/fixtures/ci_build_artifacts.zip
+++ b/spec/fixtures/ci_build_artifacts.zip
Binary files differ
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index cee299522ce..b86e92d5969 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -319,18 +319,21 @@ describe Backup::Manager do
context 'when there is a non-tarred backup in the directory' do
before do
- allow(Dir).to receieve(:glob).and_return(
+ allow(Dir).to receive(:glob).and_return(
[
'backup_information.yml'
]
)
+ allow(File).to receive(:exist?).and_return(true)
+ end
+
+ it 'selects the non-tarred backup to restore from' do
+ expect(Kernel).not_to receive(:system)
- it 'selects the non-tarred backup to restore from' do
- expect { subject.unpack }.to output.to_stdout
- expect(progress).to have_received(:puts)
- .with(a_string_matching('Non tarred backup found '))
- expect(Kernel).not_to receive(:system)
- end
+ subject.unpack
+
+ expect(progress).to have_received(:puts)
+ .with(a_string_matching('Non tarred backup found '))
end
end
end
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
diff --git a/spec/lib/gitlab/config/entry/attributable_spec.rb b/spec/lib/gitlab/config/entry/attributable_spec.rb
index bc29a194181..64a4670f483 100644
--- a/spec/lib/gitlab/config/entry/attributable_spec.rb
+++ b/spec/lib/gitlab/config/entry/attributable_spec.rb
@@ -59,7 +59,7 @@ describe Gitlab::Config::Entry::Attributable do
end
end
- expectation.to raise_error(ArgumentError, 'Method already defined: length')
+ expectation.to raise_error(ArgumentError, /Method 'length' already defined in/)
end
end
end
diff --git a/spec/models/ci/job_artifact_spec.rb b/spec/models/ci/job_artifact_spec.rb
index 8f56d735f36..0a7a44b225c 100644
--- a/spec/models/ci/job_artifact_spec.rb
+++ b/spec/models/ci/job_artifact_spec.rb
@@ -25,7 +25,7 @@ describe Ci::JobArtifact do
end
it_behaves_like 'UpdateProjectStatistics' do
- subject { build(:ci_job_artifact, :archive, size: 106365) }
+ subject { build(:ci_job_artifact, :archive, size: 107464) }
end
end
@@ -35,7 +35,7 @@ describe Ci::JobArtifact do
end
it_behaves_like 'UpdateProjectStatistics' do
- subject { build(:ci_job_artifact, :archive, size: 106365) }
+ subject { build(:ci_job_artifact, :archive, size: 107464) }
end
end
@@ -173,7 +173,7 @@ describe Ci::JobArtifact do
let(:artifact) { create(:ci_job_artifact, :archive, project: project) }
it 'sets the size from the file size' do
- expect(artifact.size).to eq(106365)
+ expect(artifact.size).to eq(107464)
end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 76051ecb177..f775906a545 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -2553,6 +2553,19 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#find_job_with_archive_artifacts' do
+ let!(:old_job) { create(:ci_build, name: 'rspec', retried: true, pipeline: pipeline) }
+ let!(:job_without_artifacts) { create(:ci_build, name: 'rspec', pipeline: pipeline) }
+ let!(:expected_job) { create(:ci_build, :artifacts, name: 'rspec', pipeline: pipeline ) }
+ let!(:different_job) { create(:ci_build, name: 'deploy', pipeline: pipeline) }
+
+ subject { pipeline.find_job_with_archive_artifacts('rspec') }
+
+ it 'finds the expected job' do
+ expect(subject).to eq(expected_job)
+ end
+ end
+
describe '#latest_builds_with_artifacts' do
let!(:fresh_build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
let!(:stale_build) { create(:ci_build, :success, :expired, :artifacts, pipeline: pipeline) }
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 87ace7b51f4..95807f5f0c1 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -511,6 +511,32 @@ describe Snippet do
end
end
+ describe '#blobs' do
+ let(:snippet) { create(:snippet) }
+
+ context 'when repository does not exist' do
+ it 'returns empty array' do
+ expect(snippet.blobs).to be_empty
+ end
+ end
+
+ context 'when repository exists' do
+ let(:snippet) { create(:snippet, :repository) }
+
+ it 'returns array of blobs' do
+ expect(snippet.blobs).to all(be_a(Blob))
+ end
+ end
+
+ it 'returns a blob representing the snippet data' do
+ blob = snippet.blob
+
+ expect(blob).to be_a(Blob)
+ expect(blob.path).to eq(snippet.file_name)
+ expect(blob.data).to eq(snippet.content)
+ end
+ end
+
describe '#to_json' do
let(:snippet) { build(:snippet) }
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index e76ab8d409b..6e5c2088ee7 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -756,7 +756,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
expect(json_response['dependencies'].count).to eq(1)
expect(json_response['dependencies']).to include(
{ 'id' => job.id, 'name' => job.name, 'token' => job.token,
- 'artifacts_file' => { 'filename' => 'ci_build_artifacts.zip', 'size' => 106365 } })
+ 'artifacts_file' => { 'filename' => 'ci_build_artifacts.zip', 'size' => 107464 } })
end
end
diff --git a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
index 2657f1d300a..112b19fcbc5 100644
--- a/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
+++ b/spec/services/ci/create_pipeline_service/custom_config_content_spec.rb
@@ -4,30 +4,77 @@ require 'spec_helper'
describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:admin) }
- let(:upstream_pipeline) { create(:ci_pipeline) }
let(:ref) { 'refs/heads/master' }
let(:service) { described_class.new(project, user, { ref: ref }) }
+ let(:upstream_pipeline) { create(:ci_pipeline, project: project) }
+ let(:bridge) { create(:ci_bridge, pipeline: upstream_pipeline) }
+
+ subject { service.execute(:push, bridge: bridge) }
+
context 'custom config content' do
let(:bridge) do
create(:ci_bridge, status: 'running', pipeline: upstream_pipeline, project: upstream_pipeline.project).tap do |bridge|
- allow(bridge).to receive(:yaml_for_downstream).and_return(
- <<~YML
- rspec:
- script: rspec
- custom:
- script: custom
- YML
- )
+ allow(bridge).to receive(:yaml_for_downstream).and_return(config_from_bridge)
end
end
- subject { service.execute(:push, bridge: bridge) }
+ let(:config_from_bridge) do
+ <<~YML
+ rspec:
+ script: rspec
+ custom:
+ script: custom
+ YML
+ end
+
+ before do
+ allow(bridge).to receive(:yaml_for_downstream).and_return config_from_bridge
+ end
it 'creates a pipeline using the content passed in as param' do
expect(subject).to be_persisted
expect(subject.builds.map(&:name)).to eq %w[rspec custom]
expect(subject.config_source).to eq 'bridge_source'
end
+
+ context 'when bridge includes yaml from artifact' do
+ # the generated.yml is available inside the ci_build_artifacts.zip associated
+ # to the generator_job
+ let(:config_from_bridge) do
+ <<~YML
+ include:
+ - artifact: generated.yml
+ job: generator
+ YML
+ end
+
+ context 'when referenced job exists' do
+ let!(:generator_job) do
+ create(:ci_build, :artifacts,
+ project: project,
+ pipeline: upstream_pipeline,
+ name: 'generator')
+ end
+
+ it 'created a pipeline using the content passed in as param and download the artifact' do
+ expect(subject).to be_persisted
+ expect(subject.builds.pluck(:name)).to eq %w[rspec time custom]
+ expect(subject.config_source).to eq 'bridge_source'
+ end
+ end
+
+ context 'when referenced job does not exist' do
+ it 'creates an empty pipeline' do
+ expect(subject).to be_persisted
+ expect(subject).to be_failed
+ expect(subject.errors.full_messages)
+ .to contain_exactly(
+ 'Job `generator` not found in parent pipeline or does not have artifacts!')
+ expect(subject.builds.pluck(:name)).to be_empty
+ expect(subject.config_source).to eq 'bridge_source'
+ end
+ end
+ end
end
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 12c51d01d63..cbf7a135c41 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -315,6 +315,7 @@ describe Projects::ForkService do
# Stub everything required to move a project to a Gitaly shard that does not exist
stub_storage_settings('test_second_storage' => { 'path' => 'tmp/tests/second_storage' })
allow_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror).and_return(true)
+ allow_any_instance_of(Gitlab::Git::Repository).to receive(:checksum).and_return(::Gitlab::Git::BLANK_SHA)
Projects::UpdateRepositoryStorageService.new(project).execute('test_second_storage')
fork_after_move = fork_project(project)
diff --git a/spec/services/projects/update_repository_storage_service_spec.rb b/spec/services/projects/update_repository_storage_service_spec.rb
index a0917f718e6..2e9a4626abb 100644
--- a/spec/services/projects/update_repository_storage_service_spec.rb
+++ b/spec/services/projects/update_repository_storage_service_spec.rb
@@ -16,6 +16,15 @@ describe Projects::UpdateRepositoryStorageService do
context 'without wiki and design repository' do
let(:project) { create(:project, :repository, repository_read_only: true, wiki_enabled: false) }
+ let!(:checksum) { project.repository.checksum }
+ let(:project_repository_double) { double(:repository) }
+
+ before do
+ allow(Gitlab::Git::Repository).to receive(:new).and_call_original
+ allow(Gitlab::Git::Repository).to receive(:new)
+ .with('test_second_storage', project.repository.raw.relative_path, project.repository.gl_repository, project.repository.full_path)
+ .and_return(project_repository_double)
+ end
context 'when the move succeeds' do
it 'moves the repository to the new storage and unmarks the repository as read only' do
@@ -23,10 +32,14 @@ describe Projects::UpdateRepositoryStorageService do
project.repository.path_to_repo
end
- expect_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror)
+ expect(project_repository_double).to receive(:fetch_repository_as_mirror)
.with(project.repository.raw).and_return(true)
+ expect(project_repository_double).to receive(:checksum)
+ .and_return(checksum)
+
+ result = subject.execute('test_second_storage')
- subject.execute('test_second_storage')
+ expect(result[:status]).to eq(:success)
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('test_second_storage')
expect(gitlab_shell.repository_exists?('default', old_path)).to be(false)
@@ -44,16 +57,50 @@ describe Projects::UpdateRepositoryStorageService do
context 'when the move fails' do
it 'unmarks the repository as read-only without updating the repository storage' do
- expect_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror)
+ expect(project_repository_double).to receive(:fetch_repository_as_mirror)
.with(project.repository.raw).and_return(false)
expect(GitlabShellWorker).not_to receive(:perform_async)
- subject.execute('test_second_storage')
+ result = subject.execute('test_second_storage')
+ expect(result[:status]).to eq(:error)
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
end
end
+
+ context 'when the checksum does not match' do
+ it 'unmarks the repository as read-only without updating the repository storage' do
+ expect(project_repository_double).to receive(:fetch_repository_as_mirror)
+ .with(project.repository.raw).and_return(true)
+ expect(project_repository_double).to receive(:checksum)
+ .and_return('not matching checksum')
+ expect(GitlabShellWorker).not_to receive(:perform_async)
+
+ result = subject.execute('test_second_storage')
+
+ expect(result[:status]).to eq(:error)
+ expect(project).not_to be_repository_read_only
+ expect(project.repository_storage).to eq('default')
+ end
+ end
+
+ context 'when a object pool was joined' do
+ let!(:pool) { create(:pool_repository, :ready, source_project: project) }
+
+ it 'leaves the pool' do
+ expect(project_repository_double).to receive(:fetch_repository_as_mirror)
+ .with(project.repository.raw).and_return(true)
+ expect(project_repository_double).to receive(:checksum)
+ .and_return(checksum)
+
+ result = subject.execute('test_second_storage')
+
+ expect(result[:status]).to eq(:success)
+ expect(project.repository_storage).to eq('test_second_storage')
+ expect(project.reload_pool_repository).to be_nil
+ end
+ end
end
context 'with wiki repository' do
@@ -66,18 +113,5 @@ describe Projects::UpdateRepositoryStorageService do
end
end
end
-
- context 'when a object pool was joined' do
- let(:project) { create(:project, :repository, wiki_enabled: false, repository_read_only: true) }
- let(:pool) { create(:pool_repository, :ready, source_project: project) }
-
- it 'leaves the pool' do
- allow_any_instance_of(Gitlab::Git::Repository).to receive(:fetch_repository_as_mirror).and_return(true)
-
- subject.execute('test_second_storage')
-
- expect(project.reload_pool_repository).to be_nil
- end
- end
end
end
diff --git a/spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb
index 556d81133bc..95772b1774a 100644
--- a/spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb
@@ -53,7 +53,7 @@ RSpec.shared_examples 'with inheritable CI config' do
let(:deps) do
if inheritable_key
- double('deps', inheritable_key => inheritable, '[]' => unspecified)
+ double('deps', "#{inheritable_key}_entry" => inheritable, '[]' => unspecified)
else
inheritable
end
@@ -68,7 +68,7 @@ RSpec.shared_examples 'with inheritable CI config' do
it 'does inherit value' do
expect(inheritable).to receive('[]').with(entry_key).and_return(specified)
- entry.compose!(deps)
+ entry.send(:inherit!, deps)
expect(entry[entry_key]).to eq(specified)
end
@@ -86,7 +86,7 @@ RSpec.shared_examples 'with inheritable CI config' do
expect do
# we ignore exceptions as `#overwrite_entry`
# can raise exception on duplicates
- entry.compose!(deps) rescue described_class::InheritError
+ entry.send(:inherit!, deps) rescue described_class::InheritError
end.not_to change { entry[entry_key] }
end
end
@@ -94,7 +94,7 @@ RSpec.shared_examples 'with inheritable CI config' do
context 'when inheritable does not specify' do
it 'does not inherit value' do
- entry.compose!(deps)
+ entry.send(:inherit!, deps)
expect(entry[entry_key]).to be_a(
Gitlab::Config::Entry::Undefined)
diff --git a/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb b/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
index f222dff60ab..6f83f52d54b 100644
--- a/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
@@ -2,7 +2,10 @@
RSpec.shared_examples 'moves repository to another storage' do |repository_type|
let(:project_repository_double) { double(:repository) }
+ let!(:project_repository_checksum) { project.repository.checksum }
+
let(:repository_double) { double(:repository) }
+ let(:repository_checksum) { repository.checksum }
before do
# Default stub for non-specified params
@@ -19,15 +22,16 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
context 'when the move succeeds', :clean_gitlab_redis_shared_state do
before do
- allow(project_repository_double)
- .to receive(:fetch_repository_as_mirror)
+ allow(project_repository_double).to receive(:fetch_repository_as_mirror)
.with(project.repository.raw)
.and_return(true)
+ allow(project_repository_double).to receive(:checksum)
+ .and_return(project_repository_checksum)
- allow(repository_double)
- .to receive(:fetch_repository_as_mirror)
- .with(repository.raw)
- .and_return(true)
+ allow(repository_double).to receive(:fetch_repository_as_mirror)
+ .with(repository.raw).and_return(true)
+ allow(repository_double).to receive(:checksum)
+ .and_return(repository_checksum)
end
it "moves the project and its #{repository_type} repository to the new storage and unmarks the repository as read only" do
@@ -37,8 +41,9 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
old_repository_path = repository.full_path
- subject.execute('test_second_storage')
+ result = subject.execute('test_second_storage')
+ expect(result[:status]).to eq(:success)
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('test_second_storage')
expect(gitlab_shell.repository_exists?('default', old_project_repository_path)).to be(false)
@@ -87,13 +92,38 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
it 'unmarks the repository as read-only without updating the repository storage' do
allow(project_repository_double).to receive(:fetch_repository_as_mirror)
.with(project.repository.raw).and_return(true)
+ allow(project_repository_double).to receive(:checksum)
+ .and_return(project_repository_checksum)
allow(repository_double).to receive(:fetch_repository_as_mirror)
.with(repository.raw).and_return(false)
expect(GitlabShellWorker).not_to receive(:perform_async)
- subject.execute('test_second_storage')
+ result = subject.execute('test_second_storage')
+
+ expect(result[:status]).to eq(:error)
+ expect(project).not_to be_repository_read_only
+ expect(project.repository_storage).to eq('default')
+ end
+ end
+
+ context "when the checksum of the #{repository_type} repository does not match" do
+ it 'unmarks the repository as read-only without updating the repository storage' do
+ allow(project_repository_double).to receive(:fetch_repository_as_mirror)
+ .with(project.repository.raw).and_return(true)
+ allow(project_repository_double).to receive(:checksum)
+ .and_return(project_repository_checksum)
+
+ allow(repository_double).to receive(:fetch_repository_as_mirror)
+ .with(repository.raw).and_return(true)
+ allow(repository_double).to receive(:checksum)
+ .and_return('not matching checksum')
+
+ expect(GitlabShellWorker).not_to receive(:perform_async)
+
+ result = subject.execute('test_second_storage')
+ expect(result[:status]).to eq(:error)
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
end
diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb
index 72e423db611..2a2d0f5a857 100644
--- a/spec/workers/post_receive_spec.rb
+++ b/spec/workers/post_receive_spec.rb
@@ -421,17 +421,35 @@ describe PostReceive do
perform
end
end
+
+ it 'updates the snippet db information' do
+ blob = snippet.blobs.first
+
+ expect(snippet).to receive(:update).with(file_name: blob.path, content: blob.data)
+
+ perform
+ end
+
+ context 'when snippet does not have any blob' do
+ it 'does not update snippet db information' do
+ allow(snippet).to receive(:blobs).and_return([])
+
+ expect(snippet).not_to receive(:update)
+
+ perform
+ end
+ end
end
end
context 'with PersonalSnippet' do
- let!(:snippet) { create(:personal_snippet, author: project.owner) }
+ let!(:snippet) { create(:personal_snippet, :repository, author: project.owner) }
it_behaves_like 'snippet changes actions'
end
context 'with ProjectSnippet' do
- let!(:snippet) { create(:project_snippet, project: project, author: project.owner) }
+ let!(:snippet) { create(:project_snippet, :repository, project: project, author: project.owner) }
it_behaves_like 'snippet changes actions'
end