gitlab-qa 14.6.0 → 14.8.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d16aa0d0e3acf2f78c85344345d2d7a1637fa9c16154446020d0ffd5649687f9
4
- data.tar.gz: 68bbb672fecd7bd17113fd7485cbacf547477cd64362e250296316a897868974
3
+ metadata.gz: 3632783614831ceda0acb1c2fa312dcea081c8e878dfe2ce41bdb6f9ac70253b
4
+ data.tar.gz: 5af7c287d9820b050feb5944a9bf93561ef33442f0120bb71e6c7d0c33528ed3
5
5
  SHA512:
6
- metadata.gz: 260445e5a526267392c3d91d81eee2baa37df00c6981acecef40f64d17ebf7a10d608d9eb3eae61a287633ca5e7446fdd4e8da70bc70d1de8a2c915065910248
7
- data.tar.gz: fcb5cf3c6a4aa914bb089316cb1f3f1b6d8c666fc7dccf7621c79a90d92dc5dcfb6bb5aa77631059f1c841321baf898471f0e35f09ad7a6d831394badc983a67
6
+ metadata.gz: 46a5d0fd06137c2f41f8f504f1b3afea1e82ba010f86f704a5991f859c555a45e74e1ad6eaa320e916ed6c8fa9227ef20e47e7da03441f8bc3ec6e6ef2aa2352
7
+ data.tar.gz: 8ccadd90b943ca72ccd967fabfd70ae26a834ff8b949456eecdda333af3a7e6754b46a956e0dc029b7b70847c9134fb11dcd54a202299d64cbfe2902620c7ca1
data/.gitlab-ci.yml CHANGED
@@ -10,7 +10,7 @@
10
10
  include:
11
11
  - component: gitlab.com/gitlab-org/components/danger-review/danger-review@~latest
12
12
  inputs:
13
- job_image: "${CI_REGISTRY}/gitlab-org/gitlab-build-images/debian-bullseye-ruby-${RUBY_VERSION}:bundler-2.4"
13
+ job_image: "${CI_REGISTRY}/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}:bundler-${BUNDLER_VERSION}"
14
14
  - component: gitlab.com/gitlab-org/components/gem-release/gem-release@~latest
15
15
 
16
16
  stages:
@@ -20,7 +20,7 @@ stages:
20
20
  - deploy
21
21
 
22
22
  default:
23
- image: ${CI_REGISTRY}/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}:bundler-2.3
23
+ image: ${CI_REGISTRY}/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}:bundler-${BUNDLER_VERSION}
24
24
  tags:
25
25
  - gitlab-org
26
26
  cache:
@@ -41,8 +41,10 @@ workflow:
41
41
  - if: '$CI_PIPELINE_SOURCE == "web"'
42
42
 
43
43
  variables:
44
- DEBIAN_VERSION: bullseye
45
- RUBY_VERSION: "3.0"
44
+ DEBIAN_VERSION: bookworm
45
+ DOCKER_VERSION: "24.0.5"
46
+ BUNDLER_VERSION: "2.5"
47
+ RUBY_VERSION: "3.1"
46
48
  BUNDLE_PATH: vendor
47
49
  BUNDLE_SILENCE_ROOT_WARNING: "true"
48
50
  BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES: "true"
@@ -133,13 +135,17 @@ package-and-test:
133
135
  RUN_WITH_BUNDLE: "true"
134
136
  SKIP_OMNIBUS_TRIGGER: "true"
135
137
  SKIP_REPORT_IN_ISSUES: "true"
136
- ALLURE_JOB_NAME: gitlab-qa
137
138
  UPDATE_QA_CACHE: $UPDATE_QA_CACHE
138
139
  GITLAB_QA_CACHE_KEY: $GITLAB_QA_CACHE_KEY
140
+ QA_RETRY_FAILED_SPECS: "true"
141
+ QA_RUN_TYPE: gitlab-qa
142
+ QA_EXPORT_TEST_METRICS: "false" # skip metrics export as this pipeline is only used to validate gitlab-qa changes
139
143
  inherit:
140
144
  variables:
141
145
  - RUBY_VERSION
142
146
  - DEBIAN_VERSION
147
+ - DOCKER_VERSION
148
+ - BUNDLER_VERSION
143
149
  trigger:
144
150
  strategy: depend
145
151
  forward:
@@ -153,4 +159,4 @@ package-and-test:
153
159
  - if: '$CI_MERGE_REQUEST_IID'
154
160
  when: manual
155
161
  allow_failure: true
156
- - when: always
162
+ - when: always
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-qa (14.6.0)
4
+ gitlab-qa (14.8.0)
5
5
  activesupport (>= 6.1, < 7.2)
6
6
  gitlab (~> 4.19)
7
7
  http (~> 5.0)
@@ -127,7 +127,7 @@ GEM
127
127
  multi_xml (>= 0.5.2)
128
128
  i18n (1.14.1)
129
129
  concurrent-ruby (~> 1.0)
130
- jaro_winkler (1.5.4)
130
+ jaro_winkler (1.5.6)
131
131
  json (2.6.3)
132
132
  kramdown (2.4.0)
133
133
  rexml
@@ -18,7 +18,7 @@ I.e, if you have a Selenium server set up at http://localhost:4444 or if you hav
18
18
  | QA_SAVE_ALL_VIDEOS | Used with Selenoid. Saves video for both passed and failed tests | false | false, true |
19
19
  | QA_SELENOID_BROWSER_IMAGE | Used with Selenoid. Sets the browser image to use for video recording. | "selenoid/chrome" | "selenoid/chrome", "registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-chrome-gitlab" |
20
20
  | QA_SELENOID_BROWSER_VERSION | Used in conjunction with QA_SELENOID_BROWSER_IMAGE. Version of browser to run against. | "111.0" | "latest" "111.0" "mobile-111.0"|
21
- | QA_VIDEO_RECORDER_IMAGE | Used with Selenoid. Sets the video recorder image to use for video recording. | "presidenten/selenoid-manual-video-recorder" | "presidenten/selenoid-manual-video-recorder" |
21
+ | QA_VIDEO_RECORDER_IMAGE | Used with Selenoid. Sets the video recorder image to use for video recording. | "registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-manual-video-recorder" | "registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-manual-video-recorder", "presidenten/selenoid-manual-video-recorder" |
22
22
  | QA_VIDEO_RECORDER_VERSION | Used with Selenoid. Sets the video recorder image version to use for video recording. | "latest" | "latest" |
23
23
  | QA_REMOTE_GRID_USERNAME | Used with Sauce Labs. Username to specify in the remote grid. "USERNAME@provider:80" | | "gitlab-sl" |
24
24
  | QA_REMOTE_GRID_ACCESS_KEY | Used with Sauce Labs. Key/Token paired with `QA_REMOTE_GRID_USERNAME` | | |
@@ -349,11 +349,13 @@ $ gitlab-qa Test::Omnibus::UpdateFromPrevious gitlab-ee:dev-tag 15.6.0-pre major
349
349
 
350
350
  ### `Test::Integration::Geo EE|<full image address>`
351
351
 
352
- This tests that two GitLab Geo instances work as expected.
352
+ This tests that Geo UI proxying is working as expected.
353
353
 
354
- The scenario spins up a primary and secondary GitLab Geo nodes, and verifies
355
- that the replications (repository, attachments, project rename etc.) work as
356
- expected.
354
+ The scenario spins up primary and secondary GitLab Geo nodes and
355
+ can be used to verify that web requests to secondary Geo site return
356
+ data that is present on the primary.
357
+
358
+ See https://docs.gitlab.com/ee/administration/geo/secondary_proxy
357
359
 
358
360
  To run tests against the GitLab containers, a GitLab QA (`gitlab/gitlab-qa`)
359
361
  container is spun up and tests are run from it by running the
@@ -24,7 +24,7 @@ module Gitlab
24
24
  'AIGW_GITLAB_URL' => "http://#{gitlab_hostname}",
25
25
  'AIGW_GITLAB_API_URL' => "http://#{gitlab_hostname}/api/v4",
26
26
  'AIGW_CUSTOMER_PORTAL_URL' => Runtime::Env.customer_portal_url,
27
- 'AIGW_USE_FAKE_MODELS' => true,
27
+ 'AIGW_MOCK_MODEL_RESPONSES' => true,
28
28
  'AIGW_LOGGING__LEVEL' => 'debug',
29
29
  'AIGW_LOGGING__TO_FILE' => "..#{LOG_DIR}/modelgateway_debug.log"
30
30
  }
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/CyclomaticComplexity
4
3
  # rubocop:disable Metrics/AbcSize
5
4
 
6
5
  require 'securerandom'
6
+ require 'active_support/core_ext/array/grouping'
7
7
 
8
8
  module Gitlab
9
9
  module QA
@@ -13,7 +13,19 @@ module Gitlab
13
13
  # the `qa/` directory located in GitLab CE / EE repositories.
14
14
  #
15
15
  class Specs < Scenario::Template
16
- attr_accessor :suite, :release, :network, :args, :volumes, :env, :runner_network, :hostname, :additional_hosts
16
+ LAST_RUN_FILE = "examples.txt"
17
+
18
+ attr_accessor :suite,
19
+ :release,
20
+ :network,
21
+ :args,
22
+ :volumes,
23
+ :env,
24
+ :runner_network,
25
+ :hostname,
26
+ :additional_hosts,
27
+ :retry_failed_specs,
28
+ :infer_qa_image_from_release
17
29
 
18
30
  def initialize
19
31
  @docker = Docker::Engine.new(stream_output: true) # stream test output directly instead of through logger
@@ -21,6 +33,7 @@ module Gitlab
21
33
  @volumes = {}
22
34
  @additional_hosts = []
23
35
  @volumes = { '/var/run/docker.sock' => '/var/run/docker.sock' }
36
+ @retry_failed_specs = Runtime::Env.retry_failed_specs?
24
37
 
25
38
  include_optional_volumes(
26
39
  Runtime::Env.qa_rspec_report_path => 'rspec',
@@ -51,9 +64,30 @@ module Gitlab
51
64
  Runtime::Logger.info("Running test suite `#{suite}` for #{release.project_name}")
52
65
 
53
66
  name = "#{release.project_name}-qa-#{SecureRandom.hex(4)}"
67
+ run_specs(name)
68
+ rescue Support::ShellCommand::StatusError => e
69
+ raise e unless retry_failed_specs
54
70
 
55
- feature_flag_sets = []
71
+ results_file = File.join(host_artifacts_dir(name), LAST_RUN_FILE)
72
+ raise "Failed to find initial run results file #{results_file}" unless File.exist?(results_file)
73
+
74
+ Runtime::Logger.warn("Initial test run failed, retrying failed specs in new process!")
75
+ run_specs(name, retry_process: true, initial_run_results_host_path: results_file)
76
+ end
77
+
78
+ private
56
79
 
80
+ # Ful path to tmp dir inside container
81
+ #
82
+ # @return [String]
83
+ def tmp_dir
84
+ @tmp_dir ||= File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp')
85
+ end
86
+
87
+ def feature_flag_sets
88
+ return @feature_flag_sets if defined?(@feature_flag_sets)
89
+
90
+ feature_flag_sets = []
57
91
  # When `args` includes:
58
92
  # `[..., "--disable-feature", "a", "--enable-feature", "b", "--set-feature-flags", "c=enable", ...]`
59
93
  # `feature_flag_sets` will be set to:
@@ -62,14 +96,36 @@ module Gitlab
62
96
  while (index = args&.index { |x| x =~ /--.*-feature/ })
63
97
  feature_flag_sets << args.slice!(index, 2)
64
98
  end
65
-
66
99
  # When `args` do not have any feature flag options, we add [] so that test is run exactly once.
67
100
  feature_flag_sets << [] unless feature_flag_sets.any?
68
101
 
102
+ @feature_flag_sets = feature_flag_sets
103
+ end
104
+
105
+ def run_specs(name, retry_process: false, initial_run_results_host_path: nil)
106
+ container_name = retry_process ? "#{name}-retry" : name
107
+
108
+ env_vars = if retry_process
109
+ Runtime::Env.variables.merge({
110
+ **env,
111
+ "QA_RSPEC_RETRIED" => "true",
112
+ "NO_KNAPSACK" => "true"
113
+ })
114
+ else
115
+ Runtime::Env.variables.merge(env)
116
+ end
117
+
118
+ env_vars["RSPEC_LAST_RUN_RESULTS_FILE"] = last_run_results_file
119
+ # TODO: remove once rspec-retry gem is removed
120
+ env_vars["QA_DISABLE_RSPEC_RETRY"] = "true" if retry_failed_specs
121
+
122
+ run_volumes = volumes.to_h.merge({ host_artifacts_dir(container_name) => tmp_dir })
123
+ run_volumes[initial_run_results_host_path] = last_run_results_file if retry_process
124
+
69
125
  feature_flag_sets.each do |feature_flag_set|
70
126
  @docker.run(
71
127
  image: qa_image,
72
- args: [suite, *args_with_flags(args, feature_flag_set)],
128
+ args: [suite, *args_with_flags(feature_flag_set, retry_process: retry_process)],
73
129
  mask_secrets: Runtime::Env.variables_to_mask
74
130
  ) do |command|
75
131
  command << "-t --rm --net=#{network || 'bridge'}"
@@ -84,37 +140,50 @@ module Gitlab
84
140
  command << hosts # override /etc/hosts in docker container when test runs
85
141
  end
86
142
 
87
- Runtime::Env.variables.merge(env).each do |key, value|
88
- command.env(key, value)
89
- end
90
-
91
- command.volume(
92
- File.join(Runtime::Env.host_artifacts_dir, name),
93
- File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp')
94
- )
143
+ env_vars.each { |key, value| command.env(key, value) }
144
+ run_volumes.each { |to, from| command.volume(to, from) }
95
145
 
96
- volumes.to_h.each { |to, from| command.volume(to, from) }
97
-
98
- command.name(name)
146
+ command.name(container_name)
99
147
  end
100
148
  end
101
149
  end
102
150
 
103
- private
104
-
105
151
  def docker_pull_qa_image_if_needed
106
152
  @docker.login(**release.login_params) if release.login_params
107
153
 
108
154
  @docker.pull(image: qa_image) unless Runtime::Env.skip_pull?
109
155
  end
110
156
 
111
- def args_with_flags(args, feature_flag_set)
112
- return args if feature_flag_set.empty?
157
+ def args_with_flags(feature_flag_set, retry_process: false)
158
+ return args if feature_flag_set.empty? && !retry_process
159
+
160
+ run_args = if !retry_process
161
+ args.dup
162
+ elsif args.include?("--")
163
+ qa_args, rspec_args = args.split("--")
164
+ [*qa_args, "--"] + args_without_spec_arguments(rspec_args).push("--only-failures")
165
+ else
166
+ args.dup.push("--", "--only-failures")
167
+ end
168
+
169
+ return run_args if feature_flag_set.empty?
113
170
 
114
171
  Runtime::Logger.info("Running with feature flag: #{feature_flag_set.join(' ')}")
172
+ run_args.insert(1, *feature_flag_set)
173
+ end
174
+
175
+ # Remove particular spec argument like specific spec/folder or specific tags
176
+ #
177
+ # @param [Array] rspec_args
178
+ # @return [Array]
179
+ def args_without_spec_arguments(rspec_args)
180
+ arg_pairs = rspec_args.each_with_object([]) do |arg, new_args|
181
+ next new_args.push([arg]) if new_args.last.nil? || arg.start_with?("--") || new_args.last.size == 2
182
+
183
+ new_args.last.push(arg)
184
+ end
115
185
 
116
- args_with_f = args.dup
117
- args_with_f.insert(1, *feature_flag_set)
186
+ arg_pairs.reject { |pair| pair.first == "--tag" || !pair.first.start_with?("--") }.flatten
118
187
  end
119
188
 
120
189
  def skip_tests?
@@ -122,11 +191,10 @@ module Gitlab
122
191
  end
123
192
 
124
193
  def qa_image
125
- if Runtime::Scenario.attributes.include?(:qa_image)
126
- Runtime::Scenario.qa_image
127
- else
128
- "#{release.qa_image}:#{release.qa_tag}"
129
- end
194
+ infered_qa_image = "#{release.qa_image}:#{release.qa_tag}"
195
+ return infered_qa_image if infer_qa_image_from_release || !Runtime::Scenario.attributes.include?(:qa_image)
196
+
197
+ Runtime::Scenario.qa_image
130
198
  end
131
199
 
132
200
  # Adds volumes to the volumes hash if the relevant host paths exist
@@ -138,9 +206,23 @@ module Gitlab
138
206
  host_path.present? && volumes[host_path] = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, container_path)
139
207
  end
140
208
  end
209
+
210
+ # Full path to host artifacts dir
211
+ #
212
+ # @param [String] name
213
+ # @return [String]
214
+ def host_artifacts_dir(name)
215
+ File.join(Runtime::Env.host_artifacts_dir, name)
216
+ end
217
+
218
+ # Path to save or read run results file within container
219
+ #
220
+ # @return [String]
221
+ def last_run_results_file
222
+ File.join(tmp_dir, LAST_RUN_FILE)
223
+ end
141
224
  end
142
225
  end
143
226
  end
144
227
  end
145
- # rubocop:enable Metrics/CyclomaticComplexity
146
228
  # rubocop:enable Metrics/AbcSize
@@ -96,6 +96,7 @@ module Gitlab
96
96
  'CI' => :ci,
97
97
  'CI_JOB_NAME' => :ci_job_name,
98
98
  'CI_JOB_NAME_SLUG' => :ci_job_name_slug,
99
+ 'CI_JOB_ID' => :ci_job_id,
99
100
  'CI_JOB_URL' => :ci_job_url,
100
101
  'CI_JOB_TOKEN' => :ci_job_token,
101
102
  'CI_RUNNER_ID' => :ci_runner_id,
@@ -105,7 +106,9 @@ module Gitlab
105
106
  'CI_NODE_TOTAL' => :ci_node_total,
