summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-19 11:50:12 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-19 11:50:12 +0000
commit6cd5b7dbfaa4ff630ecbbfe351a1faac5fc71a8d (patch)
treed3563b9f60936c18a02185e2e53b424bb1b83539 /spec
parentb3e0658cb1fbc7c8e7dd381467c656f2e675ee46 (diff)
downloadgitlab-ce-6cd5b7dbfaa4ff630ecbbfe351a1faac5fc71a8d.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb20
-rw-r--r--spec/features/container_registry_spec.rb4
-rw-r--r--spec/features/issues_spec.rb3
-rw-r--r--spec/frontend/helpers/vue_resource_helper.js11
-rw-r--r--spec/javascripts/helpers/vue_resource_helper.js11
-rw-r--r--spec/javascripts/test_bundle.js9
-rw-r--r--spec/lib/container_registry/client_spec.rb65
-rw-r--r--spec/lib/container_registry/tag_spec.rb4
-rw-r--r--spec/requests/api/project_container_repositories_spec.rb36
-rw-r--r--spec/services/projects/container_repository/delete_tags_service_spec.rb120
-rw-r--r--spec/support/helpers/wait_for_requests.rb6
11 files changed, 234 insertions, 55 deletions
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index c6e063d8229..8da0d217e9e 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -10,6 +10,8 @@ describe Projects::Registry::TagsController do
create(:container_repository, name: 'image', project: project)
end
+ let(:service) { double('service') }
+
before do
sign_in(user)
stub_container_registry_config(enabled: true)
@@ -84,17 +86,17 @@ describe Projects::Registry::TagsController do
context 'when there is matching tag present' do
before do
- stub_container_registry_tags(repository: repository.path, tags: %w[rc1 test.])
+ stub_container_registry_tags(repository: repository.path, tags: %w[rc1], with_manifest: true)
end
it 'makes it possible to delete regular tag' do
- expect_any_instance_of(ContainerRegistry::Tag).to receive(:delete)
+ expect_delete_tags(%w[rc1])
destroy_tag('rc1')
end
it 'makes it possible to delete a tag that ends with a dot' do
- expect_any_instance_of(ContainerRegistry::Tag).to receive(:delete)
+ expect_delete_tags(%w[test.])
destroy_tag('test.')
end
@@ -125,11 +127,12 @@ describe Projects::Registry::TagsController do
stub_container_registry_tags(repository: repository.path, tags: %w[rc1 test.])
end
+ let(:tags) { %w[tc1 test.] }
+
it 'makes it possible to delete tags in bulk' do
- allow_any_instance_of(ContainerRegistry::Tag).to receive(:delete) { |*args| ContainerRegistry::Tag.delete(*args) }
- expect(ContainerRegistry::Tag).to receive(:delete).exactly(2).times
+ expect_delete_tags(tags)
- bulk_destroy_tags(['rc1', 'test.'])
+ bulk_destroy_tags(tags)
end
end
end
@@ -146,4 +149,9 @@ describe Projects::Registry::TagsController do
format: :json
end
end
+
+ def expect_delete_tags(tags, status = :success)
+ expect(service).to receive(:execute).with(repository) { { status: status } }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(repository.project, user, tags: tags) { service }
+ end
end
diff --git a/spec/features/container_registry_spec.rb b/spec/features/container_registry_spec.rb
index aefdc4d6d4f..dfd08483430 100644
--- a/spec/features/container_registry_spec.rb
+++ b/spec/features/container_registry_spec.rb
@@ -53,7 +53,9 @@ describe 'Container Registry', :js do
find('.js-toggle-repo').click
wait_for_requests
- expect_any_instance_of(ContainerRegistry::Tag).to receive(:delete).and_return(true)
+ service = double('service')
+ expect(service).to receive(:execute).with(container_repository) { { status: :success } }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['latest']) { service }
click_on(class: 'js-delete-registry-row', visible: false)
expect(find('.modal .modal-title')).to have_content 'Remove image'
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index 5bdd9113b06..f9e83af352d 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -470,9 +470,6 @@ describe 'Issues' do
expect(page).to have_content 'None'
end
- # wait_for_requests does not work with vue-resource at the moment
- sleep 1
-
expect(issue.reload.assignees).to be_empty
end
diff --git a/spec/frontend/helpers/vue_resource_helper.js b/spec/frontend/helpers/vue_resource_helper.js
deleted file mode 100644
index 0f58af09933..00000000000
--- a/spec/frontend/helpers/vue_resource_helper.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// eslint-disable-next-line import/prefer-default-export
-export const headersInterceptor = (request, next) => {
- next(response => {
- const headers = {};
- response.headers.forEach((value, key) => {
- headers[key] = value;
- });
- // eslint-disable-next-line no-param-reassign
- response.headers = headers;
- });
-};
diff --git a/spec/javascripts/helpers/vue_resource_helper.js b/spec/javascripts/helpers/vue_resource_helper.js
deleted file mode 100644
index 0f58af09933..00000000000
--- a/spec/javascripts/helpers/vue_resource_helper.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// eslint-disable-next-line import/prefer-default-export
-export const headersInterceptor = (request, next) => {
- next(response => {
- const headers = {};
- response.headers.forEach((value, key) => {
- headers[key] = value;
- });
- // eslint-disable-next-line no-param-reassign
- response.headers = headers;
- });
-};
diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js
index c0a999cfaa6..191df3cc709 100644
--- a/spec/javascripts/test_bundle.js
+++ b/spec/javascripts/test_bundle.js
@@ -7,7 +7,6 @@ import 'core-js/features/set-immediate';
import 'vendor/jasmine-jquery';
import '~/commons';
import Vue from 'vue';
-import VueResource from 'vue-resource';
import Translate from '~/vue_shared/translate';
import jasmineDiff from 'jasmine-diff';
import { config as testUtilsConfig } from '@vue/test-utils';
@@ -46,7 +45,6 @@ Vue.config.errorHandler = function(err) {
fail(err);
};
-Vue.use(VueResource);
Vue.use(Translate);
// enable test fixtures
@@ -102,13 +100,6 @@ afterEach(__rewire_reset_all__); // eslint-disable-line
// to run our unit tests.
beforeEach(done => done());
-const builtinVueHttpInterceptors = Vue.http.interceptors.slice();
-
-beforeEach(() => {
- // restore interceptors so we have no remaining ones from previous tests
- Vue.http.interceptors = builtinVueHttpInterceptors.slice();
-});
-
let longRunningTestTimeoutHandle;
beforeEach(done => {
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index 6c2b338bfcd..3782c30e88a 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -73,4 +73,69 @@ describe ContainerRegistry::Client do
expect(response).to eq('Successfully redirected')
end
end
+
+ def stub_upload(path, content, digest, status = 200)
+ stub_request(:post, "http://container-registry/v2/#{path}/blobs/uploads/")
+ .to_return(status: status, body: "", headers: { 'location' => 'http://container-registry/next_upload?id=someid' })
+
+ stub_request(:put, "http://container-registry/next_upload?digest=#{digest}&id=someid")
+ .with(body: content)
+ .to_return(status: status, body: "", headers: {})
+ end
+
+ describe '#upload_blob' do
+ subject { client.upload_blob('path', 'content', 'sha256:123') }
+
+ context 'with successful uploads' do
+ it 'starts the upload and posts the blob' do
+ stub_upload('path', 'content', 'sha256:123')
+
+ expect(subject).to be_success
+ end
+ end
+
+ context 'with a failed upload' do
+ before do
+ stub_upload('path', 'content', 'sha256:123', 400)
+ end
+
+ it 'returns nil' do
+ expect(subject).to be nil
+ end
+ end
+ end
+
+ describe '#generate_empty_manifest' do
+ subject { client.generate_empty_manifest('path') }
+
+ let(:result_manifest) do
+ {
+ schemaVersion: 2,
+ mediaType: 'application/vnd.docker.distribution.manifest.v2+json',
+ config: {
+ mediaType: 'application/vnd.docker.container.image.v1+json',
+ size: 21,
+ digest: 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3'
+ }
+ }
+ end
+
+ it 'uploads a random image and returns the manifest' do
+ stub_upload('path', "{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+
+ expect(subject).to eq(result_manifest)
+ end
+ end
+
+ describe '#put_tag' do
+ subject { client.put_tag('path', 'tagA', { foo: :bar }) }
+
+ it 'uploads the manifest and returns the digest' do
+ stub_request(:put, "http://container-registry/v2/path/manifests/tagA")
+ .with(body: "{\n \"foo\": \"bar\"\n}")
+ .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:123' })
+
+ expect(subject).to eq 'sha256:123'
+ end
+ end
end
diff --git a/spec/lib/container_registry/tag_spec.rb b/spec/lib/container_registry/tag_spec.rb
index 110f006536b..3115dfe852f 100644
--- a/spec/lib/container_registry/tag_spec.rb
+++ b/spec/lib/container_registry/tag_spec.rb
@@ -179,7 +179,7 @@ describe ContainerRegistry::Tag do
end
end
- describe '#delete' do
+ describe '#unsafe_delete' do
before do
stub_request(:delete, 'http://registry.gitlab/v2/group/test/manifests/sha256:digest')
.with(headers: headers)
@@ -187,7 +187,7 @@ describe ContainerRegistry::Tag do
end
it 'correctly deletes the tag' do
- expect(tag.delete).to be_truthy
+ expect(tag.unsafe_delete).to be_truthy
end
end
end
diff --git a/spec/requests/api/project_container_repositories_spec.rb b/spec/requests/api/project_container_repositories_spec.rb
index f1dc4e6f0b2..3ac7ff7656b 100644
--- a/spec/requests/api/project_container_repositories_spec.rb
+++ b/spec/requests/api/project_container_repositories_spec.rb
@@ -150,7 +150,7 @@ describe API::ProjectContainerRepositories do
expect(response).to have_gitlab_http_status(:accepted)
end
- context 'called multiple times in one hour' do
+ context 'called multiple times in one hour', :clean_gitlab_redis_shared_state do
it 'returns 400 with an error message' do
stub_exclusive_lease_taken(lease_key, timeout: 1.hour)
subject
@@ -202,6 +202,8 @@ describe API::ProjectContainerRepositories do
end
describe 'DELETE /projects/:id/registry/repositories/:repository_id/tags/:tag_name' do
+ let(:service) { double('service') }
+
subject { delete api("/projects/#{project.id}/registry/repositories/#{root_repository.id}/tags/rootA", api_user) }
it_behaves_like 'rejected container repository access', :reporter, :forbidden
@@ -210,18 +212,34 @@ describe API::ProjectContainerRepositories do
context 'for developer' do
let(:api_user) { developer }
- before do
- stub_container_registry_tags(repository: root_repository.path, tags: %w(rootA), with_manifest: true)
+ context 'when there are multiple tags' do
+ before do
+ stub_container_registry_tags(repository: root_repository.path, tags: %w(rootA rootB), with_manifest: true)
+ end
+
+ it 'properly removes tag' do
+ expect(service).to receive(:execute).with(root_repository) { { status: :success } }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(root_repository.project, api_user, tags: %w[rootA]) { service }
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
- it 'properly removes tag' do
- expect_any_instance_of(ContainerRegistry::Client)
- .to receive(:delete_repository_tag).with(root_repository.path,
- 'sha256:4c8e63ca4cb663ce6c688cb06f1c372b088dac5b6d7ad7d49cd620d85cf72a15')
+ context 'when there\'s only one tag' do
+ before do
+ stub_container_registry_tags(repository: root_repository.path, tags: %w(rootA), with_manifest: true)
+ end
- subject
+ it 'properly removes tag' do
+ expect(service).to receive(:execute).with(root_repository) { { status: :success } }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(root_repository.project, api_user, tags: %w[rootA]) { service }
- expect(response).to have_gitlab_http_status(:ok)
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
end
end
diff --git a/spec/services/projects/container_repository/delete_tags_service_spec.rb b/spec/services/projects/container_repository/delete_tags_service_spec.rb
new file mode 100644
index 00000000000..2ec5850c69e
--- /dev/null
+++ b/spec/services/projects/container_repository/delete_tags_service_spec.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Projects::ContainerRepository::DeleteTagsService do
+ set(:user) { create(:user) }
+ set(:project) { create(:project, :private) }
+ set(:repository) { create(:container_repository, :root, project: project) }
+
+ let(:params) { { tags: tags } }
+ let(:service) { described_class.new(project, user, params) }
+
+ before do
+ stub_container_registry_config(enabled: true,
+ api_url: 'http://registry.gitlab',
+ host_port: 'registry.gitlab')
+
+ stub_container_registry_tags(
+ repository: repository.path,
+ tags: %w(latest A Ba Bb C D E))
+
+ stub_tag_digest('latest', 'sha256:configA')
+ stub_tag_digest('A', 'sha256:configA')
+ stub_tag_digest('Ba', 'sha256:configB')
+ end
+
+ describe '#execute' do
+ let(:tags) { %w[A] }
+ subject { service.execute(repository) }
+
+ context 'without permissions' do
+ it { is_expected.to include(status: :error) }
+ end
+
+ context 'with permissions' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when no params are specified' do
+ let(:params) { {} }
+
+ it 'does not remove anything' do
+ expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag)
+
+ is_expected.to include(status: :error)
+ end
+ end
+
+ context 'with empty tags' do
+ let(:tags) { [] }
+
+ it 'does not remove anything' do
+ expect_any_instance_of(ContainerRegistry::Client).not_to receive(:delete_repository_tag)
+
+ is_expected.to include(status: :error)
+ end
+ end
+
+ context 'with dummy tags disabled' do
+ let(:tags) { %w[A Ba] }
+
+ before do
+ stub_feature_flags(container_registry_smart_delete: false)
+ end
+
+ it 'deletes tags one by one' do
+ expect_delete_tag('sha256:configA')
+ expect_delete_tag('sha256:configB')
+ is_expected.to include(status: :success)
+ end
+ end
+
+ context 'with dummy tags enabled' do
+ let(:tags) { %w[A Ba] }
+
+ it 'deletes the tags using a dummy image' do
+ stub_upload("{\n \"config\": {\n }\n}", 'sha256:4435000728ee66e6a80e55637fc22725c256b61de344a2ecdeaac6bdb36e8bc3')
+
+ stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/A")
+ .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
+
+ stub_request(:put, "http://registry.gitlab/v2/#{repository.path}/manifests/Ba")
+ .to_return(status: 200, body: "", headers: { 'docker-content-digest' => 'sha256:dummy' })
+
+ expect_delete_tag('sha256:dummy')
+
+ is_expected.to include(status: :success)
+ end
+ end
+ end
+ end
+
+ private
+
+ def stub_tag_digest(tag, digest)
+ stub_request(:head, "http://registry.gitlab/v2/#{repository.path}/manifests/#{tag}")
+ .to_return(status: 200, body: "", headers: { 'docker-content-digest' => digest })
+ end
+
+ def stub_digest_config(digest, created_at)
+ allow_any_instance_of(ContainerRegistry::Client)
+ .to receive(:blob)
+ .with(repository.path, digest, nil) do
+ { 'created' => created_at.to_datetime.rfc3339 }.to_json if created_at
+ end
+ end
+
+ def stub_upload(content, digest)
+ expect_any_instance_of(ContainerRegistry::Client)
+ .to receive(:upload_blob)
+ .with(repository.path, content, digest) { double(success?: true ) }
+ end
+
+ def expect_delete_tag(digest)
+ expect_any_instance_of(ContainerRegistry::Client)
+ .to receive(:delete_repository_tag)
+ .with(repository.path, digest) { true }
+ end
+end
diff --git a/spec/support/helpers/wait_for_requests.rb b/spec/support/helpers/wait_for_requests.rb
index 30dff1063b5..d5483d0b0a7 100644
--- a/spec/support/helpers/wait_for_requests.rb
+++ b/spec/support/helpers/wait_for_requests.rb
@@ -49,11 +49,11 @@ module WaitForRequests
return true unless javascript_test?
finished_all_ajax_requests? &&
- finished_all_vue_resource_requests?
+ finished_all_axios_requests?
end
- def finished_all_vue_resource_requests?
- Capybara.page.evaluate_script('window.activeVueResources || 0').zero?
+ def finished_all_axios_requests?
+ Capybara.page.evaluate_script('window.pendingRequests || 0').zero?
end
def finished_all_ajax_requests?