gitlab-qa 6.22.0 → 7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +32 -31
  3. data/docs/configuring_omnibus.md +208 -0
  4. data/docs/what_tests_can_be_run.md +46 -8
  5. data/gitlab-qa.gemspec +6 -4
  6. data/lib/gitlab/qa.rb +7 -0
  7. data/lib/gitlab/qa/component/base.rb +2 -2
  8. data/lib/gitlab/qa/component/elasticsearch.rb +1 -1
  9. data/lib/gitlab/qa/component/gitlab.rb +35 -24
  10. data/lib/gitlab/qa/component/internet_tunnel.rb +4 -1
  11. data/lib/gitlab/qa/component/jira.rb +1 -1
  12. data/lib/gitlab/qa/component/ldap.rb +1 -1
  13. data/lib/gitlab/qa/component/mail_hog.rb +1 -1
  14. data/lib/gitlab/qa/component/minio.rb +3 -11
  15. data/lib/gitlab/qa/component/postgresql.rb +1 -1
  16. data/lib/gitlab/qa/component/saml.rb +1 -1
  17. data/lib/gitlab/qa/component/specs.rb +10 -2
  18. data/lib/gitlab/qa/docker/engine.rb +37 -6
  19. data/lib/gitlab/qa/report/test_result.rb +5 -1
  20. data/lib/gitlab/qa/runner.rb +57 -5
  21. data/lib/gitlab/qa/runtime/env.rb +2 -0
  22. data/lib/gitlab/qa/runtime/omnibus_configuration.rb +70 -0
  23. data/lib/gitlab/qa/runtime/omnibus_configurations/default.rb +25 -0
  24. data/lib/gitlab/qa/runtime/omnibus_configurations/object_storage.rb +48 -0
  25. data/lib/gitlab/qa/runtime/omnibus_configurations/packages.rb +17 -0
  26. data/lib/gitlab/qa/scenario/cli_commands.rb +3 -3
  27. data/lib/gitlab/qa/scenario/test/instance/relative_url.rb +1 -3
  28. data/lib/gitlab/qa/scenario/test/instance/repository_storage.rb +1 -1
  29. data/lib/gitlab/qa/scenario/test/integration/actioncable.rb +1 -3
  30. data/lib/gitlab/qa/scenario/test/integration/geo.rb +4 -5
  31. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +4 -5
  32. data/lib/gitlab/qa/scenario/test/integration/group_saml.rb +1 -1
  33. data/lib/gitlab/qa/scenario/test/integration/instance_saml.rb +1 -1
  34. data/lib/gitlab/qa/scenario/test/integration/kubernetes.rb +1 -1
  35. data/lib/gitlab/qa/scenario/test/integration/ldap.rb +1 -4
  36. data/lib/gitlab/qa/scenario/test/integration/ldap_no_server.rb +1 -1
  37. data/lib/gitlab/qa/scenario/test/integration/ldap_no_tls.rb +1 -1
  38. data/lib/gitlab/qa/scenario/test/integration/ldap_tls.rb +1 -1
  39. data/lib/gitlab/qa/scenario/test/integration/mattermost.rb +1 -1
  40. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +2 -2
  41. data/lib/gitlab/qa/scenario/test/integration/smtp.rb +1 -1
  42. data/lib/gitlab/qa/scenario/test/integration/ssh_tunnel.rb +1 -1
  43. data/lib/gitlab/qa/version.rb +1 -1
  44. metadata +12 -9
  45. data/lib/gitlab/qa/scenario/test/integration/object_storage.rb +0 -64
  46. data/lib/gitlab/qa/scenario/test/integration/packages.rb +0 -36
@@ -101,10 +101,14 @@ module Gitlab
101
101
  {
102
102
  'message' => "#{exception['class']}: #{exception['message']}",
103
103
  'message_lines' => exception['message_lines'],
104
- 'stacktrace' => "#{exception['message_lines'].join("\n")}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
104
+ 'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
105
105
  }
106
106
  end
107
107
  end
108
+
109
+ def format_message_lines(message_lines)
110
+ message_lines.is_a?(Array) ? message_lines.join("\n") : message_lines
111
+ end
108
112
  # rubocop:enable Metrics/AbcSize
109
113
  end
110
114
 
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
4
+ require 'active_support/inflector'
2
5
 
3
6
  module Gitlab
4
7
  module QA
@@ -7,6 +10,12 @@ module Gitlab
7
10
  def self.run(args)
8
11
  Runtime::Scenario.define(:teardown, true)
9
12
  Runtime::Scenario.define(:run_tests, true)
13
+ Runtime::Scenario.define(:qa_image, Runtime::Env.qa_image) if Runtime::Env.qa_image
14
+ Runtime::Scenario.define(:omnibus_configuration, Runtime::OmnibusConfiguration.new)
15
+
16
+ # Omnibus Configurators specified by flags
17
+ @active_configurators = []
18
+ @omnibus_configurations = %w[default] # always load default configuration
10
19
 
11
20
  @options = OptionParser.new do |opts|
12
21
  opts.banner = 'Usage: gitlab-qa [options] Scenario URL [[--] path] [rspec_options]'
@@ -20,12 +29,22 @@ module Gitlab
20
29
  Runtime::Scenario.define(:teardown, false)
21
30
  end
22
31
 
32
+ opts.on('--qa-image QA_IMAGE', String, 'Specifies a QA image to be used instead of inferring it from the GitLab image. See Gitlab::QA::Release#qa_image') do |value|
33
+ Runtime::Scenario.define(:qa_image, value)
34
+ end
35
+
23
36
  opts.on_tail('-v', '--version', 'Show the version') do
24
37
  require 'gitlab/qa/version'
25
38
  puts "#{$PROGRAM_NAME} : #{VERSION}"
26
39
  exit
27
40
  end
28
41
 
42
+ opts.on('--omnibus-config config1[,config2,...]', 'Use Omnibus Configuration package') do |configuration|
43
+ configuration.split(',').map do |config|
44
+ @omnibus_configurations << config
45
+ end
46
+ end
47
+
29
48
  opts.on_tail('-h', '--help', 'Show the usage') do
30
49
  puts opts
31
50
  exit
@@ -39,21 +58,54 @@ module Gitlab
39
58
  end
40
59
 
41
60
  args.reject! { |arg| gitlab_qa_options.include?(arg) }
42
-
43
61
  if args.size >= 1
44
- Scenario
45
- .const_get(args.shift)
46
- .perform(*args)
62
+ load_omnibus_configurations
63
+
64
+ begin
65
+ @active_configurators.compact.each do |configurator|
66
+ configurator.instance(skip_teardown: true)
67
+ end
68
+
69
+ Scenario
70
+ .const_get(args.shift)
71
+ .perform(*args)
72
+ ensure
73
+ @active_configurators.compact.each(&:teardown)
74
+ end
47
75
  else
48
76
  puts @options
49
77
  exit 1
50
78
  end
51
79
  end
52
- # rubocop:enable Metrics/AbcSize
53
80
 
54
81
  def self.gitlab_qa_options
55
82
  @gitlab_qa_options ||= @options.top.list.map(&:long).flatten
56
83
  end
84
+
85
+ def self.load_omnibus_configurations
86
+ # OmnibusConfiguration::Test => --test
87
+ # OmnibusConfiguration::HelloThere => --hello_there
88
+ @omnibus_configurations.uniq.each do |config|
89
+ Runtime::OmnibusConfigurations.const_get(config.camelize).new.tap do |configurator|
90
+ @active_configurators << configurator.prepare
91
+
92
+ # */etc/gitlab/gitlab.rb*
93
+ # -----------------------
94
+ # # Runtime::OmnibusConfiguration::Packages
95
+ # gitlab_rails['packages_enabled'] = true
96
+ Runtime::Scenario.omnibus_configuration << "# #{configurator.class.name}"
97
+
98
+ # Load the configuration
99
+ configurator.configuration.split("\n").each { |c| Runtime::Scenario.omnibus_configuration << c }
100
+ end
101
+ rescue NameError
102
+ raise <<~ERROR
103
+ Invalid Omnibus Configuration `#{config}`.
104
+ Possible configurations: #{Runtime::OmnibusConfigurations.constants.map { |c| c.to_s.underscore }.join(',')}"
105
+ ERROR
106
+ end
107
+ end
57
108
  end
109
+ # rubocop:enable Metrics/AbcSize
58
110
  end
59
111
  end
@@ -10,6 +10,7 @@ module Gitlab
10
10
  # These variables should be listed in /docs/what_tests_can_be_run.md#supported-gitlab-environment-variables
11
11
  # unless they're defined elsewhere (e.g.: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
