From 212ef9daa57a7b2573166e82e4471b7e32be9816 Mon Sep 17 00:00:00 2001
From: Jennifer Louie <jlouie@gitlab.com>
Date: Thu, 8 Oct 2020 23:21:02 +0000
Subject: [PATCH] Add end-to-end Geo tests for CI job logs and artifacts

Add page object methods to wait for replication
Add page object methods to wait and check for job log
Add page object method to wait for browse button
---
 qa/qa/ee.rb                                   |   5 +
 qa/qa/ee/page/project/job/show.rb             |  30 +++++
 qa/qa/ee/page/project/pipeline/index.rb       |  22 +++
 qa/qa/ee/page/project/pipeline/show.rb        |   7 +
 qa/qa/page/project/job/show.rb                |   6 +
 qa/qa/page/project/pipeline/index.rb          |   2 +
 ...o_replication_ci_job_log_artifacts_spec.rb | 125 ++++++++++++++++++
 7 files changed, 197 insertions(+)
 create mode 100644 qa/qa/ee/page/project/job/show.rb
 create mode 100644 qa/qa/ee/page/project/pipeline/index.rb
 create mode 100644 qa/qa/specs/features/ee/browser_ui/geo/geo_replication_ci_job_log_artifacts_spec.rb

diff --git a/qa/qa/ee.rb b/qa/qa/ee.rb
index e6d0c1040a786..94b73753902c3 100644
--- a/qa/qa/ee.rb
+++ b/qa/qa/ee.rb
@@ -153,6 +153,7 @@ module Metrics
 
         module Pipeline
           autoload :Show, 'qa/ee/page/project/pipeline/show'
+          autoload :Index, 'qa/ee/page/project/pipeline/index'
         end
 
         module Secure
@@ -174,6 +175,10 @@ module Packages
         module Snippet
           autoload :Index, 'qa/ee/page/project/snippet/index'
         end
+
+        module Job
+          autoload :Show, 'qa/ee/page/project/job/show'
+        end
       end
 
       module MergeRequest
diff --git a/qa/qa/ee/page/project/job/show.rb b/qa/qa/ee/page/project/job/show.rb
new file mode 100644
index 0000000000000..0613dbe2ceb8d
--- /dev/null
+++ b/qa/qa/ee/page/project/job/show.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module QA
+  module EE
+    module Page
+      module Project
+        module Job
+          module Show
+            extend QA::Page::PageConcern
+
+            # These wait times cover both the time for pipeline job to complete and time for log and artifact to Geo replicate, so the max duration has been doubled
+            def wait_for_job_log_replication
+              QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_job_log_replication])
+              wait_until(max_duration: 2 * Runtime::Geo.max_file_replication_time) do
+                has_job_log?
+              end
+            end
+
+            def wait_for_job_artifact_replication
+              QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_job_artifact_replication])
+              wait_until(max_duration: 2 * Runtime::Geo.max_file_replication_time) do
+                has_browse_button?
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/qa/qa/ee/page/project/pipeline/index.rb b/qa/qa/ee/page/project/pipeline/index.rb
new file mode 100644
index 0000000000000..3c488900f1d98
--- /dev/null
+++ b/qa/qa/ee/page/project/pipeline/index.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module QA
+  module EE
+    module Page
+      module Project
+        module Pipeline
+          module Index
+            extend QA::Page::PageConcern
+
+            def wait_for_latest_pipeline_replication
+              QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_latest_pipeline_replication])
+              wait_until(max_duration: Runtime::Geo.max_file_replication_time) do
+                within_element_by_index(:pipeline_commit_status, 0) { has_text?('passed') || has_text?('failed') }
+              end
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/qa/qa/ee/page/project/pipeline/show.rb b/qa/qa/ee/page/project/pipeline/show.rb
index 09c4ce50b674f..b75c2a7c8b732 100644
--- a/qa/qa/ee/page/project/pipeline/show.rb
+++ b/qa/qa/ee/page/project/pipeline/show.rb
@@ -34,6 +34,13 @@ def click_on_licenses
             def has_license_count_of?(count)
               find_element(:licenses_counter).has_content?(count)
             end
