Commit 121bc0af authored by Patrick Steinhardt's avatar Patrick Steinhardt

gitaly_client: Implement support for `#list_blobs`

The new `#list_blobs` RPC allows the caller to enumerate blobs via a set
of revisions. It's thus a more flexible sibling to `#get_new_blobs`,
which only allows a single positive revision and will automatically add
`--not --all`.

Add support for this new RPC via a new `#list_blobs` function in the
`BlobService`.
parent e3dd612a
...@@ -19,6 +19,25 @@ module Gitlab ...@@ -19,6 +19,25 @@ module Gitlab
consume_blob_response(response) consume_blob_response(response)
end end
def list_blobs(revisions, limit: 0, bytes_limit: 0, dynamic_timeout: nil)
request = Gitaly::ListBlobsRequest.new(
repository: @gitaly_repo,
revisions: Array.wrap(revisions),
limit: limit,
bytes_limit: bytes_limit
)
timeout =
if dynamic_timeout
[dynamic_timeout, GitalyClient.medium_timeout].min
else
GitalyClient.medium_timeout
end
response = GitalyClient.call(@gitaly_repo.storage_name, :blob_service, :list_blobs, request, timeout: timeout)
GitalyClient::BlobsStitcher.new(GitalyClient::ListBlobsAdapter.new(response))
end
def batch_lfs_pointers(blob_ids) def batch_lfs_pointers(blob_ids)
return [] if blob_ids.empty? return [] if blob_ids.empty?
......
# frozen_string_literal: true
module Gitlab
module GitalyClient
class ListBlobsAdapter
include Enumerable
def initialize(rpc_response)
@rpc_response = rpc_response
end
def each
@rpc_response.each do |msg|
msg.blobs.each do |blob|
yield blob
end
end
end
end
end
end
...@@ -88,4 +88,104 @@ RSpec.describe Gitlab::GitalyClient::BlobService do ...@@ -88,4 +88,104 @@ RSpec.describe Gitlab::GitalyClient::BlobService do
subject subject
end end
end end
describe '#list_blobs' do
let(:limit) { 0 }
let(:bytes_limit) { 0 }
let(:expected_params) { { revisions: revisions, limit: limit, bytes_limit: bytes_limit } }
before do
::Gitlab::GitalyClient.clear_stubs!
end
subject { client.list_blobs(revisions, limit: limit, bytes_limit: bytes_limit) }
context 'with a single revision' do
let(:revisions) { ['master'] }
it 'sends a list_blobs message' do
expect_next_instance_of(Gitaly::BlobService::Stub) do |service|
expect(service)
.to receive(:list_blobs)
.with(gitaly_request_with_params(expected_params), kind_of(Hash))
.and_return([])
end
subject
end
end
context 'with multiple revisions' do
let(:revisions) { ['master', '--not', '--all'] }
it 'sends a list_blobs message' do
expect_next_instance_of(Gitaly::BlobService::Stub) do |service|
expect(service)
.to receive(:list_blobs)
.with(gitaly_request_with_params(expected_params), kind_of(Hash))
.and_return([])
end
subject
end
end
context 'with multiple revisions and limits' do
let(:revisions) { ['master', '--not', '--all'] }
let(:limit) { 10 }
let(:bytes_lmit) { 1024 }
it 'sends a list_blobs message' do
expect_next_instance_of(Gitaly::BlobService::Stub) do |service|
expect(service)
.to receive(:list_blobs)
.with(gitaly_request_with_params(expected_params), kind_of(Hash))
.and_return([])
end
subject
end
end
context 'with split contents' do
let(:revisions) { ['master'] }
it 'sends a list_blobs message', :aggregate_failures do
expect_next_instance_of(Gitaly::BlobService::Stub) do |service|
expect(service)
.to receive(:list_blobs)
.with(gitaly_request_with_params(expected_params), kind_of(Hash))
.and_return([
Gitaly::ListBlobsResponse.new(blobs: [
Gitaly::ListBlobsResponse::Blob.new(oid: "012345", size: 8, data: "0x01"),
Gitaly::ListBlobsResponse::Blob.new(data: "23")
]),
Gitaly::ListBlobsResponse.new(blobs: [
Gitaly::ListBlobsResponse::Blob.new(data: "45"),
Gitaly::ListBlobsResponse::Blob.new(oid: "56", size: 4, data: "0x5"),
Gitaly::ListBlobsResponse::Blob.new(data: "6")
]),
Gitaly::ListBlobsResponse.new(blobs: [
Gitaly::ListBlobsResponse::Blob.new(oid: "78", size: 4, data: "0x78")
])
])
end
blobs = subject.to_a
expect(blobs.size).to be(3)
expect(blobs[0].id).to eq('012345')
expect(blobs[0].size).to eq(8)
expect(blobs[0].data).to eq('0x012345')
expect(blobs[1].id).to eq('56')
expect(blobs[1].size).to eq(4)
expect(blobs[1].data).to eq('0x56')
expect(blobs[2].id).to eq('78')
expect(blobs[2].size).to eq(4)
expect(blobs[2].data).to eq('0x78')
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment