Commit 8a229fdf authored by Andrejs Cunskis's avatar Andrejs Cunskis

E2E: Refactor github import tests

parent 3a360285
...@@ -262,7 +262,7 @@ module QA ...@@ -262,7 +262,7 @@ module QA
reload!.api_response[:default_branch] || Runtime::Env.default_branch reload!.api_response[:default_branch] || Runtime::Env.default_branch
end end
def import_status def project_import_status
response = get(request_url("/projects/#{id}/import")) response = get(request_url("/projects/#{id}/import"))
unless response.code == HTTP_STATUS_OK unless response.code == HTTP_STATUS_OK
...@@ -276,7 +276,7 @@ module QA ...@@ -276,7 +276,7 @@ module QA
Runtime::Logger.error("Failed relations: #{result[:failed_relations]}") Runtime::Logger.error("Failed relations: #{result[:failed_relations]}")
end end
result[:import_status] result
end end
def commits(auto_paginate: false, attempts: 0) def commits(auto_paginate: false, attempts: 0)
......
...@@ -31,11 +31,13 @@ module QA ...@@ -31,11 +31,13 @@ module QA
end end
it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
imported_project # import the project imported_project.reload! # import the project
expect { imported_project.reload!.import_status }.to eventually_eq('finished').within(max_duration: 90) expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
.within(max_duration: 90, sleep_interval: 1)
aggregate_failures do aggregate_failures do
verify_status_data
verify_repository_import verify_repository_import
verify_commits_import verify_commits_import
verify_labels_import verify_labels_import
...@@ -46,6 +48,19 @@ module QA ...@@ -46,6 +48,19 @@ module QA
end end
end end
def verify_status_data
stats = imported_project.project_import_status.dig(:stats, :imported)
expect(stats).to eq(
label: 10,
milestone: 1,
issue: 2,
note: 2,
pull_request: 1,
pull_request_review: 2,
diff_note: 2
)
end
def verify_repository_import def verify_repository_import
expect(imported_project.api_response).to include( expect(imported_project.api_response).to include(
description: 'A new repo for test', description: 'A new repo for test',
......
...@@ -99,21 +99,29 @@ module QA ...@@ -99,21 +99,29 @@ module QA
import_time: @import_time, import_time: @import_time,
github: { github: {
project_name: github_repo, project_name: github_repo,
branches: gh_branches, branches: gh_branches.length,
commits: gh_commits, commits: gh_commits.length,
labels: gh_labels, labels: gh_labels.length,
milestones: gh_milestones, milestones: gh_milestones.length,
prs: gh_prs, prs: gh_prs.length,
issues: gh_issues pr_comments: gh_prs.sum { |_k, v| v.length },
issues: gh_issues.length,
issue_comments: gh_issues.sum { |_k, v| v.length }
}, },
gitlab: { gitlab: {
project_name: imported_project.path_with_namespace, project_name: imported_project.path_with_namespace,
branches: gl_branches, branches: gl_branches.length,
commits: gl_commits, commits: gl_commits.length,
labels: gl_labels, labels: gl_labels.length,
milestones: gl_milestones, milestones: gl_milestones.length,
mrs: mrs, mrs: mrs.length,
issues: gl_issues mr_comments: mrs.sum { |_k, v| v.length },
issues: gl_issues.length,
issue_comments: gl_issues.sum { |_k, v| v.length }
},
not_imported: {
mrs: @mr_diff,
issues: @issue_diff
} }
}.to_json }.to_json
) )
...@@ -125,14 +133,18 @@ module QA ...@@ -125,14 +133,18 @@ module QA
) do ) do
start = Time.now start = Time.now
Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path # import the project and log path
fetch_github_objects # fetch all objects right after import has started Runtime::Logger.info("Importing project '#{imported_project.reload!.full_path}'")
# fetch all objects right after import has started
fetch_github_objects
import_status = lambda do import_status = lambda do
imported_project.reload!.import_status.tap do |status| imported_project.project_import_status[:import_status].tap do |status|
# fail fast if import explicitly failed
raise "Import of '#{imported_project.name}' failed!" if status == 'failed' raise "Import of '#{imported_project.name}' failed!" if status == 'failed'
end end
end end
expect(import_status).to eventually_eq('finished').within(max_duration: import_max_duration, sleep_interval: 30) expect(import_status).to eventually_eq('finished').within(max_duration: import_max_duration, sleep_interval: 30)
@import_time = Time.now - start @import_time = Time.now - start
...@@ -177,7 +189,7 @@ module QA ...@@ -177,7 +189,7 @@ module QA
# @return [void] # @return [void]
def verify_merge_requests_import def verify_merge_requests_import
logger.debug("== Verifying merge request import ==") logger.debug("== Verifying merge request import ==")
verify_mrs_or_issues('mr') @mr_diff = verify_mrs_or_issues('mr')
end end
# Verify imported issues and issue comments # Verify imported issues and issue comments
...@@ -185,7 +197,7 @@ module QA ...@@ -185,7 +197,7 @@ module QA
# @return [void] # @return [void]
def verify_issues_import def verify_issues_import
logger.debug("== Verifying issue import ==") logger.debug("== Verifying issue import ==")
verify_mrs_or_issues('issue') @issue_diff = verify_mrs_or_issues('issue')
end end
# Verify imported labels # Verify imported labels
...@@ -207,47 +219,67 @@ module QA ...@@ -207,47 +219,67 @@ module QA
private private
# Verify imported mrs or issues # Verify imported mrs or issues and return diff
# #
# @param [String] type verification object, 'mrs' or 'issues' # @param [String] type verification object, 'mrs' or 'issues'
# @return [void] # @return [Hash]
def verify_mrs_or_issues(type) def verify_mrs_or_issues(type)
msg = ->(title) { "expected #{type} with title '#{title}' to have" }
# Compare length to have easy to read overview how many objects are missing # Compare length to have easy to read overview how many objects are missing
#
expected = type == 'mr' ? mrs : gl_issues expected = type == 'mr' ? mrs : gl_issues
actual = type == 'mr' ? gh_prs : gh_issues actual = type == 'mr' ? gh_prs : gh_issues
count_msg = "Expected to contain same amount of #{type}s. Gitlab: #{expected.length}, Github: #{actual.length}" count_msg = "Expected to contain same amount of #{type}s. Gitlab: #{expected.length}, Github: #{actual.length}"
expect(expected.length).to eq(actual.length), count_msg expect(expected.length).to eq(actual.length), count_msg
logger.debug("= Comparing #{type}s =") logger.debug("= Comparing #{type}s =")
actual.each do |title, actual_item| missing_comments = verify_comments(type, actual, expected)
print "." # indicate that it is still going but don't spam the output with newlines
{
"#{type}s": actual.keys - expected.keys,
"#{type}_comments": missing_comments
}
end
# Verify imported comments
#
# @param [String] type verification object, 'mrs' or 'issues'
# @param [Hash] actual
# @param [Hash] expected
# @return [Hash]
def verify_comments(type, actual, expected)
actual.each_with_object({}) do |(title, actual_item), missing_comments|
msg = "expected #{type} with title '#{title}' to have"
expected_item = expected[title] expected_item = expected[title]
# Print title in the error message to see which object is missing # Print title in the error message to see which object is missing
expect(expected_item).to be_truthy, "#{msg.call(title)} been imported" #
expect(expected_item).to be_truthy, "#{msg} been imported"
next unless expected_item next unless expected_item
# Print difference in the description # Print difference in the description
#
expected_body = expected_item[:body] expected_body = expected_item[:body]
actual_body = actual_item[:body] actual_body = actual_item[:body]
body_msg = <<~MSG body_msg = <<~MSG
#{msg.call(title)} same description. diff:\n#{differ.diff(expected_item[:body], actual_item[:body])} #{msg} same description. diff:\n#{differ.diff(expected_item[:body], actual_item[:body])}
MSG MSG
expect(expected_body).to include(actual_body), body_msg expect(expected_body).to include(actual_body), body_msg
# Print amount difference first # Print amount difference first
#
expected_comments = expected_item[:comments] expected_comments = expected_item[:comments]
actual_comments = actual_item[:comments] actual_comments = actual_item[:comments]
comment_count_msg = <<~MSG comment_count_msg = <<~MSG
#{msg.call(title)} same amount of comments. Gitlab: #{expected_comments.length}, Github: #{actual_comments.length} #{msg} same amount of comments. Gitlab: #{expected_comments.length}, Github: #{actual_comments.length}
MSG MSG
expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg
expect(expected_comments).to match_array(actual_comments) expect(expected_comments).to match_array(actual_comments)
# Save missing comments
#
comment_diff = actual_comments - expected_comments
missing_comments[title] = comment_diff unless comment_diff.empty?
end end
puts # print newline after last print to make output pretty
end end
# Imported project branches # Imported project branches
...@@ -339,12 +371,12 @@ module QA ...@@ -339,12 +371,12 @@ module QA
end end
end end
# Remove added prefixes by importer # Remove added prefixes and legacy diff format
# #
# @param [String] body # @param [String] body
# @return [String] # @return [String]
def sanitize(body) def sanitize(body)
body.gsub(/\*Created by: \S+\*\n\n/, "") body.gsub(/\*Created by: \S+\*\n\n/, "").gsub(/suggestion:-\d+\+\d+/, "suggestion\r")
end end
# Save json as file # Save json as file
......
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