diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-17 13:20:11 -0500 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-05-17 13:20:11 -0500 |
commit | 24145592e804ffbe58a38b15095808919337d545 (patch) | |
tree | a3d4108b84bfab9f7813b982ce53fdd45d5306f4 | |
parent | a82109eee80bf703ad8e82de2410f490e5fc6d54 (diff) | |
download | gitlab-ce-24145592e804ffbe58a38b15095808919337d545.tar.gz |
Provide full test coverage to lib/container_registry API implementation
-rw-r--r-- | app/controllers/projects/container_registry_controller.rb | 2 | ||||
-rw-r--r-- | app/models/project.rb | 2 | ||||
-rw-r--r-- | lib/container_registry/blob.rb | 10 | ||||
-rw-r--r-- | lib/container_registry/client.rb | 8 | ||||
-rw-r--r-- | lib/container_registry/registry.rb | 2 | ||||
-rw-r--r-- | lib/container_registry/repository.rb | 28 | ||||
-rw-r--r-- | lib/container_registry/tag.rb | 20 | ||||
-rw-r--r-- | spec/lib/container_registry/blob_spec.rb | 61 | ||||
-rw-r--r-- | spec/lib/container_registry/registry_spec.rb | 2 | ||||
-rw-r--r-- | spec/lib/container_registry/repository_spec.rb | 65 | ||||
-rw-r--r-- | spec/lib/container_registry/tag_spec.rb | 89 |
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 |