summaryrefslogtreecommitdiff
path: root/qa/qa/tools/ci
diff options
context:
space:
mode:
Diffstat (limited to 'qa/qa/tools/ci')
-rw-r--r--qa/qa/tools/ci/non_empty_suites.rb81
-rw-r--r--qa/qa/tools/ci/qa_changes.rb51
2 files changed, 81 insertions, 51 deletions
diff --git a/qa/qa/tools/ci/non_empty_suites.rb b/qa/qa/tools/ci/non_empty_suites.rb
index 687c11a3e62..2319237fa25 100644
--- a/qa/qa/tools/ci/non_empty_suites.rb
+++ b/qa/qa/tools/ci/non_empty_suites.rb
@@ -10,42 +10,11 @@ module QA
class NonEmptySuites
include Helpers
- # rubocop:disable Layout/LineLength
- SCENARIOS = [
- { klass: "Test::Instance::All" },
- { klass: "Test::Instance::Smoke" },
- { klass: "Test::Instance::Reliable" },
- { klass: "Test::Instance::ReviewBlocking" },
- { klass: "Test::Instance::ReviewNonBlocking" },
- { klass: "Test::Instance::CloudActivation" },
- { klass: "Test::Instance::Integrations" },
- { klass: "Test::Instance::Jira" },
- { klass: "Test::Instance::LargeSetup" },
- { klass: "Test::Instance::Metrics" },
- { klass: "Test::Instance::ObjectStorage" },
- { klass: "Test::Instance::Packages" },
- { klass: "Test::Instance::RepositoryStorage" },
- { klass: "Test::Integration::ServicePingDisabled" },
- { klass: "Test::Integration::LDAPNoTLS" },
- { klass: "Test::Integration::LDAPTLS" },
- { klass: "Test::Integration::LDAPNoServer" },
- { klass: "Test::Integration::InstanceSAML" },
- { klass: "Test::Integration::RegistryWithCDN" },
- { klass: "Test::Integration::RegistryTLS" },
- { klass: "Test::Integration::Registry" },
- { klass: "Test::Integration::SMTP" },
- { klass: "QA::EE::Scenario::Test::Integration::Elasticsearch" },
- { klass: "QA::EE::Scenario::Test::Integration::GroupSAML" },
- {
- klass: "QA::EE::Scenario::Test::Geo",
- args: "--primary-address http://dummy1.test --primary-name gitlab-primary --secondary-address http://dummy2.test --secondary-name gitlab-secondary --without-setup"
- },
- {
- klass: "Test::Integration::Mattermost",
- args: "--mattermost-address http://mattermost.test"
- }
+ # @return [Array] scenarios that never run in package-and-test pipeline
+ IGNORED_SCENARIOS = [
+ "QA::EE::Scenario::Test::Geo",
+ "QA::Scenario::Test::Instance::Airgapped"
].freeze
- # rubocop:enable Layout/LineLength
def initialize(qa_tests)
@qa_tests = qa_tests
@@ -56,38 +25,58 @@ module QA
# @return [String]
def fetch
logger.info("Checking for runnable suites")
- scenarios = SCENARIOS.each_with_object([]) do |scenario, runnable_scenarios|
- logger.info(" fetching runnable specs for '#{scenario[:klass]}'")
+ 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)
+ out, err, status = run_command(scenario)
unless status.success?
- logger.error(" example count failed!\n#{err}")
+ 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[:klass] if count > 0
- end
-
- scenarios.join(",")
+ 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
- # @param [String] args
# @return [String]
- def run_command(klass:, args: nil)
+ def run_command(klass)
cmd = ["bundle exec bin/qa"]
cmd << klass
cmd << "--count-examples-only --address http://dummy1.test"
- cmd << args if args
cmd << "-- #{qa_tests}" unless qa_tests.blank?
Open3.capture3(cmd.join(" "))
diff --git a/qa/qa/tools/ci/qa_changes.rb b/qa/qa/tools/ci/qa_changes.rb
index 75274961efe..784923714d6 100644
--- a/qa/qa/tools/ci/qa_changes.rb
+++ b/qa/qa/tools/ci/qa_changes.rb
@@ -11,17 +11,25 @@ module QA
QA_PATTERN = %r{^qa/}.freeze
SPEC_PATTERN = %r{^qa/qa/specs/features/}.freeze
-
- def initialize(mr_diff, mr_labels)
+ DEPENDENCY_PATTERN = Regexp.union(
+ /_VERSION/,
+ /Gemfile\.lock/,
+ /yarn\.lock/,
+ /Dockerfile\.assets/
+ )
+
+ def initialize(mr_diff, mr_labels, additional_group_spec_list)
@mr_diff = mr_diff
@mr_labels = mr_labels
+ @additional_group_spec_list = additional_group_spec_list
end
# Specific specs to run
#
# @return [String]
def qa_tests
- return if mr_diff.empty?
+ return if mr_diff.empty? || dependency_changes
+
# make paths relative to qa directory
return changed_files&.map { |path| path.delete_prefix("qa/") }&.join(" ") if only_spec_changes?
return qa_spec_directories_for_devops_stage&.join(" ") if non_qa_changes? && mr_labels.any?
@@ -73,6 +81,9 @@ module QA
# @return [Array]
attr_reader :mr_labels
+ # @return [Hash<String, Array<String>>]
+ attr_reader :additional_group_spec_list
+
# Are the changed files only qa specs?
#
# @return [Boolean] whether the changes files are only qa specs
@@ -94,6 +105,13 @@ module QA
mr_labels.find { |label| label =~ /^devops::/ }&.delete_prefix('devops::')
end
+ # Extract group name from MR labels
+ #
+ # @return [String] a group name
+ def group_name_from_mr_labels
+ mr_labels.find { |label| label =~ /^group::/ }&.delete_prefix('group::')
+ end
+
# Get qa spec directories for devops stage
#
# @return [Array] qa spec directories
@@ -101,14 +119,37 @@ module QA
devops_stage = devops_stage_from_mr_labels
return unless devops_stage
- Dir.glob("qa/specs/**/*/").select { |dir| dir =~ %r{\d+_#{devops_stage}/$} }
+ spec_dirs = stage_specs(devops_stage)
+
+ grp_name = group_name_from_mr_labels
+ return spec_dirs if grp_name.nil?
+
+ additional_grp_specs = additional_group_spec_list[grp_name]
+ return spec_dirs if additional_grp_specs.nil?
+
+ spec_dirs + stage_specs(*additional_grp_specs)
+ end
+
+ # Changes to gitlab dependencies
+ #
+ # @return [Boolean]
+ def dependency_changes
+ changed_files.any? { |file| file.match?(DEPENDENCY_PATTERN) }
end
# Change files in merge request
#
# @return [Array<String>]
def changed_files
- @changed_files ||= mr_diff.map { |change| change[:path] } # rubocop:disable Rails/Pluck
+ @changed_files ||= mr_diff.map { |change| change[:path] }
+ end
+
+ # Devops stage specs
+ #
+ # @param [Array<String>] devops_stages
+ # @return [Array]
+ def stage_specs(*devops_stages)
+ Dir.glob("qa/specs/**/*/").select { |dir| dir =~ %r{\d+_(#{devops_stages.join('|')})/$} }
end
end
end