gitlab-qa 14.6.0 → 14.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d16aa0d0e3acf2f78c85344345d2d7a1637fa9c16154446020d0ffd5649687f9
4
- data.tar.gz: 68bbb672fecd7bd17113fd7485cbacf547477cd64362e250296316a897868974
3
+ metadata.gz: aca8f96e30555fcac3d968c580f1393b87d2114a3616e8ab6dbb98f913f852d4
4
+ data.tar.gz: 566a628d9587a7eeb6e6bcb530bed7170aa689aaadc50cecb28eaba17096e26e
5
5
  SHA512:
6
- metadata.gz: 260445e5a526267392c3d91d81eee2baa37df00c6981acecef40f64d17ebf7a10d608d9eb3eae61a287633ca5e7446fdd4e8da70bc70d1de8a2c915065910248
7
- data.tar.gz: fcb5cf3c6a4aa914bb089316cb1f3f1b6d8c666fc7dccf7621c79a90d92dc5dcfb6bb5aa77631059f1c841321baf898471f0e35f09ad7a6d831394badc983a67
6
+ metadata.gz: 4304f800c1430834f7b335ddae6627e51e6126d883359feefb2863662abe274c8b3de2fadca9328c6f6e9815aeb5df2798a1e839a24cf372ee66cdd5db9bea84
7
+ data.tar.gz: 1a8325bf53f232d5db6292a63107b15f0acf19a04acb7dc0186474656dbd12744ab429030eb53a4e3f83acc5f9655a7159fc14d89cf81b373650b4045904e95c
data/.gitlab-ci.yml CHANGED
@@ -133,9 +133,11 @@ package-and-test:
133
133
  RUN_WITH_BUNDLE: "true"
134
134
  SKIP_OMNIBUS_TRIGGER: "true"
135
135
  SKIP_REPORT_IN_ISSUES: "true"
136
- ALLURE_JOB_NAME: gitlab-qa
137
136
  UPDATE_QA_CACHE: $UPDATE_QA_CACHE
138
137
  GITLAB_QA_CACHE_KEY: $GITLAB_QA_CACHE_KEY
138
+ QA_RETRY_FAILED_SPECS: "true"
139
+ QA_RUN_TYPE: gitlab-qa
140
+ QA_EXPORT_TEST_METRICS: "false" # skip metrics export as this pipeline is only used to validate gitlab-qa changes
139
141
  inherit:
140
142
  variables:
141
143
  - RUBY_VERSION
@@ -153,4 +155,4 @@ package-and-test:
153
155
  - if: '$CI_MERGE_REQUEST_IID'
154
156
  when: manual
155
157
  allow_failure: true
156
- - when: always
158
+ - 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.7.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,6 +1,5 @@
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'
@@ -13,7 +12,18 @@ module Gitlab
13
12
  # the `qa/` directory located in GitLab CE / EE repositories.
14
13
  #
15
14
  class Specs < Scenario::Template
16
- attr_accessor :suite, :release, :network, :args, :volumes, :env, :runner_network, :hostname, :additional_hosts
15
+ LAST_RUN_FILE = "examples.txt"
16
+
17
+ attr_accessor :suite,
18
+ :release,
19
+ :network,
20
+ :args,
21
+ :volumes,
22
+ :env,
23
+ :runner_network,
24
+ :hostname,
25
+ :additional_hosts,
26
+ :retry_failed_specs
17
27
 
18
28
  def initialize
19
29
  @docker = Docker::Engine.new(stream_output: true) # stream test output directly instead of through logger
@@ -21,6 +31,7 @@ module Gitlab
21
31
  @volumes = {}
22
32
  @additional_hosts = []
23
33
  @volumes = { '/var/run/docker.sock' => '/var/run/docker.sock' }
34
+ @retry_failed_specs = Runtime::Env.retry_failed_specs?
24
35
 