+
+            def wait_for_pipeline_job_replication(name)
+              QA::Runtime::Logger.debug(%Q[#{self.class.name} - wait_for_pipeline_job_replication])
+              wait_until(max_duration: Runtime::Geo.max_file_replication_time) do
+                has_job?(name)
+              end
+            end
           end
         end
       end
diff --git a/qa/qa/page/project/job/show.rb b/qa/qa/page/project/job/show.rb
index 6a657b4ab3906..2ecb27e05b2cc 100644
--- a/qa/qa/page/project/job/show.rb
+++ b/qa/qa/page/project/job/show.rb
@@ -58,6 +58,10 @@ def retry!
             click_element :retry_button
           end
 
+          def has_job_log?
+            has_element? :job_log_content
+          end
+
           private
 
           def loaded?(wait: 60)
@@ -70,3 +74,5 @@ def loaded?(wait: 60)
     end
   end
 end
+
+QA::Page::Project::Job::Show.prepend_if_ee('QA::EE::Page::Project::Job::Show')
diff --git a/qa/qa/page/project/pipeline/index.rb b/qa/qa/page/project/pipeline/index.rb
index b2ecbb2e98812..aff2378330ab5 100644
--- a/qa/qa/page/project/pipeline/index.rb
+++ b/qa/qa/page/project/pipeline/index.rb
@@ -57,3 +57,5 @@ def click_run_pipeline_button
     end
   end
 end
+
+QA::Page::Project::Pipeline::Index.prepend_if_ee('QA::EE::Page::Project::Pipeline::Index')
diff --git a/qa/qa/specs/features/ee/browser_ui/geo/geo_replication_ci_job_log_artifacts_spec.rb b/qa/qa/specs/features/ee/browser_ui/geo/geo_replication_ci_job_log_artifacts_spec.rb
new file mode 100644
index 0000000000000..c8931ea6aa3d6
--- /dev/null
+++ b/qa/qa/specs/features/ee/browser_ui/geo/geo_replication_ci_job_log_artifacts_spec.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: true
+
+module QA
+  RSpec.describe 'Geo', :orchestrated, :runner, :requires_admin, :geo do
+    describe 'CI job' do
+      before(:all) do
+        @file_name = 'geo_artifact.txt'
+        @directory_name = 'geo_artifacts'
+        @pipeline_job_name = 'test-artifacts'
+        executor = "qa-runner-#{Time.now.to_i}"
+
+        @project = Resource::Project.fabricate_via_api! do |project|
+          project.name = 'geo-project-with-artifacts'
+        end
+
+        @runner = Resource::Runner.fabricate! do |runner|
+          runner.project = @project
+          runner.name = executor
+          runner.tags = [executor]
+        end
+
+        Resource::Repository::Commit.fabricate_via_api! do |commit|
+          commit.project = @project
+          commit.commit_message = 'Add .gitlab-ci.yml'
+          commit.add_files(
+            [
+              {
+                file_path: '.gitlab-ci.yml',
+                content: <<~YAML
+                  test-artifacts:
+                    tags:
+                      - '#{executor}'
+                    artifacts:
+                      paths:
+                        - '#{@directory_name}'
+                      expire_in: 1000 seconds
+                    script:
+                      - |
+                        mkdir #{@directory_name}
+                        echo "CONTENTS" > #{@directory_name}/#{@file_name}
+                YAML
+              }
+            ]
+          )
+        end
+      end
+
+      after(:all) do
+        @runner.remove_via_api!
+      end
+
+      # Test code is based on qa/specs/features/ee/browser_ui/4_verify/locked_artifacts_spec.rb
+      it 'replicates the job log to the secondary Geo site', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/908' do
+        Runtime::Logger.debug('Visiting the secondary Geo site')
+
+        Flow::Login.while_signed_in(address: :geo_secondary) do
+          EE::Page::Main::Banner.perform do |banner|
+            expect(banner).to have_secondary_read_only_banner
+          end
+
+          Page::Main::Menu.perform(&:go_to_projects)
+
+          Page::Dashboard::Projects.perform do |dashboard|
+            dashboard.wait_for_project_replication(@project.name)
+            dashboard.go_to_project(@project.name)
+          end
+
+          Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+          Page::Project::Pipeline::Index.perform do |index|
+            index.wait_for_latest_pipeline_replication
+            index.click_on_latest_pipeline
+          end
+
+          Page::Project::Pipeline::Show.perform do |pipeline|
+            pipeline.wait_for_pipeline_job_replication(@pipeline_job_name)
+            pipeline.click_job(@pipeline_job_name)
+          end
+
+          Page::Project::Job::Show.perform do |pipeline_job|
+            pipeline_job.wait_for_job_log_replication
+            expect(pipeline_job).to have_job_log
+          end
+        end
+      end
+
+      it 'replicates the job artifact to the secondary Geo site', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/186' do
+        Runtime::Logger.debug('Visiting the secondary Geo site')
+
+        Flow::Login.while_signed_in(address: :geo_secondary) do
+          EE::Page::Main::Banner.perform do |banner|
+            expect(banner).to have_secondary_read_only_banner
+          end
+
+          Page::Main::Menu.perform(&:go_to_projects)
+
+          Page::Dashboard::Projects.perform do |dashboard|
+            dashboard.wait_for_project_replication(@project.name)
+            dashboard.go_to_project(@project.name)
+          end
+
+          Page::Project::Menu.perform(&:click_ci_cd_pipelines)
+          Page::Project::Pipeline::Index.perform do |index|
+            index.wait_for_latest_pipeline_replication
+            index.click_on_latest_pipeline
+          end
+
+          Page::Project::Pipeline::Show.perform do |pipeline|
+            pipeline.wait_for_pipeline_job_replication(@pipeline_job_name)
+            pipeline.click_job(@pipeline_job_name)
+          end
+
+          Page::Project::Job::Show.perform do |pipeline_job|
+            pipeline_job.wait_for_job_artifact_replication
+            pipeline_job.click_browse_button
+          end
+
+          EE::Page::Project::Artifact::Show.perform do |artifact|
+            artifact.go_to_directory(@directory_name)
+            expect(artifact).to have_content(@file_name)
+          end
+        end
+      end
+    end
+  end
+end
-- 
GitLab