summaryrefslogtreecommitdiff
path: root/qa/qa/tools/ci/non_empty_suites.rb
blob: 2319237fa258edf6f45d257fbb2c2e01151dfe05 (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
# frozen_string_literal: true

require 'open3'

module QA
  module Tools
    module Ci
      # Run count commands for scenarios and detect which ones have more than 0 examples to run
      #
      class NonEmptySuites
        include Helpers

        # @return [Array] scenarios that never run in package-and-test pipeline
        IGNORED_SCENARIOS = [
          "QA::EE::Scenario::Test::Geo",
          "QA::Scenario::Test::Instance::Airgapped"
        ].freeze

        def initialize(qa_tests)
          @qa_tests = qa_tests
        end

        # Run counts and return runnable scenario list
        #
        # @return [String]
        def fetch
          logger.info("Checking for runnable suites")
          scenarios.each_with_object([]) do |scenario, runnable_scenarios|
            logger.info(" fetching runnable specs for '#{scenario}'")
            next logger.info("  scenario is in ignore list, skipping") if IGNORED_SCENARIOS.include?(scenario)

            out, err, status = run_command(scenario)

            unless status.success?
              logger.error("  example count failed!\n#{err}")
              next
            end

            count = out.split("\n").last.to_i
            logger.info("  found #{count} examples to run")
            runnable_scenarios << scenario if count > 0
          end.join(",")
        end

        private

        attr_reader :qa_tests

        # Get all defined scenarios
        #
        # @return [Array<String>]
        def scenarios
          foss_scenarios = scenario_classes(QA::Scenario::Test)
          return foss_scenarios unless QA.const_defined?("QA::EE")

          foss_scenarios + scenario_classes(QA::EE::Scenario::Test)
        end

        # Fetch scenario classes recursively
        #
        # @param [Module] mod
        # @return [Array<String>]
        def scenario_classes(mod)
          mod.constants.map do |const|
            c = mod.const_get(const, false)
            next c.to_s if c.is_a?(Class)

            scenario_classes(c)
          end.flatten
        end

        # Run scenario count command
        #
        # @param [String] klass
        # @return [String]
        def run_command(klass)
          cmd = ["bundle exec bin/qa"]
          cmd << klass
          cmd << "--count-examples-only --address http://dummy1.test"
          cmd << "-- #{qa_tests}" unless qa_tests.blank?

          Open3.capture3(cmd.join(" "))
        end
      end
    end
  end
end