25
36
  include_optional_volumes(
26
37
  Runtime::Env.qa_rspec_report_path => 'rspec',
@@ -51,9 +62,30 @@ module Gitlab
51
62
  Runtime::Logger.info("Running test suite `#{suite}` for #{release.project_name}")
52
63
 
53
64
  name = "#{release.project_name}-qa-#{SecureRandom.hex(4)}"
65
+ run_specs(name)
66
+ rescue Support::ShellCommand::StatusError => e
67
+ raise e unless retry_failed_specs
54
68
 
55
- feature_flag_sets = []
69
+ results_file = File.join(host_artifacts_dir(name), LAST_RUN_FILE)
70
+ raise "Failed to find initial run results file #{results_file}" unless File.exist?(results_file)
71
+
72
+ Runtime::Logger.warn("Initial test run failed, retrying failed specs in new process!")
73
+ run_specs(name, retry_process: true, initial_run_results_host_path: results_file)
74
+ end
75
+
76
+ private
77
+
78
+ # Ful path to tmp dir inside container
79
+ #
80
+ # @return [String]
81
+ def tmp_dir
82
+ @tmp_dir ||= File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, 'tmp')
83
+ end
84
+
85
+ def feature_flag_sets
86
+ return @feature_flag_sets if defined?(@feature_flag_sets)
56
87
 
88
+ feature_flag_sets = []
57
89
  # When `args` includes:
58
90
  # `[..., "--disable-feature", "a", "--enable-feature", "b", "--set-feature-flags", "c=enable", ...]`
59
91
  # `feature_flag_sets` will be set to:
@@ -62,14 +94,36 @@ module Gitlab
62
94
  while (index = args&.index { |x| x =~ /--.*-feature/ })
63
95
  feature_flag_sets << args.slice!(index, 2)
64
96
  end
65
-
66
97
  # When `args` do not have any feature flag options, we add [] so that test is run exactly once.
67
98
  feature_flag_sets << [] unless feature_flag_sets.any?
68
99
 
100
+ @feature_flag_sets = feature_flag_sets
101
+ end
102
+
103
+ def run_specs(name, retry_process: false, initial_run_results_host_path: nil)
104
+ container_name = retry_process ? "#{name}-retry" : name
105
+
106
+ env_vars = if retry_process
107
+ Runtime::Env.variables.merge({
108
+ **env,
109
+ "QA_RSPEC_RETRIED" => "true",
110
+ "NO_KNAPSACK" => "true"
111
+ })
112
+ else
113
+ Runtime::Env.variables.merge(env)
114
+ end
115
+
116
+ env_vars["RSPEC_LAST_RUN_RESULTS_FILE"] = last_run_results_file
117
+ # TODO: remove once rspec-retry gem is removed
118
+ env_vars["QA_DISABLE_RSPEC_RETRY"] = "true" if retry_failed_specs
119
+
120
+ run_volumes = volumes.to_h.merge({ host_artifacts_dir(container_name) => tmp_dir })
121
+ run_volumes[initial_run_results_host_path] = last_run_results_file if retry_process
122
+
69
123
  feature_flag_sets.each do |feature_flag_set|
70
124
  @docker.run(
71
125
  image: qa_image,
72
- args: [suite, *args_with_flags(args, feature_flag_set)],
126
+ args: [suite, *args_with_flags(feature_flag_set, retry_process: retry_process)],
73
127
  mask_secrets: Runtime::Env.variables_to_mask
74
128
  ) do |command|
75
129
  command << "-t --rm --net=#{network || 'bridge'}"
@@ -84,37 +138,40 @@ module Gitlab
84
138
  command << hosts # override /etc/hosts in docker container when test runs
85
139
  end
86
140
 
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
- )
95
-
96
- volumes.to_h.each { |to, from| command.volume(to, from) }
141
+ env_vars.each { |key, value| command.env(key, value) }
142
+ run_volumes.each { |to, from| command.volume(to, from) }
97
143
 
98
- command.name(name)
144
+ command.name(container_name)
99
145
  end
100
146
  end
101
147
  end
102
148
 
103
- private
104
-
105
149
  def docker_pull_qa_image_if_needed
106
150
  @docker.login(**release.login_params) if release.login_params
107
151
 
108
152
  @docker.pull(image: qa_image) unless Runtime::Env.skip_pull?
109
153
  end
110
154
 
111
- def args_with_flags(args, feature_flag_set)
112
- return args if feature_flag_set.empty?
155
+ def args_with_flags(feature_flag_set, retry_process: false)
156
+ return args if feature_flag_set.empty? && !retry_process
113
157
 
114
- Runtime::Logger.info("Running with feature flag: #{feature_flag_set.join(' ')}")
158
+ run_args = args.dup
159
+
160
+ if retry_process
161
+ if run_args.include?("--")
162
+ run_args.push("--only-failures")
163
+ first_rspec_arg_index = run_args.index("--") + 1
164
+ # if first arg after `--` is a not a flag, it's a specific spec/folder which needs to be removed
165
+ run_args.delete_at(first_rspec_arg_index) unless run_args[first_rspec_arg_index].start_with?("--")
166
+ else
167
+ run_args.push("--", "--only-failures")
168
+ end
169
+ end
115
170
 
