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