106
107
  'CI_PROJECT_NAME' => :ci_project_name,
107
108
  'CI_PROJECT_PATH' => :ci_project_path,
109
+ 'CI_PROJECT_PATH_SLUG' => :ci_project_path_slug,
108
110
  'CI_PIPELINE_SOURCE' => :ci_pipeline_source,
111
+ 'CI_PIPELINE_ID' => :ci_pipeline_id,
109
112
  'CI_PIPELINE_URL' => :ci_pipeline_url,
110
113
  'CI_PIPELINE_CREATED_AT' => :ci_pipeline_created_at,
111
114
  'CI_MERGE_REQUEST_IID' => :ci_merge_request_iid,
@@ -277,20 +280,29 @@ module Gitlab
277
280
 
278
281
  def require_aws_s3_environment!
279
282
  %w[AWS_S3_REGION AWS_S3_KEY_ID AWS_S3_ACCESS_KEY AWS_S3_BUCKET_NAME].each do |env_key|
280
- raise ArgumentError, "Environment variable #{env_key} must be set to run AWS S3 object storage specs" unless ENV.key?(env_key)
283
+ unless ENV.key?(env_key)
284
+ raise ArgumentError,
285
+ "Environment variable #{env_key} must be set to run AWS S3 object storage specs"
286
+ end
281
287
  end
282
288
  end
283
289
 
284
290
  def require_gcs_environment!
285
291
  %w[GOOGLE_PROJECT GOOGLE_CLIENT_EMAIL GOOGLE_JSON_KEY GCS_BUCKET_NAME].each do |env_key|
286
- raise ArgumentError, "Environment variable #{env_key} must be set to run GCS object storage specs" unless ENV.key?(env_key)
292
+ unless ENV.key?(env_key)
293
+ raise ArgumentError,
294
+ "Environment variable #{env_key} must be set to run GCS object storage specs"
295
+ end
287
296
  end
288
297
  end
289
298
 
290
299
  def require_gcs_with_cdn_environment!
291
300
  %w[GOOGLE_CDN_JSON_KEY GCS_CDN_BUCKET_NAME GOOGLE_CDN_LB GOOGLE_CDN_SIGNURL_KEY
292
301
  GOOGLE_CDN_SIGNURL_KEY_NAME].each do |env_key|
293
- raise ArgumentError, "Environment variable #{env_key} must be set to run GCS with CDN enabled scenario" unless ENV.key?(env_key)
302
+ unless ENV.key?(env_key)
303
+ raise ArgumentError,
304
+ "Environment variable #{env_key} must be set to run GCS with CDN enabled scenario"
305
+ end
294
306
  end
295
307
  end
296
308
 
@@ -359,7 +371,7 @@ module Gitlab
359
371
  end
360
372
 
361
373
  def video_recorder_image
362
- env_var_value_if_defined('QA_VIDEO_RECORDER_IMAGE') || 'presidenten/selenoid-manual-video-recorder'
374
+ env_var_value_if_defined('QA_VIDEO_RECORDER_IMAGE') || 'registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-manual-video-recorder'
363
375
  end
364
376
 
365
377
  def video_recorder_version
@@ -455,6 +467,10 @@ module Gitlab
455
467
  enabled?(env_var_value_if_defined('QA_MOCK_GITHUB'), default: true)
456
468
  end
457
469
 
470
+ def retry_failed_specs?
471
+ enabled?(env_var_value_if_defined('QA_RETRY_FAILED_SPECS'), default: false)
472
+ end
473
+
458
474
  private
459
475
 
460
476
  def enabled?(value, default: true)
@@ -111,8 +111,11 @@ module Gitlab
111
111
  specs.args = [gitlab.address, *rspec_args]
112
112
  next if release == current_release
113
113
 
114
- # do not generate reports and metrics artifacts for non release runs
114
+ # do not generate reports and metrics artifacts for non release runs or retry failures
115
115
  specs.env = { 'QA_GENERATE_ALLURE_REPORT' => false, 'QA_SAVE_TEST_METRICS' => false }
116
+ specs.retry_failed_specs = false
117
+ # if qa-image was set explicitly, make sure it is not used on initial run for release
118
+ specs.infer_qa_image_from_release = true
116
119
  end
117
120
  rescue Support::ShellCommand::StatusError => e
118
121
  if release == current_release # only fail on current release
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '14.6.0'
5
+ VERSION = '14.8.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab-qa
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.6.0
4
+ version: 14.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-02 00:00:00.000000000 Z
11
+ date: 2024-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control