Welcome to mirror list, hosted at ThFree Co, Russian Federation.

runner.rb « specs « qa « qa - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a861c13a44c6e5f35c4c9a4028d83f4d116954aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# frozen_string_literal: true

require 'rspec/core'
require 'rspec/expectations'

module QA
  module Specs
    class Runner < Scenario::Template
      attr_accessor :tty, :tags, :options
      RegexMismatchError = Class.new(StandardError)

      DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze
      DEFAULT_STD_ARGS = [$stderr, $stdout].freeze

      def initialize
        @tty = false
        @tags = []
        @options = []
      end

      def paths_from_knapsack
        allocator = Knapsack::AllocatorBuilder.new(Knapsack::Adapters::RSpecAdapter).allocator

        QA::Runtime::Logger.info '==== Knapsack specs to execute ====='
        QA::Runtime::Logger.info 'Report specs:'
        QA::Runtime::Logger.info allocator.report_node_tests.join(', ')
        QA::Runtime::Logger.info 'Leftover specs:'
        QA::Runtime::Logger.info allocator.leftover_node_tests.join(', ')

        ['--', allocator.node_tests]
      end

      def rspec_tags
        tags_for_rspec = []

        if tags.any?
          tags.each { |tag| tags_for_rspec.push(['--tag', tag.to_s]) }
        else
          tags_for_rspec.push(%w[--tag ~orchestrated --tag ~transient]) unless (%w[-t --tag] & options).any?
        end

        tags_for_rspec.push(%w[--tag ~geo]) unless QA::Runtime::Env.geo_environment?

        tags_for_rspec.push(%w[--tag ~skip_signup_disabled]) if QA::Runtime::Env.signup_disabled?

        tags_for_rspec.push(%w[--tag ~skip_live_env]) if QA::Specs::Helpers::ContextSelector.dot_com?

        QA::Runtime::Env.supported_features.each_key do |key|
          tags_for_rspec.push(%W[--tag ~requires_#{key}]) unless QA::Runtime::Env.can_test? key
        end

        tags_for_rspec
      end

      def perform
        args = []
        args.push('--tty') if tty
        args.push(rspec_tags)
        args.push(options)

        if Runtime::Env.knapsack?
          args.push(paths_from_knapsack)
        else
          args.push(DEFAULT_TEST_PATH_ARGS) unless options.any? { |opt| opt =~ %r{/features/} }
        end

        Runtime::Scenario.define(:large_setup?, args.flatten.include?('can_use_large_setup'))

        if Runtime::Scenario.attributes[:parallel]
          ParallelRunner.run(args.flatten)
        elsif Runtime::Scenario.attributes[:loop]
          LoopRunner.run(args.flatten)
        elsif Runtime::Scenario.attributes[:count_examples_only]
          args.unshift('--dry-run')
          out = StringIO.new

          RSpec::Core::Runner.run(args.flatten, $stderr, out).tap do |status|
            abort if status.nonzero?
          end

          begin
            total_examples = out.string.match(/(\d+) examples?,/)[1]
          rescue StandardError
            raise RegexMismatchError, 'Rspec output did not match regex'
          end

          filename = build_filename

          File.open(filename, 'w') { |f| f.write(total_examples) } if total_examples.to_i > 0

          $stdout.puts "Total examples in #{Runtime::Scenario.klass}: #{total_examples}#{total_examples.to_i > 0 ? ". Saved to file: #{filename}" : ''}"
        else
          RSpec::Core::Runner.run(args.flatten, *DEFAULT_STD_ARGS).tap do |status|
            abort if status.nonzero?
          end
        end
      end

      private

      def build_filename
        filename = Runtime::Scenario.klass.split('::').last(3).join('_').downcase

        tags = []
        options.reduce do |before, after|
          tags << after if %w[--tag -t].include?(before)
          after
        end
        tags = tags.compact.join('_')

        filename.concat("_#{tags}") unless tags.empty?

        filename.concat('.txt')

        FileUtils.mkdir_p('no_of_examples')
        File.join('no_of_examples', filename)
      end
    end
  end
end