summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2016-05-17 13:20:11 -0500
committerKamil Trzcinski <ayufan@ayufan.eu>2016-05-17 13:20:11 -0500
commit24145592e804ffbe58a38b15095808919337d545 (patch)
treea3d4108b84bfab9f7813b982ce53fdd45d5306f4
parenta82109eee80bf703ad8e82de2410f490e5fc6d54 (diff)
downloadgitlab-ce-24145592e804ffbe58a38b15095808919337d545.tar.gz
Provide full test coverage to lib/container_registry API implementation
-rw-r--r--app/controllers/projects/container_registry_controller.rb2
-rw-r--r--app/models/project.rb2
-rw-r--r--lib/container_registry/blob.rb10
-rw-r--r--lib/container_registry/client.rb8
-rw-r--r--lib/container_registry/registry.rb2
-rw-r--r--lib/container_registry/repository.rb28
-rw-r--r--lib/container_registry/tag.rb20
-rw-r--r--spec/lib/container_registry/blob_spec.rb61
-rw-r--r--spec/lib/container_registry/registry_spec.rb2
-rw-r--r--spec/lib/container_registry/repository_spec.rb65
-rw-r--r--spec/lib/container_registry/tag_spec.rb89
11 files changed, 232 insertions, 57 deletions
diff --git a/app/controllers/projects/container_registry_controller.rb b/app/controllers/projects/container_registry_controller.rb
index e48f205d216..8ed5a8ff6fd 100644
--- a/app/controllers/projects/container_registry_controller.rb
+++ b/app/controllers/projects/container_registry_controller.rb
@@ -22,6 +22,6 @@ class Projects::ContainerRegistryController < Projects::ApplicationController
end
def tag
- @tag ||= container_registry_repository[params[:id]]
+ @tag ||= container_registry_repository.tag(params[:id])
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 8e80a6b5c01..09a214da043 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -336,7 +336,7 @@ class Project < ActiveRecord::Base
url = Gitlab.config.registry.api_url
host_port = Gitlab.config.registry.host_port
registry = ContainerRegistry::Registry.new(url, token: token, path: host_port)
- registry[path_with_namespace]
+ registry.repository(path_with_namespace)
end
end
diff --git a/lib/container_registry/blob.rb b/lib/container_registry/blob.rb
index d59792a383e..4e20dc4f875 100644
--- a/lib/container_registry/blob.rb
+++ b/lib/container_registry/blob.rb
@@ -2,6 +2,8 @@ module ContainerRegistry
class Blob
attr_reader :repository, :config
+ delegate :registry, :client, to: :repository
+
def initialize(repository, config)
@repository = repository
@config = config || {}
@@ -35,10 +37,6 @@ module ContainerRegistry
revision[0..8]
end
- def client
- @client ||= repository.client
- end
-
def delete
client.delete_blob(repository.name, digest)
end
@@ -46,9 +44,5 @@ module ContainerRegistry
def data
@data ||= client.blob(repository.name, digest, type)
end
-
- def mount_to(to_repository)
- client.repository_mount_blob(to_repository.name, digest, repository.name)
- end
end
end
diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb
index c250a4b6946..4d726692f45 100644
--- a/lib/container_registry/client.rb
+++ b/lib/container_registry/client.rb
@@ -22,14 +22,6 @@ module ContainerRegistry
@faraday.get("/v2/#{name}/manifests/#{reference}").body
end
- def put_repository_manifest(name, reference, manifest)
- @faraday.put("/v2/#{name}/manifests/#{reference}", manifest, { "Content-Type" => MANIFEST_VERSION }).success?
- end
-
- def repository_mount_blob(name, digest, from)
- @faraday.post("/v2/#{name}/blobs/uploads/?mount=#{digest}&from=#{from}").status == 201
- end
-
def repository_tag_digest(name, reference)
response = @faraday.head("/v2/#{name}/manifests/#{reference}")
response.headers['docker-content-digest'] if response.success?
diff --git a/lib/container_registry/registry.rb b/lib/container_registry/registry.rb
index 07490de94ba..0e634f6b6ef 100644
--- a/lib/container_registry/registry.rb
+++ b/lib/container_registry/registry.rb
@@ -8,7 +8,7 @@ module ContainerRegistry
@client = ContainerRegistry::Client.new(uri, options)
end
- def [](name)
+ def repository(name)
ContainerRegistry::Repository.new(self, name)
end
diff --git a/lib/container_registry/repository.rb b/lib/container_registry/repository.rb
index 77825056138..0e4a7cb3cc9 100644
--- a/lib/container_registry/repository.rb
+++ b/lib/container_registry/repository.rb
@@ -2,19 +2,17 @@ module ContainerRegistry
class Repository
attr_reader :registry, :name
+ delegate :client, to: :registry
+
def initialize(registry, name)
@registry, @name = registry, name
end
- def client
- @client ||= registry.client
- end
-
def path
[registry.path, name].compact.join('/')
end
- def [](tag)
+ def tag(tag)
ContainerRegistry::Tag.new(self, tag)
end
@@ -37,26 +35,14 @@ module ContainerRegistry
end
end
+ def blob(config)
+ ContainerRegistry::Blob.new(self, config)
+ end
+
def delete_tags
return unless tags
tags.all?(&:delete)
end
-
- def mount_blob(blob)
- return unless blob
-
- client.repository_mount_blob(name, blob.digest, blob.repository.name)
- end
-
- def mount_manifest(tag, manifest)
- client.put_repository_manifest(name, tag, manifest)
- end
-
- def copy_to(other_repository)
- tags.all? do |tag|
- tag.copy_to(other_repository)
- end
- end
end
end
diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb
index f06806db6a8..43f8d6dc8c2 100644
--- a/lib/container_registry/tag.rb
+++ b/lib/container_registry/tag.rb
@@ -2,6 +2,8 @@ module ContainerRegistry
class Tag
attr_reader :repository, :name
+ delegate :registry, :client, to: :repository
+
def initialize(repository, name)
@repository, @name = repository, name
end
@@ -36,7 +38,7 @@ module ContainerRegistry
return @config_blob if defined?(@config_blob)
return unless manifest && manifest['config']
- @config_blob = ContainerRegistry::Blob.new(repository, manifest['config'])
+ @config_blob = repository.blob(manifest['config'])
end
def config
@@ -56,7 +58,7 @@ module ContainerRegistry
return unless manifest
@layers = manifest['layers'].map do |layer|
- ContainerRegistry::Blob.new(repository, layer)
+ repository.blob(layer)
end
end
@@ -71,19 +73,5 @@ module ContainerRegistry
client.delete_repository_tag(repository.name, digest)
end
-
- def copy_to(repository)
- return unless manifest
-
- layers.each do |blob|
- repository.mount_blob(blob)
- end
- repository.mount_blob(config_blob)
- repository.mount_manifest(name, manifest.to_json)
- end
-
- def client
- @client ||= repository.client
- end
end
end
diff --git a/spec/lib/container_registry/blob_spec.rb b/spec/lib/container_registry/blob_spec.rb
new file mode 100644
index 00000000000..4d8cb787dde
--- /dev/null
+++ b/spec/lib/container_registry/blob_spec.rb
@@ -0,0 +1,61 @@
+require 'spec_helper'
+
+describe ContainerRegistry::Blob do
+ let(:digest) { 'sha256:0123456789012345' }
+ let(:config) do
+ {
+ 'digest' => digest,
+ 'mediaType' => 'binary',
+ 'size' => 1000
+ }
+ end
+
+ let(:registry) { ContainerRegistry::Registry.new('http://example.com') }
+ let(:repository) { registry.repository('group/test') }
+ let(:blob) { repository.blob(config) }
+
+ it { expect(blob).to respond_to(:repository) }
+ it { expect(blob).to delegate_method(:registry).to(:repository) }
+ it { expect(blob).to delegate_method(:client).to(:repository) }
+
+ context '#path' do
+ subject { blob.path }
+
+ it { is_expected.to eq('example.com/group/test@sha256:0123456789012345') }
+ end
+
+ context '#digest' do
+ subject { blob.digest }
+
+ it { is_expected.to eq(digest) }
+ end
+
+ context '#type' do
+ subject { blob.type }
+
+ it { is_expected.to eq('binary') }
+ end
+
+ context '#revision' do
+ subject { blob.revision }
+
+ it { is_expected.to eq('0123456789012345') }
+ end
+
+ context '#short_revision' do
+ subject { blob.short_revision }
+
+ it { is_expected.to eq('012345678') }
+ end
+
+ context '#delete' do
+ before do
+ stub_request(:delete, 'http://example.com/v2/group/test/blobs/sha256:0123456789012345').
+ to_return(status: 200)
+ end
+
+ subject { blob.delete }
+
+ it { is_expected.to be_truthy }
+ end
+end
diff --git a/spec/lib/container_registry/registry_spec.rb b/spec/lib/container_registry/registry_spec.rb
index f5f7c3c8bf2..2638401ae6e 100644
--- a/spec/lib/container_registry/registry_spec.rb
+++ b/spec/lib/container_registry/registry_spec.rb
@@ -10,7 +10,7 @@ describe ContainerRegistry::Registry do
it { is_expected.to respond_to(:uri) }
it { is_expected.to respond_to(:path) }
- it { expect(subject['test']).to_not be_nil }
+ it { expect(subject.repository('test')).to_not be_nil }
context '#path' do
subject { registry.path }
diff --git a/spec/lib/container_registry/repository_spec.rb b/spec/lib/container_registry/repository_spec.rb
new file mode 100644
index 00000000000..e6d66b11e4e
--- /dev/null
+++ b/spec/lib/container_registry/repository_spec.rb
@@ -0,0 +1,65 @@
+require 'spec_helper'
+
+describe ContainerRegistry::Repository do
+ let(:registry) { ContainerRegistry::Registry.new('http://example.com') }
+ let(:repository) { registry.repository('group/test') }
+
+ it { expect(repository).to respond_to(:registry) }
+ it { expect(repository).to delegate_method(:client).to(:registry) }
+ it { expect(repository.tag('test')).to_not be_nil }
+
+ context '#path' do
+ subject { repository.path }
+
+ it { is_expected.to eq('example.com/group/test') }
+ end
+
+ context 'manifest processing' do
+ before do
+ stub_request(:get, 'http://example.com/v2/group/test/tags/list').
+ with(headers: { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' }).
+ to_return(
+ status: 200,
+ body: JSON.dump(tags: ['test']),
+ headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' })
+ end
+
+ context '#manifest' do
+ subject { repository.manifest }
+
+ it { is_expected.to_not be_nil }
+ end
+
+ context '#valid?' do
+ subject { repository.valid? }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context '#tags' do
+ subject { repository.tags }
+
+ it { is_expected.to_not be_empty }
+ end
+ end
+
+ context '#delete_tags' do
+ let(:tag) { ContainerRegistry::Tag.new(repository, 'tag') }
+
+ before { expect(repository).to receive(:tags).twice.and_return([tag]) }
+
+ subject { repository.delete_tags }
+
+ context 'succeeds' do
+ before { expect(tag).to receive(:delete).and_return(true) }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context 'any fails' do
+ before { expect(tag).to receive(:delete).and_return(false) }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+end
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
new file mode 100644
index 00000000000..12cf91127ed
--- /dev/null
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -0,0 +1,89 @@
+require 'spec_helper'
+
+describe ContainerRegistry::Tag do
+ let(:registry) { ContainerRegistry::Registry.new('http://example.com') }
+ let(:repository) { registry.repository('group/test') }
+ let(:tag) { repository.tag('tag') }
+ let(:headers) { { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' } }
+
+ it { expect(tag).to respond_to(:repository) }
+ it { expect(tag).to delegate_method(:registry).to(:repository) }
+ it { expect(tag).to delegate_method(:client).to(:repository) }
+
+ context '#path' do
+ subject { tag.path }
+
+ it { is_expected.to eq('example.com/group/test:tag') }
+ end
+
+ context 'manifest processing' do
+ before do
+ stub_request(:get, 'http://example.com/v2/group/test/manifests/tag').
+ with(headers: headers).
+ to_return(
+ status: 200,
+ body: File.read(Rails.root + 'spec/fixtures/container_registry/tag_manifest.json'),
+ headers: { 'Content-Type' => 'application/vnd.docker.distribution.manifest.v2+json' })
+ end
+
+ context '#layers' do
+ subject { tag.layers }
+
+ it { expect(subject.length).to eq(1) }
+ end
+
+ context '#total_size' do
+ subject { tag.total_size }
+
+ it { is_expected.to eq(2319870) }
+ end
+
+ context 'config processing' do
+ before do
+ stub_request(:get, 'http://example.com/v2/group/test/blobs/sha256:d7a513a663c1a6dcdba9ed832ca53c02ac2af0c333322cd6ca92936d1d9917ac').
+ with(headers: { 'Accept' => 'application/octet-stream' }).
+ to_return(
+ status: 200,
+ body: File.read(Rails.root + 'spec/fixtures/container_registry/config_blob.json'))
+ end
+
+ context '#config' do
+ subject { tag.config }
+
+ it { is_expected.to_not be_nil }
+ end
+
+ context '#created_at' do
+ subject { tag.created_at }
+
+ it { is_expected.to_not be_nil }
+ end
+ end
+ end
+
+ context 'manifest digest' do
+ before do
+ stub_request(:head, 'http://example.com/v2/group/test/manifests/tag').
+ with(headers: headers).
+ to_return(status: 200, headers: { 'Docker-Content-Digest' => 'sha256:digest' })
+ end
+
+ context '#digest' do
+ subject { tag.digest }
+
+ it { is_expected.to eq('sha256:digest') }
+ end
+
+ context '#delete' do
+ before do
+ stub_request(:delete, 'http://example.com/v2/group/test/manifests/sha256:digest').
+ with(headers: headers).
+ to_return(status: 200)
+ end
+
+ subject { tag.delete }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+end