Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'qa/qa/resource')
-rw-r--r--qa/qa/resource/api_fabricator.rb19
-rw-r--r--qa/qa/resource/deploy_key.rb42
-rw-r--r--qa/qa/resource/fork.rb2
-rw-r--r--qa/qa/resource/group.rb9
-rw-r--r--qa/qa/resource/group_base.rb20
-rw-r--r--qa/qa/resource/kubernetes_cluster/project_cluster.rb3
-rw-r--r--qa/qa/resource/project.rb36
-rw-r--r--qa/qa/resource/protected_branch.rb10
-rw-r--r--qa/qa/resource/reusable_collection.rb4
-rw-r--r--qa/qa/resource/reusable_group.rb2
-rw-r--r--qa/qa/resource/reusable_project.rb2
-rw-r--r--qa/qa/resource/runner.rb5
12 files changed, 111 insertions, 43 deletions
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index 1958884916c..79cb1ebebc9 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -54,7 +54,7 @@ module QA
body)
unless response.code == HTTP_STATUS_OK
- raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
+ raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
process_api_response(parse_body(response))
@@ -91,9 +91,9 @@ module QA
response = get(request.url)
if response.code == HTTP_STATUS_SERVER_ERROR
- raise InternalServerError, "Failed to GET #{request.mask_url} - (#{response.code}): `#{response}`."
+ raise InternalServerError, "Failed to GET #{request.mask_url} - (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
elsif response.code != HTTP_STATUS_OK
- raise ResourceNotFoundError, "Resource at #{request.mask_url} could not be found (#{response.code}): `#{response}`."
+ raise ResourceNotFoundError, "Resource at #{request.mask_url} could not be found (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
@api_fabrication_http_method = :get # rubocop:disable Gitlab/ModuleWithInstanceVariables
@@ -114,6 +114,7 @@ module QA
unless graphql_response.code == HTTP_STATUS_OK && (body[:errors].nil? || body[:errors].empty?)
raise(ResourceFabricationFailedError, <<~MSG)
Fabrication of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`.
+ #{QA::Support::Loglinking.failure_metadata(graphql_response.headers[:x_request_id])}
MSG
end
@@ -126,7 +127,7 @@ module QA
unless response.code == HTTP_STATUS_CREATED
raise(
ResourceFabricationFailedError,
- "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
+ "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
)
end
@@ -145,7 +146,7 @@ module QA
response = delete(request.url)
unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code
- raise ResourceNotDeletedError, "Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`."
+ raise ResourceNotDeletedError, "Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
response
@@ -165,6 +166,14 @@ module QA
def transform_api_resource(api_resource)
api_resource
end
+
+ # Get api request url
+ #
+ # @param [String] path
+ # @return [String]
+ def request_url(path, **opts)
+ Runtime::API::Request.new(api_client, path, **opts).url
+ end
end
end
end
diff --git a/qa/qa/resource/deploy_key.rb b/qa/qa/resource/deploy_key.rb
index 26355729dab..c06671be77d 100644
--- a/qa/qa/resource/deploy_key.rb
+++ b/qa/qa/resource/deploy_key.rb
@@ -5,6 +5,8 @@ module QA
class DeployKey < Base
attr_accessor :title, :key
+ attribute :id
+
attribute :md5_fingerprint do
Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |key|
@@ -34,6 +36,46 @@ module QA
end
end
end
+
+ def fabricate_via_api!
+ resource_web_url(api_get)
+ rescue ResourceNotFoundError
+ super
+ end
+
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # this particular resource does not expose a web_url property
+ end
+
+ def api_get_path
+ "/projects/#{project.id}/deploy_keys/#{find_id}"
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/deploy_keys"
+ end
+
+ def api_post_body
+ {
+ key: key,
+ title: title
+ }
+ end
+
+ private
+
+ def find_id
+ id
+ rescue NoValueError
+ found_key = auto_paginated_response(request_url("/projects/#{project.id}/deploy_keys", per_page: '100'))
+ .find { |keys| keys[:key].strip == @key.strip }
+
+ return found_key.fetch(:id) if found_key
+
+ raise ResourceNotFoundError
+ end
end
end
end
diff --git a/qa/qa/resource/fork.rb b/qa/qa/resource/fork.rb
index d60b90b534f..0e6dd626312 100644
--- a/qa/qa/resource/fork.rb
+++ b/qa/qa/resource/fork.rb
@@ -95,7 +95,7 @@ module QA
def wait_until_forked
Runtime::Logger.debug("Waiting for the fork process to complete...")
forked = wait_until do
- project.import_status == "finished"
+ project.reload!.import_status == "finished"
end
raise "Timed out while waiting for the fork process to complete." unless forked
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index dee63f9699c..c3da9d47de5 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -10,7 +10,11 @@ module QA
end
attribute :name do
- @name || path
+ @name || @path || Runtime::Namespace.name
+ end
+
+ attribute :path do
+ @path || @name || Runtime::Namespace.name
end
attribute :sandbox do
@@ -20,7 +24,6 @@ module QA
end
def initialize
- @path = Runtime::Namespace.name
@description = "QA test run at #{Runtime::Namespace.time}"
@require_two_factor_authentication = false
end
@@ -64,7 +67,7 @@ module QA
{
parent_id: sandbox.id,
path: path,
- name: name || path,
+ name: name,
visibility: 'public',
require_two_factor_authentication: @require_two_factor_authentication,
avatar: avatar
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index 05b41a4b4f6..889197a0373 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -64,6 +64,10 @@ module QA
end
end
+ def marked_for_deletion?
+ reload!.api_response[:marked_for_deletion_on].present?
+ end
+
# Get group badges
#
# @return [Array<QA::Resource::GroupBadge>]
@@ -80,22 +84,6 @@ module QA
end
end
- # Get group members
- #
- # @return [Array<QA::Resource::User>]
- def members
- parse_body(api_get_from("#{api_get_path}/members")).map do |member|
- User.init do |resource|
- resource.api_client = api_client
- resource.id = member[:id]
- resource.name = member[:name]
- resource.username = member[:username]
- resource.email = member[:email]
- resource.access_level = member[:access_level]
- end
- end
- end
-
# API get path
#
# @return [String]
diff --git a/qa/qa/resource/kubernetes_cluster/project_cluster.rb b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
index 0a63ff47694..0443b26064e 100644
--- a/qa/qa/resource/kubernetes_cluster/project_cluster.rb
+++ b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
@@ -26,9 +26,6 @@ module QA
Page::Project::Infrastructure::Kubernetes::Index.perform(
&:connect_existing_cluster)
- Page::Project::Infrastructure::Kubernetes::Add.perform(
- &:add_existing_cluster)
-
Page::Project::Infrastructure::Kubernetes::AddExisting.perform do |cluster_page|
cluster_page.set_cluster_name(@cluster.cluster_name)
cluster_page.set_api_url(@cluster.api_url)
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index c5b72eebe03..740a8920cf2 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -262,7 +262,7 @@ module QA
reload!.api_response[:default_branch] || Runtime::Env.default_branch
end
- def import_status
+ def project_import_status
response = get(request_url("/projects/#{id}/import"))
unless response.code == HTTP_STATUS_OK
@@ -276,7 +276,7 @@ module QA
Runtime::Logger.error("Failed relations: #{result[:failed_relations]}")
end
- result[:import_status]
+ result
end
def commits(auto_paginate: false, attempts: 0)
@@ -373,6 +373,30 @@ module QA
api_post_to(api_wikis_path, title: title, content: content)
end
+ # Uses the API to wait until a pull mirroring update is successful (pull mirroring is treated as an import)
+ def wait_for_pull_mirroring
+ mirror_succeeded = Support::Retrier.retry_until(max_duration: 180, raise_on_failure: false, sleep_interval: 1) do
+ reload!
+ api_resource[:import_status] == "finished"
+ end
+
+ unless mirror_succeeded
+ raise "Mirroring failed with error: #{api_resource[:import_error]}"
+ end
+ end
+
+ def remove_via_api!
+ super
+
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 1, message: "Waiting for #{self.class.name} to be removed") do
+ !exists?
+ rescue InternalServerError
+ # Retry on transient errors that are likely to be due to race conditions between concurrent delete operations
+ # when parts of a resource are stored in multiple tables
+ false
+ end
+ end
+
protected
# Return subset of fields for comparing projects
@@ -407,14 +431,6 @@ module QA
Git::Location.new(api_resource[:http_url_to_repo])
api_resource
end
-
- # Get api request url
- #
- # @param [String] path
- # @return [String]
- def request_url(path, **opts)
- Runtime::API::Request.new(api_client, path, **opts).url
- end
end
end
end
diff --git a/qa/qa/resource/protected_branch.rb b/qa/qa/resource/protected_branch.rb
index 062d4e9f3d8..55ad6edb3c1 100644
--- a/qa/qa/resource/protected_branch.rb
+++ b/qa/qa/resource/protected_branch.rb
@@ -72,6 +72,16 @@ module QA
self.remove_via_api!(&block)
end
+ # Remove the branch protection after confirming that it exists
+ def remove_via_api!
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 1, message: "Waiting for branch #{branch_name} to be protected") do
+ # We confirm it exists before removal because there's no creation event when the default branch is automatically protected by GitLab itself, and there's a slight delay between creating the repo and protecting the default branch
+ exists?
+ end
+
+ super
+ end
+
def api_get_path
"/projects/#{project.id}/protected_branches/#{branch_name}"
end
diff --git a/qa/qa/resource/reusable_collection.rb b/qa/qa/resource/reusable_collection.rb
index 1168b0091fc..99a55800d1c 100644
--- a/qa/qa/resource/reusable_collection.rb
+++ b/qa/qa/resource/reusable_collection.rb
@@ -35,6 +35,10 @@ module QA
instance.each_resource do |reuse_as, resource|
next QA::Runtime::Logger.debug("#{resource.class.name} reused as :#{reuse_as} has already been removed.") unless resource.exists?
+ if resource.respond_to?(:marked_for_deletion?) && resource.marked_for_deletion?
+ next QA::Runtime::Logger.debug("#{resource.class.name} reused as :#{reuse_as} is already scheduled to be removed.")
+ end
+
resource.method(:remove_via_api!).super_method.call
end
end
diff --git a/qa/qa/resource/reusable_group.rb b/qa/qa/resource/reusable_group.rb
index b75cb0517bf..05ff38249f6 100644
--- a/qa/qa/resource/reusable_group.rb
+++ b/qa/qa/resource/reusable_group.rb
@@ -8,7 +8,7 @@ module QA
def initialize
super
- @name = @path = 'reusable_group'
+ @name = @path = QA::Runtime::Env.reusable_group_path
@description = "QA reusable group"
@reuse_as = :default_group
end
diff --git a/qa/qa/resource/reusable_project.rb b/qa/qa/resource/reusable_project.rb
index b9fca314122..8a12c25b6f0 100644
--- a/qa/qa/resource/reusable_project.rb
+++ b/qa/qa/resource/reusable_project.rb
@@ -15,7 +15,7 @@ module QA
super
@add_name_uuid = false
- @name = @path = 'reusable_project'
+ @name = @path = QA::Runtime::Env.reusable_project_path
@reuse_as = :default_project
@initialize_with_readme = true
end
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index e69702a8ffa..9c5c9992442 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -47,9 +47,8 @@ module QA
def remove_via_api!
runners = project.runners(tag_list: @tags)
- unless runners && !runners.empty?
- raise "Project #{project.path_with_namespace} has no runners#{" with tags #{@tags}." if @tags&.any?}"
- end
+
+ return if runners.blank?
this_runner = runners.find { |runner| runner[:description] == name }
unless this_runner