Commit af55ffd2 authored by Sofia Vistas's avatar Sofia Vistas Committed by Dan Davison

Use remove_via_api! for package resources

Prior to this change, there was no way
to remove the package from a given project
unless using the UI. This could cause a
test to fail and leave the package publish
to be deleted and accumulating space.

This change introduces the resource for Package,
focusing on implementing the deletion capability
via the API instead
parent da278bda
......@@ -96,6 +96,7 @@ module QA
autoload :ProjectSnippet, 'qa/resource/project_snippet'
autoload :Design, 'qa/resource/design'
autoload :RegistryRepository, 'qa/resource/registry_repository'
autoload :Package, 'qa/resource/package'
module KubernetesCluster
autoload :Base, 'qa/resource/kubernetes_cluster/base'
......
# frozen_string_literal: true
require 'securerandom'
module QA
module Resource
class Package < Base
attr_accessor :name
attribute :project do
Project.fabricate_via_api! do |resource|
resource.name = 'project-with-package'
resource.description = 'Project with Package'
end
end
attribute :id do
packages = project.packages
return unless (this_package = packages&.find { |package| package[:name] == "#{project.path_with_namespace}/#{name}" }) # rubocop:disable Cop/AvoidReturnFromBlocks
this_package[:id]
end
def fabricate!
end
def fabricate_via_api!
resource_web_url(api_get)
rescue ResourceNotFoundError
super
end
def remove_via_api!
packages = project.packages
if packages && !packages.empty?
QA::Runtime::Logger.debug("Deleting package '#{name}' from '#{project.path_with_namespace}' via API")
super
end
end
def api_delete_path
"/projects/#{project.id}/packages/#{id}"
end
def api_get_path
"/projects/#{project.id}/packages"
end
end
end
end
......@@ -155,6 +155,10 @@ module QA
"#{api_get_path}/registry/repositories"
end
def api_packages_path
"#{api_get_path}/packages"
end
def api_commits_path
"#{api_get_path}/repository/commits"
end
......@@ -262,7 +266,11 @@ module QA
def registry_repositories
response = get Runtime::API::Request.new(api_client, "#{api_registry_repositories_path}").url
parse_body(response)
end
def packages
response = get Runtime::API::Request.new(api_client, "#{api_packages_path}").url
parse_body(response)
end
......
# frozen_string_literal: true
require 'securerandom'
module QA
RSpec.describe 'Package', :orchestrated, :packages do
describe 'Composer Repository' do
include Runtime::Fixtures
let(:package_name) { 'my_package' }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'composer-package-project'
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = "my_package-#{SecureRandom.hex(4)}"
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......@@ -30,7 +37,7 @@ module QA
let(:composer_json_file) do
<<~EOF
{
"name": "#{project.path_with_namespace}/#{package_name}",
"name": "#{project.path_with_namespace}/#{package.name}",
"description": "Library XY",
"type": "library",
"license": "GPL-3.0-only",
......@@ -94,14 +101,15 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
end
it 'publishes a composer package and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1088' do
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
index.click_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform(&:click_delete)
......@@ -109,7 +117,7 @@ module QA
Page::Project::Packages::Index.perform do |index|
aggregate_failures 'package deletion' do
expect(index).to have_content("Package deleted successfully")
expect(index).not_to have_package(package_name)
expect(index).not_to have_package(package.name)
end
end
end
......
......@@ -5,14 +5,19 @@ module QA
describe 'Conan Repository' do
include Runtime::Fixtures
let(:package_name) { 'conantest' }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'conan-package-project'
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = 'conantest'
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......@@ -29,6 +34,7 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
end
it 'publishes, installs, and deletes a Conan package', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1077' do
......@@ -47,10 +53,10 @@ module QA
stage: deploy
script:
- "conan remote add gitlab #{gitlab_address_with_port}/api/v4/projects/#{project.id}/packages/conan"
- "conan new #{package_name}/0.1 -t"
- "conan new #{package.name}/0.1 -t"
- "conan create . mycompany/stable"
- "CONAN_LOGIN_USERNAME=ci_user CONAN_PASSWORD=${CI_JOB_TOKEN} conan upload #{package_name}/0.1@mycompany/stable --all --remote=gitlab"
- "conan install conantest/0.1@mycompany/stable --remote=gitlab"
- "CONAN_LOGIN_USERNAME=ci_user CONAN_PASSWORD=${CI_JOB_TOKEN} conan upload #{package.name}/0.1@mycompany/stable --all --remote=gitlab"
- "conan install #{package.name}/0.1@mycompany/stable --remote=gitlab"
tags:
- "runner-for-#{project.name}"
YAML
......@@ -71,15 +77,15 @@ module QA
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
index.click_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform(&:click_delete)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_content("Package deleted successfully")
expect(index).not_to have_package(package_name)
expect(index).not_to have_package(package.name)
end
end
end
......
......@@ -3,14 +3,19 @@
module QA
RSpec.describe 'Package', :orchestrated, :packages do
describe 'Generic Repository' do
let(:package_name) { 'my_package' }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'generic-package-project'
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = "my_package"
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......@@ -90,14 +95,15 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
end
it 'uploads a generic package, downloads and deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1108' do
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
index.click_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform(&:click_delete)
......@@ -105,7 +111,7 @@ module QA
Page::Project::Packages::Index.perform do |index|
aggregate_failures 'package deletion' do
expect(index).to have_content("Package deleted successfully")
expect(index).to have_no_package(package_name)
expect(index).to have_no_package(package.name)
end
end
end
......
......@@ -23,6 +23,13 @@ module QA
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = package_name
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......@@ -39,6 +46,7 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
end
it 'publishes a maven package via gradle', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1074' do
......
......@@ -31,6 +31,13 @@ module QA
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = package_name
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......
......@@ -5,8 +5,7 @@ module QA
describe 'npm registry' do
include Runtime::Fixtures
let(:registry_scope) { project.group.sandbox.path }
let(:package_name) { "@#{registry_scope}/#{project.name}" }
let!(:registry_scope) { project.group.sandbox.path }
let(:auth_token) do
unless Page::Main::Menu.perform(&:signed_in?)
Flow::Login.sign_in
......@@ -15,12 +14,23 @@ module QA
Resource::PersonalAccessToken.fabricate!.token
end
let(:project) do
let!(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'npm-registry-project'
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = "@#{registry_scope}/#{project.name}"
package.project = project
end
end
after do
package.remove_via_api!
end
it 'publishes an npm package and then deletes it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/944' do
uri = URI.parse(Runtime::Scenario.gitlab_address)
gitlab_host_with_port = "#{uri.host}:#{uri.port}"
......@@ -29,7 +39,7 @@ module QA
file_path: 'package.json',
content: <<~JSON
{
"name": "#{package_name}",
"name": "#{package.name}",
"version": "1.0.0",
"description": "Example package for GitLab npm registry",
"publishConfig": {
......@@ -56,20 +66,20 @@ module QA
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package_name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform do |show|
expect(show).to have_package_info(package_name, "1.0.0")
expect(show).to have_package_info(package.name, "1.0.0")
show.click_delete
end
Page::Project::Packages::Index.perform do |index|
expect(index).to have_content("Package deleted successfully")
expect(index).not_to have_package(package_name)
expect(index).not_to have_package(package.name)
end
end
end
......
......@@ -6,8 +6,6 @@ module QA
RSpec.describe 'Package', :orchestrated, :packages do
describe 'NuGet Repository' do
include Runtime::Fixtures
let(:package_name) { "dotnetcore-#{SecureRandom.hex(8)}" }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'nuget-package-project'
......@@ -15,6 +13,13 @@ module QA
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = "dotnetcore-#{SecureRandom.hex(8)}"
package.project = project
end
end
let(:another_project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'nuget-package-install-project'
......@@ -43,6 +48,7 @@ module QA
after do
runner.remove_via_api!
another_runner.remove_via_api!
package.remove_via_api!
end
it 'publishes a nuget package at the project level, installs and deletes it at the group level', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1073' do
......@@ -66,7 +72,7 @@ module QA
script:
- dotnet restore -p:Configuration=Release
- dotnet build -c Release
- dotnet pack -c Release -p:PackageID=#{package_name}
- dotnet pack -c Release -p:PackageID=#{package.name}
- dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- dotnet nuget push "bin/Release/*.nupkg" --source gitlab
only:
......@@ -127,7 +133,7 @@ module QA
script:
- dotnet nuget locals all --clear
- dotnet nuget add source "$CI_SERVER_URL/api/v4/groups/#{another_project.group.id}/-/packages/nuget/index.json" --name gitlab --username gitlab-ci-token --password $CI_JOB_TOKEN --store-password-in-clear-text
- "dotnet add otherdotnet.csproj package #{package_name} --version 1.0.0"
- "dotnet add otherdotnet.csproj package #{package.name} --version 1.0.0"
only:
- "#{another_project.default_branch}"
tags:
......@@ -153,15 +159,15 @@ module QA
Page::Group::Menu.perform(&:go_to_group_packages)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
index.click_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform(&:click_delete)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_content("Package deleted successfully")
expect(index).not_to have_package(package_name)
expect(index).not_to have_package(package.name)
end
end
end
......
......@@ -4,15 +4,19 @@ module QA
RSpec.describe 'Package', :orchestrated, :packages do
describe 'PyPI Repository' do
include Runtime::Fixtures
let(:package_name) { 'mypypipackage' }
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pypi-package-project'
end
end
let(:package) do
Resource::Package.new.tap do |package|
package.name = 'mypypipackage'
package.project = project
end
end
let!(:runner) do
Resource::Runner.fabricate! do |runner|
runner.name = "qa-runner-#{Time.now.to_i}"
......@@ -87,6 +91,7 @@ module QA
after do
runner.remove_via_api!
package.remove_via_api!
project&.remove_via_api!
end
......@@ -94,8 +99,8 @@ module QA
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
expect(index).to have_package(package_name)
index.click_package(package_name)
expect(index).to have_package(package.name)
index.click_package(package.name)
end
Page::Project::Packages::Show.perform(&:click_delete)
......@@ -103,7 +108,7 @@ module QA
Page::Project::Packages::Index.perform do |index|
aggregate_failures do
expect(index).to have_content("Package deleted successfully")
expect(index).not_to have_package(package_name)
expect(index).not_to have_package(package.name)
end
end
end
......@@ -127,8 +132,8 @@ module QA
Page::Project::Menu.perform(&:click_packages_link)
Page::Project::Packages::Index.perform do |index|
index.wait_for_package_replication(package_name)
expect(index).to have_package(package_name)
index.wait_for_package_replication(package.name)
expect(index).to have_package(package.name)
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