gitlab-qa 10.3.0 → 12.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.gitlab/changelog_config.yml +13 -0
  4. data/.gitlab/merge_request_templates/Release.md +13 -34
  5. data/.gitlab-ci.yml +3 -1
  6. data/.rubocop.yml +13 -2
  7. data/.rubocop_todo.yml +57 -97
  8. data/Dangerfile +1 -5
  9. data/Gemfile.lock +47 -39
  10. data/README.md +1 -2
  11. data/docs/release_process.md +1 -1
  12. data/docs/running_against_remote_grid.md +42 -3
  13. data/docs/what_tests_can_be_run.md +5 -2
  14. data/gitlab-qa.gemspec +5 -3
  15. data/lib/gitlab/qa/component/base.rb +9 -9
  16. data/lib/gitlab/qa/component/gitaly.rb +7 -5
  17. data/lib/gitlab/qa/component/gitaly_cluster.rb +15 -9
  18. data/lib/gitlab/qa/component/gitlab.rb +48 -21
  19. data/lib/gitlab/qa/component/mail_hog.rb +1 -0
  20. data/lib/gitlab/qa/component/praefect.rb +41 -31
  21. data/lib/gitlab/qa/component/selenoid.rb +14 -7
  22. data/lib/gitlab/qa/component/specs.rb +11 -5
  23. data/lib/gitlab/qa/component/staging.rb +4 -4
  24. data/lib/gitlab/qa/component/telegraf.rb +2 -1
  25. data/lib/gitlab/qa/docker/engine.rb +6 -3
  26. data/lib/gitlab/qa/docker/volumes.rb +1 -1
  27. data/lib/gitlab/qa/release.rb +4 -4
  28. data/lib/gitlab/qa/runner.rb +10 -3
  29. data/lib/gitlab/qa/runtime/env.rb +47 -62
  30. data/lib/gitlab/qa/runtime/logger.rb +1 -1
  31. data/lib/gitlab/qa/runtime/omnibus_configuration.rb +1 -0
  32. data/lib/gitlab/qa/runtime/omnibus_configurations/decomposition_single_db.rb +1 -2
  33. data/lib/gitlab/qa/runtime/omnibus_configurations/object_storage_gcs.rb +2 -1
  34. data/lib/gitlab/qa/runtime/scenario.rb +1 -5
  35. data/lib/gitlab/qa/scenario/actable.rb +4 -4
  36. data/lib/gitlab/qa/scenario/test/instance/airgapped.rb +2 -4
  37. data/lib/gitlab/qa/scenario/test/instance/deployment_base.rb +2 -1
  38. data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +0 -2
  39. data/lib/gitlab/qa/scenario/test/integration/group_saml.rb +1 -1
  40. data/lib/gitlab/qa/scenario/test/integration/ldap.rb +5 -6
  41. data/lib/gitlab/qa/scenario/test/integration/mtls.rb +20 -6
  42. data/lib/gitlab/qa/scenario/test/integration/oauth.rb +13 -4
  43. data/lib/gitlab/qa/scenario/test/integration/praefect.rb +16 -10
  44. data/lib/gitlab/qa/scenario/test/integration/registry_with_cdn.rb +5 -2
  45. data/lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb +1 -1
  46. data/lib/gitlab/qa/scenario/test/omnibus/upgrade.rb +1 -3
  47. data/lib/gitlab/qa/scenario/test/sanity/version.rb +1 -1
  48. data/lib/gitlab/qa/support/config_scripts.rb +1 -1
  49. data/lib/gitlab/qa/support/gitlab_version_info.rb +30 -10
  50. data/lib/gitlab/qa/support/shell_command.rb +1 -0
  51. data/lib/gitlab/qa/test_logger.rb +2 -2
  52. data/lib/gitlab/qa/version.rb +1 -1
  53. data/lib/gitlab/qa.rb +0 -1
  54. data/support/data/admin_access_token_seed.rb +5 -1
  55. data/support/data/license_usage_seed.rb +3 -1
  56. metadata +16 -45
  57. data/bin/slack +0 -14
  58. data/exe/gitlab-qa-report +0 -10
  59. data/lib/gitlab/qa/report/base_test_results.rb +0 -39
  60. data/lib/gitlab/qa/report/find_set_dri.rb +0 -43
  61. data/lib/gitlab/qa/report/generate_test_session.rb +0 -275
  62. data/lib/gitlab/qa/report/gitlab_issue_client.rb +0 -190
  63. data/lib/gitlab/qa/report/gitlab_issue_dry_client.rb +0 -28
  64. data/lib/gitlab/qa/report/j_unit_test_results.rb +0 -27
  65. data/lib/gitlab/qa/report/json_test_results.rb +0 -29
  66. data/lib/gitlab/qa/report/prepare_stage_reports.rb +0 -86
  67. data/lib/gitlab/qa/report/relate_failure_issue.rb +0 -374
  68. data/lib/gitlab/qa/report/report_as_issue.rb +0 -176
  69. data/lib/gitlab/qa/report/report_results.rb +0 -64
  70. data/lib/gitlab/qa/report/results_in_issues.rb +0 -126
  71. data/lib/gitlab/qa/report/results_in_testcases.rb +0 -111
  72. data/lib/gitlab/qa/report/results_reporter_shared.rb +0 -70
  73. data/lib/gitlab/qa/report/summary_table.rb +0 -43
  74. data/lib/gitlab/qa/report/test_result.rb +0 -184
  75. data/lib/gitlab/qa/report/update_screenshot_path.rb +0 -63
  76. data/lib/gitlab/qa/reporter.rb +0 -131
  77. data/lib/gitlab/qa/runtime/omnibus_configurations/packages.rb +0 -17
  78. data/lib/gitlab/qa/runtime/token_finder.rb +0 -44
  79. data/lib/gitlab/qa/slack/post_to_slack.rb +0 -30
  80. data/lib/gitlab/qa/system_logs/finders/json_log_finder.rb +0 -65
  81. data/lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb +0 -21
  82. data/lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb +0 -21
  83. data/lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb +0 -21
  84. data/lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb +0 -21
  85. data/lib/gitlab/qa/system_logs/log_types/log.rb +0 -38
  86. data/lib/gitlab/qa/system_logs/log_types/rails/api_log.rb +0 -34
  87. data/lib/gitlab/qa/system_logs/log_types/rails/application_log.rb +0 -27
  88. data/lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb +0 -23
  89. data/lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb +0 -30
  90. data/lib/gitlab/qa/system_logs/shared_fields.rb +0 -29
  91. data/lib/gitlab/qa/system_logs/system_logs_formatter.rb +0 -65
data/gitlab-qa.gemspec CHANGED
@@ -10,6 +10,8 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['GitLab Quality']
11
11
  spec.email = ['gitlab-qa@gmail.com']
12
12
 
13
+ spec.required_ruby_version = ">= 3.0.0"
14
+
13
15
  spec.summary = 'Integration tests for GitLab'
14
16
  spec.homepage = 'http://about.gitlab.com/'
15
17
  spec.license = 'MIT'
@@ -22,7 +24,7 @@ Gem::Specification.new do |spec|
22
24
 
23
25
  spec.add_development_dependency 'climate_control', '~> 1.0.1'
24
26
  spec.add_development_dependency 'gitlab-dangerfiles', '~> 2.11'
25
- spec.add_development_dependency 'gitlab-styles', '~> 6.2.1'
27
+ spec.add_development_dependency 'gitlab-styles', '~> 10'
26
28
  spec.add_development_dependency 'lefthook', '~> 1.2.6'
27
29
  spec.add_development_dependency 'pry', '~> 0.11'
28
30
  spec.add_development_dependency 'rake', '~> 13.0'
@@ -33,8 +35,8 @@ Gem::Specification.new do |spec|
33
35
  spec.add_development_dependency 'timecop', '~> 0.9.5'
34
36
  spec.add_development_dependency 'webmock', '3.7.0'
35
37
 
36
- spec.add_runtime_dependency 'activesupport', '~> 6.1'
37
- spec.add_runtime_dependency 'gitlab', '~> 4.18.0'
38
+ spec.add_runtime_dependency 'activesupport', '>= 6.1', '< 7.1'
39
+ spec.add_runtime_dependency 'gitlab', '~> 4.19'
38
40
  spec.add_runtime_dependency 'http', '~> 5.0'
39
41
  spec.add_runtime_dependency 'nokogiri', '~> 1.10'
40
42
  spec.add_runtime_dependency 'parallel', '>= 1', '< 2'
@@ -11,13 +11,13 @@ module Gitlab
11
11
  attr_reader :docker
12
12
  attr_writer :name, :exec_commands
13
13
  attr_accessor :volumes,
14
- :ports,
15
- :network,
16
- :network_aliases,
17
- :environment,
18
- :runner_network,
19
- :airgapped_network,
20
- :additional_hosts
14
+ :ports,
15
+ :network,
16
+ :network_aliases,
17
+ :environment,
18
+ :runner_network,
19
+ :airgapped_network,
20
+ :additional_hosts
21
21
 
22
22
  def initialize
23
23
  @docker = Docker::Engine.new
@@ -42,13 +42,13 @@ module Gitlab
42
42
  end
43
43
 
44
44
  def image
45
- return self.class.const_get('DOCKER_IMAGE') if self.class.const_defined?('DOCKER_IMAGE')
45
+ return self.class.const_get(:DOCKER_IMAGE) if self.class.const_defined?(:DOCKER_IMAGE)
46
46
 
47
47
  raise NotImplementedError, "#{self.class.name} must specify a docker image as DOCKER_IMAGE"
48
48
  end
49
49
 
50
50
  def tag
51
- return self.class.const_get('DOCKER_IMAGE_TAG') if self.class.const_defined?('DOCKER_IMAGE_TAG')
51
+ return self.class.const_get(:DOCKER_IMAGE_TAG) if self.class.const_defined?(:DOCKER_IMAGE_TAG)
52
52
 
53
53
  raise NotImplementedError, "#{self.class.name} must specify a docker image tag as DOCKER_IMAGE_TAG"
54
54
  end
@@ -36,9 +36,9 @@ module Gitlab
36
36
 
37
37
  def reconfigure
38
38
  setup_omnibus
39
- @docker.attach(name) do |line, wait|
39
+ @docker.attach(name) do |line, _wait|
40
40
  # TODO, workaround which allows to detach from the container
41
- break if /gitlab Reconfigured!/.match?(line)
41
+ break if line.include?('gitlab Reconfigured!')
42
42
  end
43
43
  end
44
44
 
@@ -64,9 +64,11 @@ module Gitlab
64
64
  praefect['enable'] = false;
65
65
  prometheus['enable'] = true;
66
66
  gitaly['enable'] = true;
67
- gitaly['listen_addr'] = '0.0.0.0:#{gitaly_port}';
68
- gitaly['prometheus_listen_addr'] = '0.0.0.0:9236';
69
- gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN';
67
+ gitaly['configuration'] = {
68
+ 'listen_addr': '0.0.0.0:#{gitaly_port}',
69
+ 'prometheus_listen_addr': '0.0.0.0:9236',
70
+ 'auth_token': 'PRAEFECT_INTERNAL_TOKEN'
71
+ }
70
72
  gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
71
73
  gitlab_rails['internal_api_url'] = 'http://#{cluster_config.gitlab_name}.#{cluster_config.network}';
72
74
  git_data_dirs({
@@ -6,11 +6,11 @@ module Gitlab
6
6
  class GitalyCluster
7
7
  class GitalyClusterConfig
8
8
  attr_accessor :gitlab_name, :network, :airgapped_network,
9
- :praefect_node_name, :praefect_port, :praefect_ip,
10
- :primary_node_name, :primary_node_port,
11
- :secondary_node_name, :secondary_node_port,
12
- :tertiary_node_name, :tertiary_node_port,
13
- :database_node_name, :database_port
9
+ :praefect_node_name, :praefect_port, :praefect_ip,
10
+ :primary_node_name, :primary_node_port,
11
+ :secondary_node_name, :secondary_node_port,
12
+ :tertiary_node_name, :tertiary_node_port,
13
+ :database_node_name, :database_port
14
14
 
15
15
  attr_reader :praefect_addr, :primary_node_addr, :secondary_node_addr, :tertiary_node_addr, :database_node_addr
16
16
 
@@ -79,9 +79,15 @@ module Gitlab
79
79
 
80
80
  if parallel_gitaly
81
81
  threads = []
82
- threads << Thread.new { @gitaly_primary_node = gitaly(config.primary_node_name, config.primary_node_port, release) }
83
- threads << Thread.new { @gitaly_secondary_node = gitaly(config.secondary_node_name, config.secondary_node_port, release) }
84
- threads << Thread.new { @gitaly_tertiary_node = gitaly(config.tertiary_node_name, config.tertiary_node_port, release) }
82
+ threads << Thread.new do
83
+ @gitaly_primary_node = gitaly(config.primary_node_name, config.primary_node_port, release)
84
+ end
85
+ threads << Thread.new do
86
+ @gitaly_secondary_node = gitaly(config.secondary_node_name, config.secondary_node_port, release)
87
+ end
88
+ threads << Thread.new do
89
+ @gitaly_tertiary_node = gitaly(config.tertiary_node_name, config.tertiary_node_port, release)
90
+ end
85
91
  threads.each(&:join)
86
92
  else
87
93
  @gitaly_primary_node = gitaly(config.primary_node_name, config.primary_node_port, release)
@@ -135,13 +141,13 @@ module Gitlab
135
141
  postgresql['enable'] = false;
136
142
  redis['enable'] = false;
137
143
  nginx['enable'] = false;
138
- grafana['enable'] = false;
139
144
  puma['enable'] = false;
140
145
  sidekiq['enable'] = false;
141
146
  gitlab_workhorse['enable'] = false;
142
147
  gitlab_rails['rake_cache_clear'] = false;
143
148
  gitlab_rails['auto_migrate'] = false;
144
149
  gitlab_exporter['enable'] = false;
150
+ gitlab_kas['enable'] = false;
145
151
  OMNIBUS
146
152
  end
147
153
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # rubocop:disable Metrics/AbcSize
3
4
 
4
5
  require 'securerandom'
@@ -17,19 +18,19 @@ module Gitlab
17
18
  using Rainbow
18
19
 
19
20
  attr_reader :release,
20
- :omnibus_configuration,
21
- :omnibus_gitlab_rails_env,
22
- :authority_volume,
23
- :ssl_volume
21
+ :omnibus_configuration,
22
+ :omnibus_gitlab_rails_env,
23
+ :authority_volume,
24
+ :ssl_volume
24
25
 
25
26
  attr_accessor :tls,
26
- :skip_availability_check,
27
- :runner_network,
28
- :seed_admin_token,
29
- :seed_db,
30
- :skip_server_hooks,
31
- :gitaly_tls,
32
- :secrets
27
+ :skip_availability_check,
28
+ :runner_network,
29
+ :seed_admin_token,
30
+ :seed_db,
31
+ :skip_server_hooks,
32
+ :gitaly_tls,
33
+ :secrets
33
34
 
34
35
  attr_writer :name, :relative_path
35
36
 
@@ -182,9 +183,9 @@ module Gitlab
182
183
  def reconfigure
183
184
  setup_omnibus
184
185
 
185
- @docker.attach(name) do |line, wait|
186
+ @docker.attach(name) do |line, _wait|
186
187
  # TODO, workaround which allows to detach from the container
187
- break if /gitlab Reconfigured!/.match?(line)
188
+ break if line.include?('gitlab Reconfigured!')
188
189
  end
189
190
  end
190
191
 
@@ -235,17 +236,30 @@ module Gitlab
235
236
  manifest['software']['package-scripts']['locked_version']
236
237
  end
237
238
 
238
- def copy_key_file(env_key)
239
- key_dir = ENV['CI_PROJECT_DIR'] || Dir.tmpdir
240
- key_file = Tempfile.new(env_key.downcase, key_dir)
241
- key_file.write(ENV.fetch(env_key))
242
- key_file.close
239
+ def create_key_file(env_key)
240
+ directory = ENV['CI_PROJECT_DIR'] || Dir.tmpdir
241
+ unique_filename = "#{env_key.downcase}_#{Time.now.to_i}_#{rand(100)}"
242
+ key_file_path = File.join(directory, unique_filename)
243
+
244
+ File.open(key_file_path, 'w') do |file|
245
+ file.write(ENV.fetch(env_key))
246
+ file.fsync
247
+ end
243
248
 
244
- File.chmod(0o744, key_file.path)
249
+ File.chmod(0o744, key_file_path)
250
+ @volumes[key_file_path] = key_file_path
245
251
 
246
- @volumes[key_file.path] = key_file.path
252
+ key_file_path
253
+ end
247
254
 
248
- key_file.path
255
+ def delete_key_file(path)
256
+ FileUtils.rm_f(path)
257
+ end
258
+
259
+ def teardown!
260
+ log_pg_stats
261
+
262
+ super
249
263
  end
250
264
 
251
265
  private
@@ -300,6 +314,19 @@ module Gitlab
300
314
  ["gitlab-rails runner #{DATA_PATH}/admin_access_token_seed.rb"]
301
315
  end
302
316
 
317
+ def log_pg_stats
318
+ Runtime::Logger.debug('Fetching pg statistics')
319
+ File.open("#{Runtime::Env.host_artifacts_dir}/pg_stats.log", 'a') do |file|
320
+ file << "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} -- #{name} -- Postgres statistics after test run:\n"
321
+ file << "Live and dead row counts:\n"
322
+ file << @docker.exec(name, %(gitlab-psql -c 'select n_live_tup, n_dead_tup, relname from pg_stat_all_tables order by n_live_tup DESC, n_dead_tup DESC;'))
323
+ file << "Cumulative user table statistics:\n"
324
+ file << @docker.exec(name, %(gitlab-psql -c 'select * from pg_stat_user_tables;'))
325
+ end
326
+ rescue StandardError => e
327
+ Runtime::Logger.error("Error getting pg statistics: #{e}")
328
+ end
329
+
303
330
  class Availability
304
331
  def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
305
332
  @docker = Docker::Engine.new
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # This component sets up the MailHog (https://github.com/mailhog/MailHog)
3
4
  # image with the proper configuration for SMTP email delivery from Gitlab
4
5
 
@@ -37,7 +37,7 @@ module Gitlab
37
37
  setup_omnibus
38
38
  @docker.attach(name) do |line|
39
39
  # TODO, workaround which allows to detach from the container
40
- break if /gitlab Reconfigured!/.match?(line)
40
+ break if line.include?('gitlab Reconfigured!')
41
41
  end
42
42
  end
43
43
 
@@ -50,7 +50,7 @@ module Gitlab
50
50
  def wait_until_ready
51
51
  @docker.exec(name, 'praefect -config /var/opt/gitlab/praefect/cluster_config.toml check || true') do |resp|
52
52
  Runtime::Logger.info(resp)
53
- break if /All checks passed/.match?(line)
53
+ break if line.include?('All checks passed')
54
54
  end
55
55
  end
56
56
 
@@ -60,36 +60,46 @@ module Gitlab
60
60
  gitaly['enable'] = false;
61
61
  prometheus['enable'] = true;
62
62
  praefect['enable'] = true;
63
- praefect['listen_addr'] = '0.0.0.0:#{cluster_config.praefect_port}';
64
- praefect['prometheus_listen_addr'] = '0.0.0.0:9652';
65
- praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN';
66
- praefect['reconciliation_scheduling_interval'] = '10s';
67
- praefect['database_host'] = '#{cluster_config.database_node_addr}';
68
- praefect['database_user'] = 'postgres';
69
- praefect['database_port'] = #{cluster_config.database_port};
70
- praefect['database_password'] = 'SQL_PASSWORD';
71
- praefect['database_dbname'] = 'praefect_production';
72
- praefect['database_sslmode'] = 'disable';
73
- praefect['database_direct_host'] = '#{cluster_config.database_node_addr}';
74
- praefect['database_direct_port'] = #{cluster_config.database_port};
75
- praefect['virtual_storages'] = {
76
- 'default' => {
77
- 'nodes' => {
78
- '#{cluster_config.primary_node_name}' => {
79
- 'address' => 'tcp://#{cluster_config.primary_node_addr}:#{cluster_config.primary_node_port}',
80
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
81
- },
82
- '#{cluster_config.secondary_node_name}' => {
83
- 'address' => 'tcp://#{cluster_config.secondary_node_addr}:#{cluster_config.secondary_node_port}',
84
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
85
- },
86
- '#{cluster_config.tertiary_node_name}' => {
87
- 'address' => 'tcp://#{cluster_config.tertiary_node_addr}:#{cluster_config.tertiary_node_port}',
88
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
89
- }
63
+ praefect['configuration'] = {
64
+ listen_addr: '0.0.0.0:#{cluster_config.praefect_port}',
65
+ prometheus_listen_addr: '0.0.0.0:9652',
66
+ auth: {
67
+ token: 'PRAEFECT_EXTERNAL_TOKEN'
68
+ },
69
+ reconciliation: {
70
+ scheduling_interval: '10s'
71
+ },
72
+ database: {
73
+ host: '#{cluster_config.database_node_addr}',
74
+ port: #{cluster_config.database_port},
75
+ user: 'postgres',
76
+ password: 'SQL_PASSWORD',
77
+ dbname: 'praefect_production',
78
+ sslmode: 'disable'
79
+ },
80
+ virtual_storage: [
81
+ {
82
+ name: 'default',
83
+ node: [
84
+ {
85
+ 'storage': '#{cluster_config.primary_node_name}',
86
+ 'address': 'tcp://#{cluster_config.primary_node_addr}:#{cluster_config.primary_node_port}',
87
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
88
+ },
89
+ {
90
+ 'storage': '#{cluster_config.secondary_node_name}',
91
+ 'address': 'tcp://#{cluster_config.secondary_node_addr}:#{cluster_config.secondary_node_port}',
92
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
93
+ },
94
+ {
95
+ 'storage': '#{cluster_config.tertiary_node_name}',
96
+ 'address': 'tcp://#{cluster_config.tertiary_node_addr}:#{cluster_config.tertiary_node_port}',
97
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
98
+ }
99
+ ],
90
100
  }
91
- }
92
- };
101
+ ]
102
+ }
93
103
  OMNIBUS
94
104
  end
95
105
  end
@@ -27,12 +27,17 @@ module Gitlab
27
27
 
28
28
  def start
29
29
  pull_images
30
- docker.run(image: image, tag: tag, args: ['-container-network', network]) do |command|
30
+ docker.run(image: image, tag: tag, args:
31
+ ['-video-recorder-image',
32
+ QA::Runtime::Env.video_recorder_image,
33
+ '-container-network',
34
+ network,
35
+ '-timeout',
36
+ '10m0s']
37
+ ) do |command|
31
38
  set_command_args(command)
32
39
  set_volumes(command)
33
40
  end
34
-
35
- wait_until_ready
36
41
  end
37
42
 
38
43
  def wait_until_ready(max_attempts: 20, wait: 2)
@@ -50,14 +55,16 @@ module Gitlab
50
55
  private
51
56
 
52
57
  def grid_healthy?
53
- HTTP.get('http://localhost:4444/ping').status&.success?
54
- rescue HTTP::ConnectionError => _e
58
+ host = ENV['CI'] || ENV['CI_SERVER'] ? 'docker' : 'localhost'
59
+ HTTP.get("http://#{host}:4444/ping").status&.success?
60
+ rescue HTTP::ConnectionError => e
61
+ Runtime::Logger.debug(e)
55
62
  false
56
63
  end
57
64
 
58
65
  def pull_images
59
- docker.pull(image: "selenoid/chrome", tag: Runtime::Env.browser_version) if Runtime::Env.browser == :chrome && !Runtime::Env.mobile_layout?
60
- docker.pull(image: "selenoid/video-recorder", tag: "latest-release")
66
+ docker.pull(image: QA::Runtime::Env.selenoid_browser_image, tag: Runtime::Env.selenoid_browser_version)
67
+ docker.pull(image: QA::Runtime::Env.video_recorder_image, tag: QA::Runtime::Env.video_recorder_version)
61
68
  end
62
69
 
63
70
  # Set custom run command arguments
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # rubocop:disable Metrics/CyclomaticComplexity
3
4
  # rubocop:disable Metrics/AbcSize
4
5
 
@@ -20,11 +21,14 @@ module Gitlab
20
21
  @volumes = {}
21
22
  @additional_hosts = []
22
23
  @default_volumes = { '/var/run/docker.sock' => '/var/run/docker.sock' }
24
+
25
+ if Runtime::Env.qa_rspec_report_path.present? # rubocop:disable Style/IfUnlessModifier
26
+ @default_volumes[Runtime::Env.qa_rspec_report_path] = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'rspec')
27
+ end
28
+
23
29
  return if Runtime::Env.qa_knapsack_report_path.blank?
24
30
 
25
- @default_volumes[Runtime::Env.qa_knapsack_report_path] = File.join(
26
- Docker::Volumes::QA_CONTAINER_WORKDIR, 'knapsack'
27
- )
31
+ @default_volumes[Runtime::Env.qa_knapsack_report_path] = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'knapsack')
28
32
  end
29
33
 
30
34
  def perform
@@ -53,8 +57,10 @@ module Gitlab
53
57
 
54
58
  feature_flag_sets = []
55
59
 
56
- # When `args` includes `[..., "--disable-feature", "a", "--enable-feature", "b", "--set-feature-flags", "c=enable", ...]`
57
- # `feature_flag_sets` will be set to `[["--disable-feature", "a"], ["--enable-feature", "b"], ["--set-feature-flags", "c=enable"]]`
60
+ # When `args` includes:
61
+ # `[..., "--disable-feature", "a", "--enable-feature", "b", "--set-feature-flags", "c=enable", ...]`
62
+ # `feature_flag_sets` will be set to:
63
+ # `[["--disable-feature", "a"], ["--enable-feature", "b"], ["--set-feature-flags", "c=enable"]]`
58
64
  # This will result in tests running three times, once with each feature flag option.
59
65
  while (index = args&.index { |x| x =~ /--.*-feature/ })
60
66
  feature_flag_sets << args.slice!(index, 2)
@@ -13,9 +13,9 @@ module Gitlab
13
13
 
14
14
  def self.release
15
15
  QA::Release.new(image)
16
- rescue Support::InvalidResponseError => ex
17
- warn ex.message
18
- warn "#{ex.response.code} #{ex.response.message}: #{ex.response.body}"
16
+ rescue Support::InvalidResponseError => e
17
+ warn e.message
18
+ warn "#{e.response.code} #{e.response.message}: #{e.response.body}"
19
19
  exit 1
20
20
  end
21
21
 
@@ -81,7 +81,7 @@ module Gitlab
81
81
  end
82
82
 
83
83
  def api_get!
84
- @response_body ||= # rubocop:disable Naming/MemoizedInstanceVariableName
84
+ @response_body ||=
85
85
  begin
86
86
  response = Support::GetRequest.new(uri, Runtime::Env.qa_access_token).execute!
87
87
  JSON.parse(response.body)
@@ -43,7 +43,8 @@ module Gitlab
43
43
  #
44
44
  # @return [void]
45
45
  def prepare
46
- @telegraf_config = File.open("#{Dir.mktmpdir(nil, ENV['CI_BUILDS_DIR'])}/telegraf.conf", 'w') do |file|
46
+ @telegraf_config = File.open("#{Dir.mktmpdir(nil, ENV.fetch('CI_BUILDS_DIR', nil))}/telegraf.conf",
47
+ 'w') do |file|
47
48
  file.write(config)
48
49
  file.path
49
50
  end
@@ -18,7 +18,8 @@ module Gitlab
18
18
  end
19
19
 
20
20
  def login(username:, password:, registry:)
21
- Docker::Command.execute(%(login --username "#{username}" --password "#{password}" #{registry}), mask_secrets: password)
21
+ Docker::Command.execute(%(login --username "#{username}" --password "#{password}" #{registry}),
22
+ mask_secrets: password)
22
23
  end
23
24
 
24
25
  def pull(image:, tag: nil, quiet: true)
@@ -63,7 +64,8 @@ module Gitlab
63
64
  Class.new do
64
65
  # @param file The name of the file
65
66
  # @param contents The content of the file to write
66
- # @param expand_vars Set false if you need to write an environment variable '$' to a file. The variable should be escaped \\\$
67
+ # @param expand_vars Set false if you need to write an environment variable '$' to a file.
68
+ # The variable should be escaped \\\$
67
69
  def self.write(file, contents, expand_vars = true)
68
70
  if expand_vars
69
71
  %(echo "#{contents}" > #{file};)
@@ -82,7 +84,8 @@ module Gitlab
82
84
  def exec(name, command, mask_secrets: nil)
83
85
  cmd = ['exec']
84
86
  cmd << '--privileged' if privileged_command?(command)
85
- Docker::Command.execute(%(#{cmd.join(' ')} #{name} bash -c "#{command.gsub('"', '\\"')}"), mask_secrets: mask_secrets)
87
+ Docker::Command.execute(%(#{cmd.join(' ')} #{name} bash -c "#{command.gsub('"', '\\"')}"),
88
+ mask_secrets: mask_secrets)
86
89
  end
87
90
 
88
91
  def read_file(image, tag, path, &block)
@@ -20,7 +20,7 @@ module Gitlab
20
20
  # but Docker on macOS exposes /private and disallow exposing /var/
21
21
  # so we need to get the real tmpdir path
22
22
  Dir.mktmpdir('gitlab-qa-', File.realpath(Dir.tmpdir)).tap do |dir|
23
- yield Hash[@volumes.map { |k, v| ["#{dir}/#{k}", v] }]
23
+ yield @volumes.transform_keys { |k| "#{dir}/#{k}" }
24
24
  end
25
25
  end
26
26
  end
@@ -11,7 +11,7 @@ module Gitlab
11
11
  (-qa)?
12
12
  (:(?<tag>.+))?
13
13
  \z
14
- /xi.freeze
14
+ /xi
15
15
  CUSTOM_GITLAB_IMAGE_REGEX = %r{
16
16
  \A
17
17
  (?<image_without_tag>
@@ -23,7 +23,7 @@ module Gitlab
23
23
  (-qa)?
24
24
  (:(?<tag>.+))?
25
25
  \z
26
- }xi.freeze
26
+ }xi
27
27
 
28
28
  delegate :ci_project_path, to: Gitlab::QA::Runtime::Env
29
29
 
@@ -39,7 +39,7 @@ module Gitlab
39
39
  \A
40
40
  (?<version>\d+\.\d+.\d+(?:-rc\d+)?)-(?<edition>ce|ee|jh)
41
41
  \z
42
- /xi.freeze
42
+ /xi
43
43
 
44
44
  # Dev tag example:
45
45
  # 12.1.201906121026-325a6632895.b340d0bd35d
@@ -53,7 +53,7 @@ module Gitlab
53
53
  \A
54
54
  (?<version>\d+\.\d+(.\d+)?)\.(?<timestamp>\d+)-(?<gitlab_ref>[A-Za-z0-9]+)\.(?<omnibus_ref>[A-Za-z0-9]+)
55
55
  \z
56
- /xi.freeze
56
+ /xi
57
57
 
58
58
  DEFAULT_TAG = 'latest'
59
59
  DEFAULT_CANONICAL_TAG = 'nightly'
@@ -29,7 +29,8 @@ module Gitlab
29
29
  Runtime::Scenario.define(:teardown, false)
30
30
  end
31
31
 
32
- opts.on('--no-tests', 'Orchestrates the docker containers but does not run the tests. Implies --no-teardown') do
32
+ opts.on('--no-tests',
33
+ 'Orchestrates the docker containers but does not run the tests. Implies --no-teardown') do
33
34
  Runtime::Scenario.define(:run_tests, false)
34
35
  Runtime::Scenario.define(:teardown, false)
35
36
  end
@@ -42,7 +43,12 @@ module Gitlab
42
43
  Runtime::Scenario.define(:skip_server_hooks, true)
43
44
  end
44
45
 
45
- 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|
46
+ opts.on(
47
+ '--qa-image QA_IMAGE',
48
+ String,
49
+ "Specifies a QA image to be used instead of inferring it from the GitLab image." \
50
+ "See Gitlab::QA::Release#qa_image"
51
+ ) do |value|
46
52
  Runtime::Scenario.define(:qa_image, value)
47
53
  end
48
54
 
@@ -58,7 +64,8 @@ module Gitlab
58
64
  end
59
65
  end
60
66
 
61
- opts.on('--seed-db search_pattern1[,search_pattern2,...]', 'Seed application database with sample test data') do |file_pattern|
67
+ opts.on('--seed-db search_pattern1[,search_pattern2,...]',
68
+ 'Seed application database with sample test data') do |file_pattern|
62
69
  file_pattern.split(',').each do |pattern|
63
70
  @seed_scripts << pattern
64
71
  end