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 +4 -4
- data/.gitlab-ci.yml +4 -2
- data/Gemfile.lock +2 -2
- data/docs/running_against_remote_grid.md +1 -1
- data/docs/what_tests_can_be_run.md +6 -4
- data/lib/gitlab/qa/component/ai_gateway.rb +1 -1
- data/lib/gitlab/qa/component/specs.rb +95 -24
- data/lib/gitlab/qa/runtime/env.rb +19 -4
- data/lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb +2 -1
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aca8f96e30555fcac3d968c580f1393b87d2114a3616e8ab6dbb98f913f852d4
|
4
|
+
data.tar.gz: 566a628d9587a7eeb6e6bcb530bed7170aa689aaadc50cecb28eaba17096e26e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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. | "
|
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
|
352
|
+
This tests that Geo UI proxying is working as expected.
|
353
353
|
|
354
|
-
The scenario spins up
|
355
|
-
|
356
|
-
|
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
|
-
'
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
|
88
|
-
|
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(
|
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(
|
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
|
-
|
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
|
-
|
117
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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') || '
|
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
|
data/lib/gitlab/qa/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2024-04-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|