lib/gitlab/qa/scenario/test/integration/import.rb



# frozen_string_literal: true

require "parallel"

module Gitlab
  module QA
    module Scenario
      module Test
        module Integration
          # Scenario type for testing importers
          #
          # In addition to main gitlab instance, starts another gitlab instance to act as source
          #   and mock server to replace all other possible import sources
          #
          class Import < Scenario::Template
            def initialize
              @network = "test"
              @source_gitlab = Component::Gitlab.new.tap { |gitlab| gitlab.network = @network }
              @target_gitlab = Component::Gitlab.new.tap { |gitlab| gitlab.network = @network }
              @mock_server = Component::MockServer.new.tap do |server|
                server.network = @network
                server.tls = true
              end
            end

            attr_reader :source_gitlab, :target_gitlab, :mock_server, :network

            def perform(release, *rspec_args)
              start_mock_server
              start_gitlab_instances(release)

              run_specs(rspec_args)
            ensure
              mock_server.teardown
              target_gitlab.teardown
              source_gitlab.teardown
            end

            private

            # Start mock server instance
            #
            # @return [void]
            def start_mock_server
              mock_server.start_instance
            end

            # Start gitlab instance
            #
            # @param [Gitlab::QA::Release] release
            # @return [void]
            def start_gitlab_instances(release)
              instances = [
                { instance: source_gitlab, name: "import-source", additional_hosts: [] },
                { instance: target_gitlab, name: "import-target", additional_hosts: mocked_hosts }
              ]

              ::Parallel.each(instances, in_threads: 2) do |gitlab_instance|
                gitlab_instance[:instance].tap do |gitlab|
                  gitlab.name = gitlab_instance[:name]
                  gitlab.release = release
                  gitlab.additional_hosts = gitlab_instance[:additional_hosts]
                  gitlab.seed_admin_token = true

                  gitlab.start_instance
                end
              end
            end

            # Run tests
            #
            # @param [Array] rspec_args
            # @return [void]
            def run_specs(rspec_args)
              Component::Specs.perform do |specs|
                specs.suite = "Test::Integration::Import"
                specs.release = target_gitlab.release
                specs.network = network
                specs.args = [target_gitlab.address, *rspec_args]
                specs.env = {
                  "QA_ALLOW_LOCAL_REQUESTS" => "true",
                  "QA_IMPORT_SOURCE_URL" => source_gitlab.address,
                  "QA_SMOCKER_HOST" => mock_server.hostname
                }
              end
            end

            # List of hosts that should be redirected to mock server
            #
            # @return [Array]
            def mocked_hosts
              hosts = []
              hosts << "api.github.com:#{mock_server.ip_address}" if Runtime::Env.mock_github_enabled?

              hosts
            end
          end
        end
      end
    end
  end
end