12
12
  ENV_VARIABLES = {
13
+ 'QA_IMAGE' => :qa_image,
13
14
  'QA_REMOTE_GRID' => :remote_grid,
14
15
  'QA_REMOTE_GRID_USERNAME' => :remote_grid_username,
15
16
  'QA_REMOTE_GRID_ACCESS_KEY' => :remote_grid_access_key,
@@ -64,6 +65,7 @@ module Gitlab
64
65
  'KNAPSACK_TEST_FILE_PATTERN' => :knapsack_test_file_pattern,
65
66
  'KNAPSACK_TEST_DIR' => :knapsack_test_dir,
66
67
  'CI' => :ci,
68
+ 'CI_JOB_NAME' => :ci_job_name,
67
69
  'CI_JOB_URL' => :ci_job_url,
68
70
  'CI_RUNNER_ID' => :ci_runner_id,
69
71
  'CI_SERVER_HOST' => :ci_server_host,
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+
5
+ module Gitlab
6
+ module QA
7
+ module Runtime
8
+ class OmnibusConfiguration
9
+ def initialize
10
+ @config = ["# Generated by GitLab QA Omnibus Configurator at #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"]
11
+ end
12
+
13
+ def to_s
14
+ sanitize!.join("\n")
15
+ end
16
+
17
+ def configuration
18
+ raise NotImplementedError
19
+ end
20
+
21
+ # Before hook for any additional configuration
22
+ # This would usually be a container that needs to be running
23
+ # @return Any instance of [Gitlab::QA::Component::Base]
24
+ def prepare; end
25
+
26
+ # Commands to execute before GitLab boots
27
+ def exec_commands
28
+ []
29
+ end
30
+
31
+ # Ensures no duplicate entries
32
+ # @raise RuntimeError if competing configurations exist
33
+ # rubocop:disable Metrics/AbcSize
34
+ def sanitize!
35
+ sanitized = @config.map do |config|
36
+ next config if config.start_with?('#') || config.match(/\w+\(/) # allow for comments and method invocations
37
+
38
+ # sometimes "=" is part of a Hash. Only split based on the first "="
39
+ k, v = config.split("=", 2)
40
+ # make sure each config is well-formed
41
+ # e.g., gitlab_rails['packages_enabled'] = true
42
+ # NOT gitlab_rails['packages_enabled']=true
43
+
44
+ v.nil? ? k.strip : "#{k.strip} = #{v.strip.tr('"', "'")}".strip
45
+ end.uniq
46
+
47
+ errors = []
48
+
49
+ # check for duplicates
50
+ duplicate_keys = []
51
+ duplicates = sanitized.reject do |n|
52
+ key = n.split('=').first
53
+ duplicate_keys << key unless duplicate_keys.include?(key)
54
+ end
55
+
56
+ duplicates.each { |duplicate| errors << "Duplicate entry found: `#{duplicate}`" }
57
+
58
+ raise "Errors exist within the Omnibus Configuration!\n#{errors.join(',')}" if errors.any?
59
+
60
+ @config = sanitized
61
+ end
62
+ # rubocop:enable Metrics/AbcSize
63
+
64
+ def <<(config)
65
+ @config << config.strip unless config.strip.empty?
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Runtime
6
+ module OmnibusConfigurations
7
+ # Default Configuration for Omnibus
8
+ # All runs will include this configuration
9
+ class Default < Runtime::OmnibusConfiguration
10
+ def configuration
11
+ <<~OMNIBUS
12
+ gitlab_rails['gitlab_default_theme'] = 10 # Light Red Theme
13
+ gitlab_rails['gitlab_disable_animations'] = true # Disable animations
14
+ gitlab_rails['application_settings_cache_seconds'] = 0 # Settings cache expiry
15
+ OMNIBUS
16
+ end
17
+
18
+ def self.configuration
19
+ new.configuration
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Runtime
6
+ module OmnibusConfigurations
7
+ class ObjectStorage < Default
8
+ TYPES = %w[artifacts external_diffs lfs uploads packages dependency_proxy].freeze
9
+
10
+ def configuration
11
+ TYPES.each_with_object(+'') do |object_type, omnibus|
12
+ omnibus << <<~OMNIBUS
13
+ gitlab_rails['#{object_type}_enabled'] = true
14
+ gitlab_rails['#{object_type}_storage_path'] = '/var/opt/gitlab/gitlab-rails/shared/#{object_type}'
15
+ gitlab_rails['#{object_type}_object_store_enabled'] = true
16
+ gitlab_rails['#{object_type}_object_store_remote_directory'] = '#{object_type}-bucket'
17
+ gitlab_rails['#{object_type}_object_store_background_upload'] = false
18
+ gitlab_rails['#{object_type}_object_store_direct_upload'] = true
19
+ gitlab_rails['#{object_type}_object_store_proxy_download'] = true
20
+ gitlab_rails['#{object_type}_object_store_connection'] = #{minio.to_config}
21
+ OMNIBUS
22
+ end
23
+ end
24
+
25
+ def prepare
26
+ minio.network = 'test'
27
+
28
+ TYPES.each do |bucket_name|
29
+ minio.add_bucket("#{bucket_name}-bucket")
30
+ end
31
+
32
+ minio
33
+ end
34
+
35
+ def exec_commands
36
+ QA::Scenario::CLICommands.git_lfs_install_commands
37
+ end
38
+
39
+ private
40
+
41
+ def minio
42
+ @minio ||= Component::Minio.new
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Runtime
6
+ module OmnibusConfigurations
7
+ class Packages < Default
8
+ def configuration
9
+ <<~OMNIBUS
10
+ gitlab_rails['packages_enabled'] = true
11
+ OMNIBUS
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -4,11 +4,11 @@ module Gitlab
4
4
  module CLICommands
5
5
  GIT_LFS_VERSION = '2.8.0'.freeze
6
6
 
7
- def git_lfs_install_commands
8
- @git_lfs_install_commands ||= [
7
+ def self.git_lfs_install_commands
8
+ [
9
9
  "cd /tmp ; curl -qsL https://github.com/git-lfs/git-lfs/releases/download/v#{GIT_LFS_VERSION}/git-lfs-linux-amd64-v#{GIT_LFS_VERSION}.tar.gz | tar xzvf -",
10
10
  'cp /tmp/git-lfs /usr/local/bin'
11
- ]
11
+ ].freeze
12
12
  end
13
13
  end
14
14
  end
@@ -10,9 +10,7 @@ module Gitlab
10
10
  gitlab.network = 'test'
11
11
  gitlab.relative_path = '/relative'
12
12
 
13
- gitlab.omnibus_config = <<~OMNIBUS
14
- external_url '#{gitlab.address}';
15
- OMNIBUS
13
+ gitlab.omnibus_configuration << "external_url '#{gitlab.address}'"
16
14
 
17
15
  gitlab.instance do
18
16
  Component::Specs.perform do |specs|
@@ -9,7 +9,7 @@ module Gitlab
9
9
  gitlab.release = QA::Release.new(release)
10
10
  gitlab.name = 'gitlab'
11
11
  gitlab.network = 'test'
12
- gitlab.omnibus_config = <<~OMNIBUS
12
+ gitlab.omnibus_configuration << <<~OMNIBUS
13
13
  git_data_dirs({
14
14
  'default' => {
15
15
  'path' => '/var/opt/gitlab/git-data/repositories/default'
@@ -9,9 +9,7 @@ module Gitlab
9
9
  gitlab.release = QA::Release.new(release)
10
10
  gitlab.name = 'gitlab-actioncable'
11
11
  gitlab.network = 'test'
12
- gitlab.omnibus_config = <<~OMNIBUS
13
- actioncable['enable'] = true;
14
- OMNIBUS
12
+ gitlab.omnibus_configuration << "actioncable['enable'] = true"
15
13
 
16
14
  gitlab.instance do
17
15
  puts "Running actioncable specs!"
@@ -4,7 +4,6 @@ module Gitlab
4
4
  module Test
5
5
  module Integration
6
6
  class Geo < Scenario::Template
7
- include Scenario::CLICommands
8
7
  ##
9
8
  # rubocop:disable Lint/MissingCopEnableDirective
10
9
  # rubocop:disable Metrics/AbcSize
@@ -20,7 +19,7 @@ module Gitlab
20
19
  primary.release = release
21
20
  primary.name = 'gitlab-primary'
22
21
  primary.network = 'geo'
23
- primary.omnibus_config = <<~OMNIBUS
22
+ primary.omnibus_configuration << <<~OMNIBUS
24
23
  gitlab_rails['db_key_base'] = '4dd58204865eb41bca93bd38131d51cc';
25
24
  geo_primary_role['enable'] = true;
26
25
  gitlab_rails['db_password'] = 'mypass';
@@ -36,14 +35,14 @@ module Gitlab
36
35
  sidekiq['concurrency'] = 2;
37
36
  puma['worker_processes'] = 2;
38
37
  OMNIBUS
39
- primary.exec_commands = fast_ssh_key_lookup_commands + git_lfs_install_commands
38
+ primary.exec_commands = fast_ssh_key_lookup_commands + QA::Scenario::CLICommands.git_lfs_install_commands
40
39
 
41
40
  primary.instance do
42
41
  Component::Gitlab.perform do |secondary|
43
42
  secondary.release = release
44
43
  secondary.name = 'gitlab-secondary'
45
44
  secondary.network = 'geo'
46
- secondary.omnibus_config = <<~OMNIBUS
45
+ secondary.omnibus_configuration << <<~OMNIBUS
47
46
  geo_secondary['db_fdw'] = true;
48
47
  geo_secondary_role['enable'] = true;
49
48
  gitlab_rails['db_key_base'] = '4dd58204865eb41bca93bd38131d51cc';
@@ -58,7 +57,7 @@ module Gitlab
58
57
  sidekiq['concurrency'] = 2;
59
58
  puma['worker_processes'] = 2;
60
59
  OMNIBUS
61
- secondary.exec_commands = fast_ssh_key_lookup_commands + git_lfs_install_commands
60
+ secondary.exec_commands = fast_ssh_key_lookup_commands + QA::Scenario::CLICommands.git_lfs_install_commands
62
61
 
63
62
  secondary.act do
64
63
  # TODO, we do not wait for secondary to start because of
@@ -39,7 +39,7 @@ module Gitlab
39
39
  praefect.network = @network
40
40
  praefect.skip_availability_check = true
41
41
 
42
- praefect.omnibus_config = praefect_omnibus_configuration
42
+ praefect.omnibus_configuration << praefect_omnibus_configuration
43
43
 
44
44
  praefect.instance(skip_teardown: true)
45
45
  end
@@ -49,7 +49,7 @@ module Gitlab
49
49
  gitlab.name = gitlab_name
50
50
  gitlab.network = @network
51
51
 
52
- gitlab.omnibus_config = gitlab_omnibus_configuration
52
+ gitlab.omnibus_configuration << gitlab_omnibus_configuration
53
53
  gitlab.instance do
54
54
  puts "Running Gitaly Cluster specs!"
55
55
 
@@ -131,8 +131,7 @@ module Gitlab
131
131
 
132
132
  def gitaly_omnibus_configuration
133
133
  <<~OMNIBUS
134
- #{disable_other_services}
135
- prometheus['enable'] = true;
134
+ #{disable_other_services.sub(/(prometheus\['enable'\]) = false/, '\1 = true')}
136
135
  prometheus_monitoring['enable'] = false;
137
136
  gitaly['enable'] = true;
138
137
  gitaly['listen_addr'] = '0.0.0.0:8075';
@@ -197,7 +196,7 @@ module Gitlab
197
196
  gitaly.name = name
198
197
  gitaly.network = @network
199
198
  gitaly.skip_availability_check = true
200
- gitaly.omnibus_config = gitaly_omnibus_configuration
199
+ gitaly.omnibus_configuration << gitaly_omnibus_configuration
201
200
  gitaly.instance(skip_teardown: true)
202
201
  end
203
202
  end
@@ -17,7 +17,7 @@ module Gitlab
17
17
  end
18
18
 
19
19
  def configure(gitlab, saml)
20
- gitlab.omnibus_config = <<~OMNIBUS
20
+ gitlab.omnibus_configuration << <<~OMNIBUS
21
21
  gitlab_rails['omniauth_enabled'] = true;
22
22
  gitlab_rails['omniauth_providers'] = [{ name: 'group_saml' }];
23
23
  OMNIBUS
@@ -17,7 +17,7 @@ module Gitlab
17
17
  saml.set_assertion_consumer_service("#{gitlab.address}/users/auth/saml/callback")
18
18
  saml.set_simple_saml_hostname
19
19
 
20
- gitlab.omnibus_config = <<~OMNIBUS
20
+ gitlab.omnibus_configuration << <<~OMNIBUS
21
21
  gitlab_rails['omniauth_enabled'] = true;
22
22
  gitlab_rails['omniauth_allow_single_sign_on'] = ['saml'];
23
23
  gitlab_rails['omniauth_block_auto_created_users'] = false;