116
- args_with_f = args.dup
117
- args_with_f.insert(1, *feature_flag_set)
171
+ return run_args if feature_flag_set.empty?
172
+
173
+ Runtime::Logger.info("Running with feature flag: #{feature_flag_set.join(' ')}")
174
+ run_args.insert(1, *feature_flag_set)
118
175
  end
119
176
 
120
177
  def skip_tests?
@@ -138,9 +195,23 @@ module Gitlab
138
195
  host_path.present? && volumes[host_path] = File.join(Docker::Volumes::QA_CONTAINER_WORKDIR, container_path)
139
196
  end
140
197
  end
198
+
199
+ # Full path to host artifacts dir
200
+ #
201
+ # @param [String] name
202
+ # @return [String]
203
+ def host_artifacts_dir(name)
204
+ File.join(Runtime::Env.host_artifacts_dir, name)
205
+ end
206
+
207
+ # Path to save or read run results file within container
208
+ #
209
+ # @return [String]
210
+ def last_run_results_file
211
+ File.join(tmp_dir, LAST_RUN_FILE)
212
+ end
141
213
  end
142
214
  end
143
215
  end
144
216
  end
145
- # rubocop:enable Metrics/CyclomaticComplexity
146
217
  # 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,
@@ -106,6 +107,7 @@ module Gitlab
106
107
  'CI_PROJECT_NAME' => :ci_project_name,
107
108
  'CI_PROJECT_PATH' => :ci_project_path,
108
109
  'CI_PIPELINE_SOURCE' => :ci_pipeline_source,
110
+ 'CI_PIPELINE_ID' => :ci_pipeline_id,
109
111
  'CI_PIPELINE_URL' => :ci_pipeline_url,
110
112
  'CI_PIPELINE_CREATED_AT' => :ci_pipeline_created_at,
111
113
  'CI_MERGE_REQUEST_IID' => :ci_merge_request_iid,
@@ -277,20 +279,29 @@ module Gitlab
277
279
 
278
280
  def require_aws_s3_environment!
279
281
  %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)
282
+ unless ENV.key?(env_key)
283
+ raise ArgumentError,
284
+ "Environment variable #{env_key} must be set to run AWS S3 object storage specs"
285
+ end
281
286
  end
282
287
  end
283
288
 
284
289
  def require_gcs_environment!
285
290
  %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)
291
+ unless ENV.key?(env_key)
292
+ raise ArgumentError,
293
+ "Environment variable #{env_key} must be set to run GCS object storage specs"
294
+ end
287
295
  end
288
296
  end
289
297
 
290
298
  def require_gcs_with_cdn_environment!
291
299
  %w[GOOGLE_CDN_JSON_KEY GCS_CDN_BUCKET_NAME GOOGLE_CDN_LB GOOGLE_CDN_SIGNURL_KEY
292
300
  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)
301
+ unless ENV.key?(env_key)
302
+ raise ArgumentError,
303
+ "Environment variable #{env_key} must be set to run GCS with CDN enabled scenario"
304
+ end
294
305
  end
295
306
  end
296
307
 
@@ -359,7 +370,7 @@ module Gitlab
359
370
  end
360
371
 
361
372
  def video_recorder_image
362
- env_var_value_if_defined('QA_VIDEO_RECORDER_IMAGE') || 'presidenten/selenoid-manual-video-recorder'
373
+ env_var_value_if_defined('QA_VIDEO_RECORDER_IMAGE') || 'registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-manual-video-recorder'
363
374
  end
364
375
 
365
376
  def video_recorder_version
@@ -455,6 +466,10 @@ module Gitlab
455
466
  enabled?(env_var_value_if_defined('QA_MOCK_GITHUB'), default: true)
456
467
  end
457
468
 
469
+ def retry_failed_specs?
470
+ enabled?(env_var_value_if_defined('QA_RETRY_FAILED_SPECS'), default: false)
471
+ end
472
+
458
473
  private
459
474
 
460
475
  def enabled?(value, default: true)
@@ -111,8 +111,9 @@ 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
116
117
  end
117
118
  rescue Support::ShellCommand::StatusError => e
118
119
  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.7.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.7.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-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control