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:
Diffstat (limited to 'spec/lib/gitlab/git')
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb36
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb288
-rw-r--r--spec/lib/gitlab/git/tag_spec.rb14
-rw-r--r--spec/lib/gitlab/git/tree_spec.rb107
4 files changed, 333 insertions, 112 deletions
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index f58bab52cfa..f4dba5e8d58 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -364,19 +364,39 @@ RSpec.describe Gitlab::Git::Commit, :seed_helper do
end
describe '.between' do
- subject do
- commits = described_class.between(repository, SeedRepo::Commit::PARENT_ID, SeedRepo::Commit::ID)
- commits.map { |c| c.id }
+ let(:limit) { nil }
+ let(:commit_ids) { commits.map(&:id) }
+
+ subject(:commits) { described_class.between(repository, from, to, limit: limit) }
+
+ context 'requesting a single commit' do
+ let(:from) { SeedRepo::Commit::PARENT_ID }
+ let(:to) { SeedRepo::Commit::ID }
+
+ it { expect(commit_ids).to contain_exactly(to) }
end
- it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
+ context 'requesting a commit range' do
+ let(:from) { 'v1.0.0' }
+ let(:to) { 'v1.2.0' }
- context 'between_uses_list_commits FF disabled' do
- before do
- stub_feature_flags(between_uses_list_commits: false)
+ let(:commits_in_range) do
+ %w[
+ 570e7b2abdd848b95f2f578043fc23bd6f6fd24d
+ 5937ac0a7beb003549fc5fd26fc247adbce4a52e
+ eb49186cfa5c4338011f5f590fac11bd66c5c631
+ ]
end
- it { is_expected.to contain_exactly(SeedRepo::Commit::ID) }
+ context 'no limit' do
+ it { expect(commit_ids).to eq(commits_in_range) }
+ end
+
+ context 'limited' do
+ let(:limit) { 2 }
+
+ it { expect(commit_ids).to eq(commits_in_range.last(2)) }
+ end
end
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 29e7a1dce1d..9ecd281cce0 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -109,6 +109,32 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :tag_names
end
+ describe '#tags' do
+ subject { repository.tags }
+
+ it 'gets tags from GitalyClient' do
+ expect_next_instance_of(Gitlab::GitalyClient::RefService) do |service|
+ expect(service).to receive(:tags)
+ end
+
+ subject
+ end
+
+ context 'with sorting option' do
+ subject { repository.tags(sort_by: 'name_asc') }
+
+ it 'gets tags from GitalyClient' do
+ expect_next_instance_of(Gitlab::GitalyClient::RefService) do |service|
+ expect(service).to receive(:tags).with(sort_by: 'name_asc')
+ end
+
+ subject
+ end
+ end
+
+ it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :tags
+ end
+
describe '#archive_metadata' do
let(:storage_path) { '/tmp' }
let(:cache_key) { File.join(repository.gl_repository, SeedRepo::LastCommit::ID) }
@@ -936,6 +962,159 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
end
+ describe '#new_blobs' do
+ let(:repository) { mutable_repository }
+ let(:repository_rugged) { mutable_repository_rugged }
+ let(:blob) { create_blob('This is a new blob') }
+ let(:commit) { create_commit('nested/new-blob.txt' => blob) }
+
+ def create_blob(content)
+ repository_rugged.write(content, :blob)
+ end
+
+ def create_commit(blobs)
+ author = { name: 'Test User', email: 'mail@example.com', time: Time.now }
+
+ index = repository_rugged.index
+ blobs.each do |path, oid|
+ index.add(path: path, oid: oid, mode: 0100644)
+ end
+
+ Rugged::Commit.create(repository_rugged,
+ author: author,
+ committer: author,
+ message: "Message",
+ parents: [],
+ tree: index.write_tree(repository_rugged))
+ end
+
+ subject { repository.new_blobs(newrevs).to_a }
+
+ shared_examples '#new_blobs with revisions' do
+ before do
+ expect_next_instance_of(Gitlab::GitalyClient::BlobService) do |service|
+ expect(service)
+ .to receive(:list_blobs)
+ .with(expected_newrevs,
+ limit: Gitlab::Git::Repository::REV_LIST_COMMIT_LIMIT,
+ with_paths: true,
+ dynamic_timeout: nil)
+ .once
+ .and_call_original
+ end
+ end
+
+ it 'enumerates new blobs' do
+ expect(subject).to match_array(expected_blobs)
+ end
+
+ it 'memoizes results' do
+ expect(subject).to match_array(expected_blobs)
+ expect(subject).to match_array(expected_blobs)
+ end
+ end
+
+ context 'with a single revision' do
+ let(:newrevs) { commit }
+ let(:expected_newrevs) { ['--not', '--all', '--not', newrevs] }
+ let(:expected_blobs) do
+ [have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with a single-entry array' do
+ let(:newrevs) { [commit] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
+ let(:expected_blobs) do
+ [have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with multiple revisions' do
+ let(:another_blob) { create_blob('Another blob') }
+ let(:newrevs) { [commit, create_commit('another_path.txt' => another_blob)] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs.sort }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18),
+ have_attributes(class: Gitlab::Git::Blob, id: another_blob, path: 'another_path.txt', size: 12)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with partially blank revisions' do
+ let(:newrevs) { [nil, commit, Gitlab::Git::BLANK_SHA] }
+ let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with repeated revisions' do
+ let(:newrevs) { [commit, commit, commit] }
+ let(:expected_newrevs) { ['--not', '--all', '--not', commit] }
+ let(:expected_blobs) do
+ [
+ have_attributes(class: Gitlab::Git::Blob, id: blob, path: 'nested/new-blob.txt', size: 18)
+ ]
+ end
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ context 'with preexisting commits' do
+ let(:newrevs) { ['refs/heads/master'] }
+ let(:expected_newrevs) { ['--not', '--all', '--not'] + newrevs }
+ let(:expected_blobs) { [] }
+
+ it_behaves_like '#new_blobs with revisions'
+ end
+
+ shared_examples '#new_blobs without revisions' do
+ before do
+ expect(Gitlab::GitalyClient::BlobService).not_to receive(:new)
+ end
+
+ it 'returns an empty array' do
+ expect(subject).to eq([])
+ end
+ end
+
+ context 'with a single nil newrev' do
+ let(:newrevs) { nil }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with a single zero newrev' do
+ let(:newrevs) { Gitlab::Git::BLANK_SHA }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with an empty array' do
+ let(:newrevs) { [] }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+
+ context 'with array containing only empty refs' do
+ let(:newrevs) { [nil, Gitlab::Git::BLANK_SHA] }
+
+ it_behaves_like '#new_blobs without revisions'
+ end
+ end
+
describe '#new_commits' do
let(:repository) { mutable_repository }
let(:new_commit) do
@@ -1132,28 +1311,6 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
end
- describe '#ref_name_for_sha' do
- let(:ref_path) { 'refs/heads' }
- let(:sha) { repository.find_branch('master').dereferenced_target.id }
- let(:ref_name) { 'refs/heads/master' }
-
- it 'returns the ref name for the given sha' do
- expect(repository.ref_name_for_sha(ref_path, sha)).to eq(ref_name)
- end
-
- it "returns an empty name if the ref doesn't exist" do
- expect(repository.ref_name_for_sha(ref_path, "000000")).to eq("")
- end
-
- it "raise an exception if the ref is empty" do
- expect { repository.ref_name_for_sha(ref_path, "") }.to raise_error(ArgumentError)
- end
-
- it "raise an exception if the ref is nil" do
- expect { repository.ref_name_for_sha(ref_path, nil) }.to raise_error(ArgumentError)
- end
- end
-
describe '#branches' do
subject { repository.branches }
@@ -1732,83 +1889,42 @@ RSpec.describe Gitlab::Git::Repository, :seed_helper do
end
describe '#set_full_path' do
- shared_examples '#set_full_path' do
- before do
- repository_rugged.config["gitlab.fullpath"] = repository_path
- end
-
- context 'is given a path' do
- it 'writes it to disk' do
- repository.set_full_path(full_path: "not-the/real-path.git")
-
- config = File.read(File.join(repository_path, "config"))
-
- expect(config).to include("[gitlab]")
- expect(config).to include("fullpath = not-the/real-path.git")
- end
- end
-
- context 'it is given an empty path' do
- it 'does not write it to disk' do
- repository.set_full_path(full_path: "")
-
- config = File.read(File.join(repository_path, "config"))
-
- expect(config).to include("[gitlab]")
- expect(config).to include("fullpath = #{repository_path}")
- end
- end
+ before do
+ repository_rugged.config["gitlab.fullpath"] = repository_path
+ end
- context 'repository does not exist' do
- it 'raises NoRepository and does not call Gitaly WriteConfig' do
- repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project')
+ context 'is given a path' do
+ it 'writes it to disk' do
+ repository.set_full_path(full_path: "not-the/real-path.git")
- expect(repository.gitaly_repository_client).not_to receive(:set_full_path)
+ config = File.read(File.join(repository_path, "config"))
- expect do
- repository.set_full_path(full_path: 'foo/bar.git')
- end.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
+ expect(config).to include("[gitlab]")
+ expect(config).to include("fullpath = not-the/real-path.git")
end
end
- context 'with :set_full_path enabled' do
- before do
- stub_feature_flags(set_full_path: true)
- end
+ context 'it is given an empty path' do
+ it 'does not write it to disk' do
+ repository.set_full_path(full_path: "")
- it_behaves_like '#set_full_path'
- end
+ config = File.read(File.join(repository_path, "config"))
- context 'with :set_full_path disabled' do
- before do
- stub_feature_flags(set_full_path: false)
+ expect(config).to include("[gitlab]")
+ expect(config).to include("fullpath = #{repository_path}")
end
-
- it_behaves_like '#set_full_path'
end
- end
- describe '#set_config' do
- let(:repository) { mutable_repository }
- let(:entries) do
- {
- 'test.foo1' => 'bla bla',
- 'test.foo2' => 1234,
- 'test.foo3' => true
- }
- end
+ context 'repository does not exist' do
+ it 'raises NoRepository and does not call Gitaly WriteConfig' do
+ repository = Gitlab::Git::Repository.new('default', 'does/not/exist.git', '', 'group/project')
- it 'can set config settings' do
- expect(repository.set_config(entries)).to be_nil
+ expect(repository.gitaly_repository_client).not_to receive(:set_full_path)
- expect(repository_rugged.config['test.foo1']).to eq('bla bla')
- expect(repository_rugged.config['test.foo2']).to eq('1234')
- expect(repository_rugged.config['test.foo3']).to eq('true')
- end
-
- after do
- entries.keys.each { |k| repository_rugged.config.delete(k) }
+ expect do
+ repository.set_full_path(full_path: 'foo/bar.git')
+ end.to raise_error(Gitlab::Git::Repository::NoRepository)
+ end
end
end
diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb
index 79ae47f8a7b..4f56595d7d2 100644
--- a/spec/lib/gitlab/git/tag_spec.rb
+++ b/spec/lib/gitlab/git/tag_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0200") }
end
- shared_examples 'signed tag' do
+ describe 'signed tag' do
let(:project) { create(:project, :repository) }
let(:tag) { project.repository.find_tag('v1.1.1') }
@@ -54,18 +54,6 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0100") }
end
- context 'with :get_tag_signatures enabled' do
- it_behaves_like 'signed tag'
- end
-
- context 'with :get_tag_signatures disabled' do
- before do
- stub_feature_flags(get_tag_signatures: false)
- end
-
- it_behaves_like 'signed tag'
- end
-
it { expect(repository.tags.size).to eq(SeedRepo::Repo::TAGS.size) }
end
diff --git a/spec/lib/gitlab/git/tree_spec.rb b/spec/lib/gitlab/git/tree_spec.rb
index f11d84bd8d3..005f8ecaa3a 100644
--- a/spec/lib/gitlab/git/tree_spec.rb
+++ b/spec/lib/gitlab/git/tree_spec.rb
@@ -189,12 +189,109 @@ RSpec.describe Gitlab::Git::Tree, :seed_helper do
end
it_behaves_like :repo do
- context 'with pagination parameters' do
- let(:pagination_params) { { limit: 3, page_token: nil } }
+ describe 'Pagination' do
+ context 'with restrictive limit' do
+ let(:pagination_params) { { limit: 3, page_token: nil } }
+
+ it 'returns limited paginated list of tree objects' do
+ expect(entries.count).to eq(3)
+ expect(cursor.next_cursor).to be_present
+ end
+ end
+
+ context 'when limit is equal to number of entries' do
+ let(:entries_count) { entries.count }
+
+ it 'returns all entries without a cursor' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: entries_count, page_token: nil })
+
+ expect(cursor).to be_nil
+ expect(result.entries.count).to eq(entries_count)
+ end
+ end
+
+ context 'when limit is 0' do
+ let(:pagination_params) { { limit: 0, page_token: nil } }
+
+ it 'returns empty result' do
+ expect(entries).to eq([])
+ expect(cursor).to be_nil
+ end
+ end
+
+ context 'when limit is missing' do
+ let(:pagination_params) { { limit: nil, page_token: nil } }
+
+ it 'returns empty result' do
+ expect(entries).to eq([])
+ expect(cursor).to be_nil
+ end
+ end
+
+ context 'when limit is negative' do
+ let(:entries_count) { entries.count }
+
+ it 'returns all entries' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: -1, page_token: nil })
+
+ expect(result.count).to eq(entries_count)
+ expect(cursor).to be_nil
+ end
+
+ context 'when token is provided' do
+ let(:pagination_params) { { limit: 1000, page_token: nil } }
+ let(:token) { entries.second.id }
+
+ it 'returns all entries after token' do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: -1, page_token: token })
+
+ expect(result.count).to eq(entries.count - 2)
+ expect(cursor).to be_nil
+ end
+ end
+ end
+
+ context 'when token does not exist' do
+ let(:pagination_params) { { limit: 5, page_token: 'aabbccdd' } }
+
+ it 'raises a command error' do
+ expect { entries }.to raise_error(Gitlab::Git::CommandError, 'could not find starting OID: aabbccdd')
+ end
+ end
+
+ context 'when limit is bigger than number of entries' do
+ let(:pagination_params) { { limit: 1000, page_token: nil } }
+
+ it 'returns only available entries' do
+ expect(entries.count).to be < 20
+ expect(cursor).to be_nil
+ end
+ end
+
+ it 'returns all tree entries in specific order during cursor pagination' do
+ collected_entries = []
+ token = nil
+
+ expected_entries = entries
+
+ loop do
+ result, cursor = Gitlab::Git::Tree.where(repository, sha, path, recursive, { limit: 5, page_token: token })
+
+ collected_entries += result.entries
+ token = cursor&.next_cursor
+
+ break if token.blank?
+ end
+
+ expect(collected_entries.map(&:path)).to match_array(expected_entries.map(&:path))
+
+ expected_order = [
+ collected_entries.select(&:dir?).map(&:path),
+ collected_entries.select(&:file?).map(&:path),
+ collected_entries.select(&:submodule?).map(&:path)
+ ].flatten
- it 'does not support pagination' do
- expect(entries.count).to be >= 10
- expect(cursor).to be_nil
+ expect(collected_entries.map(&:path)).to eq(expected_order)
end
end
end