Commit e4fa80f3 authored by Andre Guedes's avatar Andre Guedes

Fixes broken and missing tests

parent 246df2bd
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
*/ */
.container-image { .container-image {
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid $white-normal;
} }
.container-image-head { .container-image-head {
padding: 0px 16px; padding: 0 16px;
line-height: 4; line-height: 4;
} }
.table.tags { .table.tags {
margin-bottom: 0px; margin-bottom: 0;
} }
...@@ -20,7 +20,6 @@ class Projects::ContainerRegistryController < Projects::ApplicationController ...@@ -20,7 +20,6 @@ class Projects::ContainerRegistryController < Projects::ApplicationController
redirect_to url, alert: 'Failed to remove image' redirect_to url, alert: 'Failed to remove image'
end end
end end
end end
private private
......
...@@ -22,7 +22,7 @@ class ContainerImage < ActiveRecord::Base ...@@ -22,7 +22,7 @@ class ContainerImage < ActiveRecord::Base
end end
def name_with_namespace def name_with_namespace
[container_registry_path_with_namespace, name].compact.join('/') [container_registry_path_with_namespace, name].reject(&:blank?).join('/')
end end
def tag(tag) def tag(tag)
...@@ -55,6 +55,8 @@ class ContainerImage < ActiveRecord::Base ...@@ -55,6 +55,8 @@ class ContainerImage < ActiveRecord::Base
end end
end end
# rubocop:disable RedundantReturn
def self.split_namespace(full_path) def self.split_namespace(full_path)
image_name = full_path.split('/').last image_name = full_path.split('/').last
namespace = full_path.gsub(/(.*)(#{Regexp.escape('/' + image_name)})/, '\1') namespace = full_path.gsub(/(.*)(#{Regexp.escape('/' + image_name)})/, '\1')
......
...@@ -118,8 +118,8 @@ class Namespace < ActiveRecord::Base ...@@ -118,8 +118,8 @@ class Namespace < ActiveRecord::Base
end end
def move_dir def move_dir
if any_project_has_container_registry_tags? if any_project_has_container_registry_images?
raise Gitlab::UpdatePathError.new('Namespace cannot be moved, because at least one project has tags in container registry') raise Gitlab::UpdatePathError.new('Namespace cannot be moved, because at least one project has images in container registry')
end end
# Move the namespace directory in all storages paths used by member projects # Move the namespace directory in all storages paths used by member projects
...@@ -154,8 +154,8 @@ class Namespace < ActiveRecord::Base ...@@ -154,8 +154,8 @@ class Namespace < ActiveRecord::Base
end end
end end
def any_project_has_container_registry_tags? def any_project_has_container_registry_images?
projects.any?(&:has_container_registry_tags?) projects.any? { |project| project.container_images.present? }
end end
def send_update_instructions def send_update_instructions
......
...@@ -421,18 +421,12 @@ class Project < ActiveRecord::Base ...@@ -421,18 +421,12 @@ class Project < ActiveRecord::Base
end end
end end
def container_registry_repository_url def container_registry_url
if Gitlab.config.registry.enabled if Gitlab.config.registry.enabled
"#{Gitlab.config.registry.host_port}/#{container_registry_path_with_namespace}" "#{Gitlab.config.registry.host_port}/#{container_registry_path_with_namespace}"
end end
end end
def has_container_registry_tags?
return unless container_images
container_images.first.tags.any?
end
def commit(ref = 'HEAD') def commit(ref = 'HEAD')
repository.commit(ref) repository.commit(ref)
end end
...@@ -913,11 +907,11 @@ class Project < ActiveRecord::Base ...@@ -913,11 +907,11 @@ class Project < ActiveRecord::Base
expire_caches_before_rename(old_path_with_namespace) expire_caches_before_rename(old_path_with_namespace)
if has_container_registry_tags? if container_images.present?
Rails.logger.error "Project #{old_path_with_namespace} cannot be renamed because container registry tags are present" Rails.logger.error "Project #{old_path_with_namespace} cannot be renamed because container registry images are present"
# we currently doesn't support renaming repository if it contains tags in container registry # we currently doesn't support renaming repository if it contains images in container registry
raise StandardError.new('Project cannot be renamed, because tags are present in its container registry') raise StandardError.new('Project cannot be renamed, because images are present in its container registry')
end end
if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace) if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace)
...@@ -1264,7 +1258,7 @@ class Project < ActiveRecord::Base ...@@ -1264,7 +1258,7 @@ class Project < ActiveRecord::Base
] ]
if container_registry_enabled? if container_registry_enabled?
variables << { key: 'CI_REGISTRY_IMAGE', value: container_registry_repository_url, public: true } variables << { key: 'CI_REGISTRY_IMAGE', value: container_registry_url, public: true }
end end
variables variables
......
...@@ -16,7 +16,8 @@ module Auth ...@@ -16,7 +16,8 @@ module Auth
{ token: authorized_token(scope).encoded } { token: authorized_token(scope).encoded }
end end
def self.full_access_token(names) def self.full_access_token(*names)
names = names.flatten
registry = Gitlab.config.registry registry = Gitlab.config.registry
token = JSONWebToken::RSAToken.new(registry.key) token = JSONWebToken::RSAToken.new(registry.key)
token.issuer = registry.issuer token.issuer = registry.issuer
......
module ContainerImages module ContainerImages
class DestroyService < BaseService class DestroyService < BaseService
class DestroyError < StandardError; end class DestroyError < StandardError; end
def execute(container_image) def execute(container_image)
......
...@@ -36,9 +36,9 @@ module Projects ...@@ -36,9 +36,9 @@ module Projects
raise TransferError.new("Project with same path in target namespace already exists") raise TransferError.new("Project with same path in target namespace already exists")
end end
if project.has_container_registry_tags? unless project.container_images.empty?
# we currently doesn't support renaming repository if it contains tags in container registry # we currently doesn't support renaming repository if it contains images in container registry
raise TransferError.new('Project cannot be transferred, because tags are present in its container registry') raise TransferError.new('Project cannot be transferred, because images are present in its container registry')
end end
project.expire_caches_before_rename(old_path) project.expire_caches_before_rename(old_path)
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= escape_once(image.name) = escape_once(image.name)
= clipboard_button(clipboard_text: "docker pull #{image.path}") = clipboard_button(clipboard_text: "docker pull #{image.path}")
.controls.hidden-xs.pull-right .controls.hidden-xs.pull-right
= link_to namespace_project_container_registry_path(@project.namespace, @project, image.id), class: 'btn btn-remove has-tooltip', title: "Remove", data: { confirm: "Are you sure?" }, method: :delete do = link_to namespace_project_container_registry_path(@project.namespace, @project, image.id), class: 'btn btn-remove has-tooltip', title: "Remove image", data: { confirm: "Are you sure?" }, method: :delete do
= icon("trash cred") = icon("trash cred")
......
...@@ -25,5 +25,5 @@ ...@@ -25,5 +25,5 @@
- if can?(current_user, :update_container_image, @project) - if can?(current_user, :update_container_image, @project)
%td.content %td.content
.controls.hidden-xs.pull-right .controls.hidden-xs.pull-right
= link_to namespace_project_container_registry_path(@project.namespace, @project, { id: tag.repository.id, tag: tag.name} ), class: 'btn btn-remove has-tooltip', title: "Remove", data: { confirm: "Are you sure?" }, method: :delete do = link_to namespace_project_container_registry_path(@project.namespace, @project, { id: tag.repository.id, tag: tag.name} ), class: 'btn btn-remove has-tooltip', title: "Remove tag", data: { confirm: "Are you sure?" }, method: :delete do
= icon("trash cred") = icon("trash cred")
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
%br %br
Then you are free to create and upload a container image with build and push commands: Then you are free to create and upload a container image with build and push commands:
%pre %pre
docker build -t #{escape_once(@project.container_registry_repository_url)} . docker build -t #{escape_once(@project.container_registry_url)} .
%br %br
docker push #{escape_once(@project.container_registry_repository_url)} docker push #{escape_once(@project.container_registry_url)}
- if @images.blank? - if @images.blank?
.nothing-here-block No container images in Container Registry for this project. .nothing-here-block No container images in Container Registry for this project.
......
...@@ -109,6 +109,7 @@ ActiveRecord::Schema.define(version: 20170215200045) do ...@@ -109,6 +109,7 @@ ActiveRecord::Schema.define(version: 20170215200045) do
t.boolean "html_emails_enabled", default: true t.boolean "html_emails_enabled", default: true
t.string "plantuml_url" t.string "plantuml_url"
t.boolean "plantuml_enabled" t.boolean "plantuml_enabled"
t.string "container_registry_access_token"
t.integer "max_pages_size", default: 100, null: false t.integer "max_pages_size", default: 100, null: false
t.integer "terminal_max_session_time", default: 0, null: false t.integer "terminal_max_session_time", default: 0, null: false
end end
...@@ -392,6 +393,11 @@ ActiveRecord::Schema.define(version: 20170215200045) do ...@@ -392,6 +393,11 @@ ActiveRecord::Schema.define(version: 20170215200045) do
add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree
create_table "container_images", force: :cascade do |t|
t.integer "project_id"
t.string "name"
end
create_table "deploy_keys_projects", force: :cascade do |t| create_table "deploy_keys_projects", force: :cascade do |t|
t.integer "deploy_key_id", null: false t.integer "deploy_key_id", null: false
t.integer "project_id", null: false t.integer "project_id", null: false
......
...@@ -46,9 +46,7 @@ module API ...@@ -46,9 +46,7 @@ module API
if project if project
container_image = project.container_images.find_or_create_by(name: container_image_name) container_image = project.container_images.find_or_create_by(name: container_image_name)
if container_image.valid? unless container_image.valid?
puts('Valid!')
else
render_api_error!({ error: "Failed to create container image!" }, 400) render_api_error!({ error: "Failed to create container image!" }, 400)
end end
else else
......
...@@ -38,11 +38,11 @@ module ContainerRegistry ...@@ -38,11 +38,11 @@ module ContainerRegistry
end end
def delete def delete
client.delete_blob(repository.name, digest) client.delete_blob(repository.name_with_namespace, digest)
end end
def data def data
@data ||= client.blob(repository.name, digest, type) @data ||= client.blob(repository.name_with_namespace, digest, type)
end end
end end
end end
...@@ -8,10 +8,6 @@ module ContainerRegistry ...@@ -8,10 +8,6 @@ module ContainerRegistry
@client = ContainerRegistry::Client.new(uri, options) @client = ContainerRegistry::Client.new(uri, options)
end end
def repository(name)
ContainerRegistry::Repository.new(self, name)
end
private private
def default_path def default_path
......
module ContainerRegistry
class Repository
attr_reader :registry, :name
delegate :client, to: :registry
def initialize(registry, name)
@registry, @name = registry, name
end
def path
[registry.path, name].compact.join('/')
end
def tag(tag)
ContainerRegistry::Tag.new(self, tag)
end
def manifest
return @manifest if defined?(@manifest)
@manifest = client.repository_tags(name)
end
def valid?
manifest.present?
end
def tags
return @tags if defined?(@tags)
return [] unless manifest && manifest['tags']
@tags = manifest['tags'].map do |tag|
ContainerRegistry::Tag.new(self, tag)
end
end
def blob(config)
ContainerRegistry::Blob.new(self, config)
end
def delete_tags
return unless tags
tags.all?(&:delete)
end
end
end
FactoryGirl.define do
factory :container_image do
name "test_container_image"
project
transient do
tags ['tag']
stubbed true
end
after(:build) do |image, evaluator|
if evaluator.stubbed
allow(Gitlab.config.registry).to receive(:enabled).and_return(true)
allow(image.client).to receive(:repository_tags).and_return({
name: image.name_with_namespace,
tags: evaluator.tags
})
end
end
end
end
...@@ -2,15 +2,18 @@ require 'spec_helper' ...@@ -2,15 +2,18 @@ require 'spec_helper'
describe "Container Registry" do describe "Container Registry" do
let(:project) { create(:empty_project) } let(:project) { create(:empty_project) }
let(:repository) { project.container_registry_repository } let(:registry) { project.container_registry }
let(:tag_name) { 'latest' } let(:tag_name) { 'latest' }
let(:tags) { [tag_name] } let(:tags) { [tag_name] }
let(:container_image) { create(:container_image) }
let(:image_name) { container_image.name }
before do before do
login_as(:user) login_as(:user)
project.team << [@user, :developer] project.team << [@user, :developer]
stub_container_registry_tags(*tags)
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags(*tags)
project.container_images << container_image unless container_image.nil?
allow(Auth::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token') allow(Auth::ContainerRegistryAuthenticationService).to receive(:full_access_token).and_return('token')
end end
...@@ -19,15 +22,26 @@ describe "Container Registry" do ...@@ -19,15 +22,26 @@ describe "Container Registry" do
visit namespace_project_container_registry_index_path(project.namespace, project) visit namespace_project_container_registry_index_path(project.namespace, project)
end end
context 'when no tags' do context 'when no images' do
let(:tags) { [] } let(:container_image) { }
it { expect(page).to have_content('No container images in Container Registry for this project') }
end
it { expect(page).to have_content('No images in Container Registry for this project') } context 'when there are images' do
it { expect(page).to have_content(image_name) }
end
end end
context 'when there are tags' do describe 'DELETE /:project/container_registry/:image_id' do
it { expect(page).to have_content(tag_name) } before do
it { expect(page).to have_content('d7a513a66') } visit namespace_project_container_registry_index_path(project.namespace, project)
end
it do
expect_any_instance_of(ContainerImage).to receive(:delete_tags).and_return(true)
click_on 'Remove image'
end end
end end
...@@ -39,7 +53,7 @@ describe "Container Registry" do ...@@ -39,7 +53,7 @@ describe "Container Registry" do
it do it do
expect_any_instance_of(::ContainerRegistry::Tag).to receive(:delete).and_return(true) expect_any_instance_of(::ContainerRegistry::Tag).to receive(:delete).and_return(true)
click_on 'Remove' click_on 'Remove tag'
end end
end end
end end
...@@ -429,9 +429,12 @@ describe "Internal Project Access", feature: true do ...@@ -429,9 +429,12 @@ describe "Internal Project Access", feature: true do
end end
describe "GET /:project_path/container_registry" do describe "GET /:project_path/container_registry" do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_tags('latest') stub_container_registry_tags('latest')
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
project.container_images << container_image
end end
subject { namespace_project_container_registry_index_path(project.namespace, project) } subject { namespace_project_container_registry_index_path(project.namespace, project) }
......
...@@ -418,9 +418,12 @@ describe "Private Project Access", feature: true do ...@@ -418,9 +418,12 @@ describe "Private Project Access", feature: true do
end end
describe "GET /:project_path/container_registry" do describe "GET /:project_path/container_registry" do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_tags('latest') stub_container_registry_tags('latest')
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
project.container_images << container_image
end end
subject { namespace_project_container_registry_index_path(project.namespace, project) } subject { namespace_project_container_registry_index_path(project.namespace, project) }
......
...@@ -429,9 +429,12 @@ describe "Public Project Access", feature: true do ...@@ -429,9 +429,12 @@ describe "Public Project Access", feature: true do
end end
describe "GET /:project_path/container_registry" do describe "GET /:project_path/container_registry" do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_tags('latest') stub_container_registry_tags('latest')
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
project.container_images << container_image
end end
subject { namespace_project_container_registry_index_path(project.namespace, project) } subject { namespace_project_container_registry_index_path(project.namespace, project) }
......
...@@ -9,12 +9,19 @@ describe ContainerRegistry::Blob do ...@@ -9,12 +9,19 @@ describe ContainerRegistry::Blob do
'size' => 1000 'size' => 1000
} }
end end
let(:token) { 'authorization-token' } let(:token) { 'token' }
let(:registry) { ContainerRegistry::Registry.new('http://example.com', token: token) } let(:group) { create(:group, name: 'group') }
let(:repository) { registry.repository('group/test') } let(:project) { create(:project, path: 'test', group: group) }
let(:example_host) { 'example.com' }
let(:registry_url) { 'http://' + example_host }
let(:repository) { create(:container_image, name: '', project: project) }
let(:blob) { repository.blob(config) } let(:blob) { repository.blob(config) }
before do
stub_container_registry_config(enabled: true, api_url: registry_url, host_port: example_host)
end
it { expect(blob).to respond_to(:repository) } it { expect(blob).to respond_to(:repository) }
it { expect(blob).to delegate_method(:registry).to(:repository) } it { expect(blob).to delegate_method(:registry).to(:repository) }
it { expect(blob).to delegate_method(:client).to(:repository) } it { expect(blob).to delegate_method(:client).to(:repository) }
......
...@@ -10,7 +10,7 @@ describe ContainerRegistry::Registry do ...@@ -10,7 +10,7 @@ describe ContainerRegistry::Registry do
it { is_expected.to respond_to(:uri) } it { is_expected.to respond_to(:uri) }
it { is_expected.to respond_to(:path) } it { is_expected.to respond_to(:path) }
it { expect(subject.repository('test')).not_to be_nil } it { expect(subject).not_to be_nil }
context '#path' do context '#path' do
subject { registry.path } subject { registry.path }
......
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')).not_to 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/json' })
end
context '#manifest' do
subject { repository.manifest }
it { is_expected.not_to 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.not_to 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
require 'spec_helper' require 'spec_helper'
describe ContainerRegistry::Tag do describe ContainerRegistry::Tag do
let(:registry) { ContainerRegistry::Registry.new('http://example.com') } let(:group) { create(:group, name: 'group') }
let(:repository) { registry.repository('group/test') } let(:project) { create(:project, path: 'test', group: group) }
let(:example_host) { 'example.com' }
let(:registry_url) { 'http://' + example_host }
let(:repository) { create(:container_image, name: '', project: project) }
let(:tag) { repository.tag('tag') } let(:tag) { repository.tag('tag') }
let(:headers) { { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' } } let(:headers) { { 'Accept' => 'application/vnd.docker.distribution.manifest.v2+json' } }
before do
stub_container_registry_config(enabled: true, api_url: registry_url, host_port: example_host)
end
it { expect(tag).to respond_to(:repository) } it { expect(tag).to respond_to(:repository) }
it { expect(tag).to delegate_method(:registry).to(:repository) } it { expect(tag).to delegate_method(:registry).to(:repository) }
it { expect(tag).to delegate_method(:client).to(:repository) } it { expect(tag).to delegate_method(:client).to(:repository) }
......
...@@ -114,6 +114,8 @@ merge_access_levels: ...@@ -114,6 +114,8 @@ merge_access_levels:
- protected_branch - protected_branch
push_access_levels: push_access_levels:
- protected_branch - protected_branch
container_images:
- name
project: project:
- taggings - taggings
- base_tags - base_tags
...@@ -197,6 +199,7 @@ project: ...@@ -197,6 +199,7 @@ project:
- project_authorizations - project_authorizations
- route - route
- statistics - statistics
- container_images
award_emoji: award_emoji:
- awardable - awardable
- user - user
......
...@@ -1397,7 +1397,7 @@ describe Ci::Build, :models do ...@@ -1397,7 +1397,7 @@ describe Ci::Build, :models do
{ key: 'CI_REGISTRY', value: 'registry.example.com', public: true } { key: 'CI_REGISTRY', value: 'registry.example.com', public: true }
end end
let(:ci_registry_image) do let(:ci_registry_image) do
{ key: 'CI_REGISTRY_IMAGE', value: project.container_registry_repository_url, public: true } { key: 'CI_REGISTRY_IMAGE', value: project.container_registry_url, public: true }
end end
context 'and is disabled for project' do context 'and is disabled for project' do
......
require 'spec_helper'
describe ContainerImage do
let(:group) { create(:group, name: 'group') }
let(:project) { create(:project, path: 'test', group: group) }
let(:example_host) { 'example.com' }
let(:registry_url) { 'http://' + example_host }
let(:container_image) { create(:container_image, name: '', project: project, stubbed: false) }
before do
stub_container_registry_config(enabled: true, api_url: registry_url, host_port: example_host)
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/json' })
end
it { expect(container_image).to respond_to(:project) }
it { expect(container_image).to delegate_method(:container_registry).to(:project) }
it { expect(container_image).to delegate_method(:client).to(:container_registry) }
it { expect(container_image.tag('test')).not_to be_nil }
context '#path' do
subject { container_image.path }
it { is_expected.to eq('example.com/group/test') }
end
context 'manifest processing' do
context '#manifest' do
subject { container_image.manifest }
it { is_expected.not_to be_nil }
end
context '#valid?' do
subject { container_image.valid? }
it { is_expected.to be_truthy }
end
context '#tags' do
subject { container_image.tags }
it { is_expected.not_to be_empty }
end
end
context '#delete_tags' do
let(:tag) { ContainerRegistry::Tag.new(container_image, 'tag') }
before do
expect(container_image).to receive(:tags).twice.and_return([tag])
expect(tag).to receive(:digest).and_return('sha256:4c8e63ca4cb663ce6c688cb06f1c3672a172b088dac5b6d7ad7d49cd620d85cf')
end
subject { container_image.delete_tags }
context 'succeeds' do
before { expect(container_image.client).to receive(:delete_repository_tag).and_return(true) }
it { is_expected.to be_truthy }
end
context 'any fails' do
before { expect(container_image.client).to receive(:delete_repository_tag).and_return(false) }
it { is_expected.to be_falsey }
end
end
end
...@@ -134,18 +134,20 @@ describe Namespace, models: true do ...@@ -134,18 +134,20 @@ describe Namespace, models: true do
expect(@namespace.move_dir).to be_truthy expect(@namespace.move_dir).to be_truthy
end end
context "when any project has container tags" do context "when any project has container images" do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags('tag') stub_container_registry_tags('tag')
create(:empty_project, namespace: @namespace) create(:empty_project, namespace: @namespace, container_images: [container_image])
allow(@namespace).to receive(:path_was).and_return(@namespace.path) allow(@namespace).to receive(:path_was).and_return(@namespace.path)
allow(@namespace).to receive(:path).and_return('new_path') allow(@namespace).to receive(:path).and_return('new_path')
end end
it { expect { @namespace.move_dir }.to raise_error('Namespace cannot be moved, because at least one project has tags in container registry') } it { expect { @namespace.move_dir }.to raise_error('Namespace cannot be moved, because at least one project has images in container registry') }
end end
end end
......
...@@ -1173,10 +1173,13 @@ describe Project, models: true do ...@@ -1173,10 +1173,13 @@ describe Project, models: true do
project.rename_repo project.rename_repo
end end
context 'container registry with tags' do context 'container registry with images' do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags('tag') stub_container_registry_tags('tag')
project.container_images << container_image
end end
subject { project.rename_repo } subject { project.rename_repo }
...@@ -1383,20 +1386,20 @@ describe Project, models: true do ...@@ -1383,20 +1386,20 @@ describe Project, models: true do
it { is_expected.to eq(project.path_with_namespace.downcase) } it { is_expected.to eq(project.path_with_namespace.downcase) }
end end
describe '#container_registry_repository' do describe '#container_registry' do
let(:project) { create(:empty_project) } let(:project) { create(:empty_project) }
before { stub_container_registry_config(enabled: true) } before { stub_container_registry_config(enabled: true) }
subject { project.container_registry_repository } subject { project.container_registry }
it { is_expected.not_to be_nil } it { is_expected.not_to be_nil }
end end
describe '#container_registry_repository_url' do describe '#container_registry_url' do
let(:project) { create(:empty_project) } let(:project) { create(:empty_project) }
subject { project.container_registry_repository_url } subject { project.container_registry_url }
before { stub_container_registry_config(**registry_settings) } before { stub_container_registry_config(**registry_settings) }
...@@ -1422,34 +1425,6 @@ describe Project, models: true do ...@@ -1422,34 +1425,6 @@ describe Project, models: true do
end end
end end
describe '#has_container_registry_tags?' do
let(:project) { create(:empty_project) }
subject { project.has_container_registry_tags? }
context 'for enabled registry' do
before { stub_container_registry_config(enabled: true) }
context 'with tags' do
before { stub_container_registry_tags('test', 'test2') }
it { is_expected.to be_truthy }
end
context 'when no tags' do
before { stub_container_registry_tags }
it { is_expected.to be_falsey }
end
end
context 'for disabled registry' do
before { stub_container_registry_config(enabled: false) }
it { is_expected.to be_falsey }
end
end
describe '#latest_successful_builds_for' do describe '#latest_successful_builds_for' do
def create_pipeline(status = 'success') def create_pipeline(status = 'success')
create(:ci_pipeline, project: project, create(:ci_pipeline, project: project,
......
...@@ -90,25 +90,30 @@ describe Projects::DestroyService, services: true do ...@@ -90,25 +90,30 @@ describe Projects::DestroyService, services: true do
end end
context 'container registry' do context 'container registry' do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags('tag') stub_container_registry_tags('tag')
project.container_images << container_image
end end
context 'tags deletion succeeds' do context 'images deletion succeeds' do
it do it do
expect_any_instance_of(ContainerRegistry::Tag).to receive(:delete).and_return(true) expect_any_instance_of(ContainerImage).to receive(:delete_tags).and_return(true)
destroy_project(project, user, {}) destroy_project(project, user, {})
end end
end end
context 'tags deletion fails' do context 'images deletion fails' do
before { expect_any_instance_of(ContainerRegistry::Tag).to receive(:delete).and_return(false) } before do
expect_any_instance_of(ContainerImage).to receive(:delete_tags).and_return(false)
end
subject { destroy_project(project, user, {}) } subject { destroy_project(project, user, {}) }
it { expect{subject}.to raise_error(Projects::DestroyService::DestroyError) } it { expect{subject}.to raise_error(ActiveRecord::RecordNotDestroyed) }
end end
end end
......
...@@ -29,9 +29,12 @@ describe Projects::TransferService, services: true do ...@@ -29,9 +29,12 @@ describe Projects::TransferService, services: true do
end end
context 'disallow transfering of project with tags' do context 'disallow transfering of project with tags' do
let(:container_image) { create(:container_image) }
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags('tag') stub_container_registry_tags('tag')
project.container_images << container_image
end end
subject { transfer_project(project, user, group) } subject { transfer_project(project, user, group) }
......
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