From 8a229fdf494dcb3b571e69fbc8e3f6bc4d3443d0 Mon Sep 17 00:00:00 2001 From: Andrejs Cunskis <acunskis@gitlab.com> Date: Mon, 21 Feb 2022 16:32:17 +0000 Subject: [PATCH] E2E: Refactor github import tests --- qa/qa/resource/project.rb | 4 +- .../api/1_manage/import_github_repo_spec.rb | 19 +++- .../1_manage/import_large_github_repo_spec.rb | 90 +++++++++++++------ 3 files changed, 80 insertions(+), 33 deletions(-) diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb index 4550e00f87eb..e0f9700ce5a3 100644 --- a/qa/qa/resource/project.rb +++ b/qa/qa/resource/project.rb @@ -262,7 +262,7 @@ def default_branch 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 @@ def import_status Runtime::Logger.error("Failed relations: #{result[:failed_relations]}") end - result[:import_status] + result end def commits(auto_paginate: false, attempts: 0) diff --git a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb index a51d733d484d..00a099d5730a 100644 --- a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb @@ -31,11 +31,13 @@ module QA end 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 + verify_status_data verify_repository_import verify_commits_import verify_labels_import @@ -46,6 +48,19 @@ module QA 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 expect(imported_project.api_response).to include( description: 'A new repo for test', diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb index c46de0ac514f..3d8f832df9e6 100644 --- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb @@ -99,21 +99,29 @@ module QA import_time: @import_time, github: { project_name: github_repo, - branches: gh_branches, - commits: gh_commits, - labels: gh_labels, - milestones: gh_milestones, - prs: gh_prs, - issues: gh_issues + branches: gh_branches.length, + commits: gh_commits.length, + labels: gh_labels.length, + milestones: gh_milestones.length, + prs: gh_prs.length, + pr_comments: gh_prs.sum { |_k, v| v.length }, + issues: gh_issues.length, + issue_comments: gh_issues.sum { |_k, v| v.length } }, gitlab: { project_name: imported_project.path_with_namespace, - branches: gl_branches, - commits: gl_commits, - labels: gl_labels, - milestones: gl_milestones, - mrs: mrs, - issues: gl_issues + branches: gl_branches.length, + commits: gl_commits.length, + labels: gl_labels.length, + milestones: gl_milestones.length, + mrs: mrs.length, + 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 ) @@ -125,14 +133,18 @@ module QA ) do start = Time.now - Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path - fetch_github_objects # fetch all objects right after import has started + # import the project and log path + 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 - 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' end end + expect(import_status).to eventually_eq('finished').within(max_duration: import_max_duration, sleep_interval: 30) @import_time = Time.now - start @@ -177,7 +189,7 @@ def verify_repository_import # @return [void] def verify_merge_requests_import logger.debug("== Verifying merge request import ==") - verify_mrs_or_issues('mr') + @mr_diff = verify_mrs_or_issues('mr') end # Verify imported issues and issue comments @@ -185,7 +197,7 @@ def verify_merge_requests_import # @return [void] def verify_issues_import logger.debug("== Verifying issue import ==") - verify_mrs_or_issues('issue') + @issue_diff = verify_mrs_or_issues('issue') end # Verify imported labels @@ -207,47 +219,67 @@ def verify_milestones_import private - # Verify imported mrs or issues + # Verify imported mrs or issues and return diff # # @param [String] type verification object, 'mrs' or 'issues' - # @return [void] + # @return [Hash] 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 + # expected = type == 'mr' ? mrs : gl_issues actual = type == 'mr' ? gh_prs : gh_issues 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 logger.debug("= Comparing #{type}s =") - actual.each do |title, actual_item| - print "." # indicate that it is still going but don't spam the output with newlines + missing_comments = verify_comments(type, actual, expected) + { + "#{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] # 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 # Print difference in the description + # expected_body = expected_item[:body] actual_body = actual_item[:body] 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 expect(expected_body).to include(actual_body), body_msg # Print amount difference first + # expected_comments = expected_item[:comments] actual_comments = actual_item[:comments] 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 expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg 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 - puts # print newline after last print to make output pretty end # Imported project branches @@ -339,12 +371,12 @@ def gl_issues end end - # Remove added prefixes by importer + # Remove added prefixes and legacy diff format # # @param [String] body # @return [String] def sanitize(body) - body.gsub(/\*Created by: \S+\*\n\n/, "") + body.gsub(/\*Created by: \S+\*\n\n/, "").gsub(/suggestion:-\d+\+\d+/, "suggestion\r") end # Save json as file -- GitLab