gitlab-qa 7.29.1 → 7.32.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 +4 -4
- data/.gitignore +3 -0
- data/.gitlab/ci/jobs/base.gitlab-ci.yml +2 -0
- data/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +2 -2
- data/.gitlab/ci/jobs/decomposition_multiple_db.gitlab-ci.yml +25 -0
- data/.gitlab/ci/jobs/{ci_decomposition.gitlab-ci.yml → decomposition_single_db.gitlab-ci.yml} +4 -4
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +0 -5
- data/Gemfile.lock +1 -1
- data/docs/what_tests_can_be_run.md +11 -3
- data/lib/gitlab/qa/component/gitlab.rb +25 -2
- data/lib/gitlab/qa/docker/engine.rb +9 -2
- data/lib/gitlab/qa/report/relate_failure_issue.rb +2 -2
- data/lib/gitlab/qa/report/report_results.rb +38 -2
- data/lib/gitlab/qa/report/results_in_issues.rb +1 -1
- data/lib/gitlab/qa/report/test_result.rb +1 -1
- data/lib/gitlab/qa/runner.rb +5 -0
- data/lib/gitlab/qa/runtime/logger.rb +1 -0
- data/lib/gitlab/qa/runtime/omnibus_configurations/{ci_decomposition.rb → decomposition_multiple_db.rb} +1 -1
- data/lib/gitlab/qa/runtime/omnibus_configurations/decomposition_single_db.rb +19 -0
- data/lib/gitlab/qa/scenario/test/sanity/version.rb +34 -8
- data/lib/gitlab/qa/test_logger.rb +2 -1
- data/lib/gitlab/qa/version.rb +1 -1
- data/lib/gitlab/qa.rb +2 -1
- data/scripts/generate-qa-jobs.rb +64 -43
- data/support/data/license_usage_seed.rb +1 -0
- metadata +6 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7af4e17998896415aa9c217a012124b8fa4ce8727d781a3ef47ea2801c9c6632
|
|
4
|
+
data.tar.gz: '0162299be6ab6e7f40d83a7f0c8a1d4d76879e7cf8d7181e3e8f027285fba8a0'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82aeb884f959762a0de031bf0f44d050b32a576cb92adff50b9af7902ed481dab0ce0ad295338238fb61108e58be1a85b10b27f59209bb36e8655cde13d5f460
|
|
7
|
+
data.tar.gz: 1964ac96d147d43a008ee2619d49a53b661851c1c4cb09b74701b52bf680c4f376c52aa1a68f62a08d51080199385e34cb322e4036d9d7daa7d166bf447ca620
|
data/.gitignore
CHANGED
|
@@ -11,7 +11,7 @@ ee:cloud-activation:
|
|
|
11
11
|
- .combined-gitlab-qa-options-script
|
|
12
12
|
variables:
|
|
13
13
|
QA_RSPEC_TAGS: "--tag cloud_activation"
|
|
14
|
-
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --
|
|
14
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --seed-db license*.rb"
|
|
15
15
|
|
|
16
16
|
ee:cloud-activation-quarantine:
|
|
17
17
|
before_script:
|
|
@@ -27,4 +27,4 @@ ee:cloud-activation-quarantine:
|
|
|
27
27
|
- .combined-gitlab-qa-options-script
|
|
28
28
|
variables:
|
|
29
29
|
QA_RSPEC_TAGS: "--tag cloud_activation"
|
|
30
|
-
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --
|
|
30
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --seed-db license*.rb"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
ce:decomposition_multiple_db:
|
|
2
|
+
extends:
|
|
3
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
|
4
|
+
- .rules:ce-never-when-qa-tests-specified
|
|
5
|
+
- .test
|
|
6
|
+
- .high-capacity
|
|
7
|
+
- .ce-variables
|
|
8
|
+
- .rspec-report-opts
|
|
9
|
+
- .combined-gitlab-qa-options-script
|
|
10
|
+
parallel: 5
|
|
11
|
+
variables:
|
|
12
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config decomposition_multiple_db"
|
|
13
|
+
|
|
14
|
+
ee:decomposition_multiple_db:
|
|
15
|
+
extends:
|
|
16
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
17
|
+
- .rules:ee-never-when-qa-tests-specified
|
|
18
|
+
- .test
|
|
19
|
+
- .ee-variables
|
|
20
|
+
- .high-capacity
|
|
21
|
+
- .rspec-report-opts
|
|
22
|
+
- .combined-gitlab-qa-options-script
|
|
23
|
+
parallel: 5
|
|
24
|
+
variables:
|
|
25
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config decomposition_multiple_db"
|
data/.gitlab/ci/jobs/{ci_decomposition.gitlab-ci.yml → decomposition_single_db.gitlab-ci.yml}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
ce:
|
|
1
|
+
ce:decomposition_single_db:
|
|
2
2
|
extends:
|
|
3
3
|
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
|
4
4
|
- .rules:ce-never-when-qa-tests-specified
|
|
@@ -9,9 +9,9 @@ ce:ci_decomposition:
|
|
|
9
9
|
- .combined-gitlab-qa-options-script
|
|
10
10
|
parallel: 5
|
|
11
11
|
variables:
|
|
12
|
-
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config
|
|
12
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config decomposition_single_db"
|
|
13
13
|
|
|
14
|
-
ee:
|
|
14
|
+
ee:decomposition_single_db:
|
|
15
15
|
extends:
|
|
16
16
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
17
17
|
- .rules:ee-never-when-qa-tests-specified
|
|
@@ -22,4 +22,4 @@ ee:ci_decomposition:
|
|
|
22
22
|
- .combined-gitlab-qa-options-script
|
|
23
23
|
parallel: 5
|
|
24
24
|
variables:
|
|
25
|
-
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config
|
|
25
|
+
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --omnibus-config decomposition_single_db"
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -89,11 +89,6 @@ RSpec/LeakyConstantDeclaration:
|
|
|
89
89
|
Exclude:
|
|
90
90
|
- 'spec/gitlab/qa/scenario/test/instance/deployment_base_spec.rb'
|
|
91
91
|
|
|
92
|
-
# Offense count: 221
|
|
93
|
-
# Configuration parameters: AllowSubject.
|
|
94
|
-
RSpec/MultipleMemoizedHelpers:
|
|
95
|
-
Max: 22
|
|
96
|
-
|
|
97
92
|
# Offense count: 1
|
|
98
93
|
# Cop supports --auto-correct.
|
|
99
94
|
Style/ExplicitBlockArgument:
|
data/Gemfile.lock
CHANGED
|
@@ -997,12 +997,20 @@ This scenario is a composition of two orchestrated scenarios. It tests the conta
|
|
|
997
997
|
GITLAB_TLS_CERTIFICATE=$(cat /path/to/certificate.crt) gitlab-qa Test::Integration::RegistryTLS EE --omnibus-config object_storage_aws
|
|
998
998
|
```
|
|
999
999
|
|
|
1000
|
-
### Test::Instance::Image EE --omnibus-config
|
|
1000
|
+
### Test::Instance::Image EE --omnibus-config decomposition_single_db
|
|
1001
1001
|
|
|
1002
|
-
This scenario is to run tests against GitLab instance with [decomposed database](https://gitlab.com/groups/gitlab-org/-/epics/6160)
|
|
1002
|
+
This scenario is to run tests against a GitLab instance with a [decomposed database](https://gitlab.com/groups/gitlab-org/-/epics/6160) using a single database:
|
|
1003
1003
|
|
|
1004
1004
|
```ruby
|
|
1005
|
-
gitlab-qa Test::Instance::Image EE --omnibus-config
|
|
1005
|
+
gitlab-qa Test::Instance::Image EE --omnibus-config decomposition_single_db
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
### Test::Instance::Image EE --omnibus-config decomposition_multiple_db
|
|
1009
|
+
|
|
1010
|
+
This scenario is to run tests against a GitLab instance with a [decomposed database](https://gitlab.com/groups/gitlab-org/-/epics/6160) using multiple databases:
|
|
1011
|
+
|
|
1012
|
+
```ruby
|
|
1013
|
+
gitlab-qa Test::Instance::Image EE --omnibus-config decomposition_multiple_db
|
|
1006
1014
|
```
|
|
1007
1015
|
|
|
1008
1016
|
### `Test::Instance::Geo EE|<full image address>:nightly|latest|any_tag http://geo-primary.gitlab http://geo-secondary.gitlab`
|
|
@@ -176,6 +176,7 @@ module Gitlab
|
|
|
176
176
|
exec_commands << seed_admin_token_command if seed_admin_token
|
|
177
177
|
exec_commands << seed_test_data_command if seed_db
|
|
178
178
|
exec_commands << Runtime::Scenario.omnibus_exec_commands
|
|
179
|
+
exec_commands << add_git_server_hooks unless Runtime::Scenario.skip_server_hooks
|
|
179
180
|
|
|
180
181
|
commands = exec_commands.flatten.uniq
|
|
181
182
|
return if commands.empty?
|
|
@@ -184,14 +185,17 @@ module Gitlab
|
|
|
184
185
|
commands.each { |command| @docker.exec(name, command) }
|
|
185
186
|
end
|
|
186
187
|
|
|
187
|
-
def
|
|
188
|
+
def rails_version
|
|
188
189
|
json = @docker.read_file(
|
|
189
190
|
@release.image, @release.tag,
|
|
190
191
|
'/opt/gitlab/version-manifest.json'
|
|
191
192
|
)
|
|
192
193
|
|
|
193
194
|
manifest = JSON.parse(json)
|
|
194
|
-
|
|
195
|
+
{
|
|
196
|
+
sha: manifest['software']['gitlab-rails']['locked_version'],
|
|
197
|
+
source: manifest['software']['gitlab-rails']['locked_source']['git']
|
|
198
|
+
}
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
def copy_key_file(env_key)
|
|
@@ -243,6 +247,25 @@ module Gitlab
|
|
|
243
247
|
["gitlab-rails runner #{DATA_PATH}/admin_access_token_seed.rb"]
|
|
244
248
|
end
|
|
245
249
|
|
|
250
|
+
def add_git_server_hooks
|
|
251
|
+
global_server_prereceive_hook = <<~SCRIPT
|
|
252
|
+
#!/usr/bin/env bash
|
|
253
|
+
|
|
254
|
+
if [[ \\\$GL_PROJECT_PATH =~ 'reject-prereceive' ]]; then
|
|
255
|
+
echo 'GL-HOOK-ERR: Custom error message rejecting prereceive hook for projects with GL_PROJECT_PATH matching pattern reject-prereceive'
|
|
256
|
+
exit 1
|
|
257
|
+
fi
|
|
258
|
+
SCRIPT
|
|
259
|
+
|
|
260
|
+
[
|
|
261
|
+
@docker.exec(name, 'mkdir -p /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d'),
|
|
262
|
+
@docker.write_files(name) do |f|
|
|
263
|
+
f.write('/opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/pre-receive.d', global_server_prereceive_hook, false)
|
|
264
|
+
end,
|
|
265
|
+
@docker.exec(name, 'chmod +x /opt/gitlab/embedded/service/gitlab-shell/hooks/pre-receive.d/*')
|
|
266
|
+
]
|
|
267
|
+
end
|
|
268
|
+
|
|
246
269
|
class Availability
|
|
247
270
|
def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
|
|
248
271
|
@docker = Docker::Engine.new
|
|
@@ -61,8 +61,15 @@ module Gitlab
|
|
|
61
61
|
def write_files(name)
|
|
62
62
|
exec(name, yield(
|
|
63
63
|
Class.new do
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
# @param file The name of the file
|
|
65
|
+
# @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
|
+
def self.write(file, contents, expand_vars = true)
|
|
68
|
+
if expand_vars
|
|
69
|
+
%(echo "#{contents}" > #{file};)
|
|
70
|
+
else
|
|
71
|
+
%(echo '#{contents}' > #{file};)
|
|
72
|
+
end
|
|
66
73
|
end
|
|
67
74
|
|
|
68
75
|
def self.append(file, contents)
|
|
@@ -210,10 +210,10 @@ module Gitlab
|
|
|
210
210
|
|
|
211
211
|
failure = full_stacktrace(test)
|
|
212
212
|
|
|
213
|
-
if test.screenshot? && !
|
|
213
|
+
if test.screenshot? && !['500 Internal Server Error', 'fabricate_via_api!', 'Error Code 500'].any? { |e| failure.include?(e) }
|
|
214
214
|
relative_url = gitlab.upload_file(file_fullpath: test.failure_screenshot)
|
|
215
215
|
|
|
216
|
-
section = "### Screenshot: #{relative_url.markdown}"
|
|
216
|
+
section = "### Screenshot: #{relative_url.markdown}" if relative_url
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
section
|
|
@@ -7,7 +7,9 @@ module Gitlab
|
|
|
7
7
|
class ReportResults < ReportAsIssue
|
|
8
8
|
attr_accessor :testcase_project_reporter, :results_issue_project_reporter, :files, :test_case_project, :results_issue_project, :gitlab
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
IGNORE_EXCEPTIONS = ['Net::ReadTimeout'].freeze
|
|
11
|
+
|
|
12
|
+
def initialize(token:, input_files:, test_case_project: nil, results_issue_project: nil, dry_run: false, **kwargs)
|
|
11
13
|
@testcase_project_reporter = Gitlab::QA::Report::ResultsInTestCases.new(token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs)
|
|
12
14
|
@results_issue_project_reporter = Gitlab::QA::Report::ResultsInIssues.new(token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs)
|
|
13
15
|
@test_case_project = test_case_project
|
|
@@ -32,7 +34,7 @@ module Gitlab
|
|
|
32
34
|
test_results.each do |test|
|
|
33
35
|
puts "Reporting test: #{test.file} | #{test.name}\n"
|
|
34
36
|
|
|
35
|
-
report_test(test)
|
|
37
|
+
report_test(test) if should_report?(test)
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
test_results.write
|
|
@@ -54,6 +56,40 @@ module Gitlab
|
|
|
54
56
|
testcase_project_reporter.update_testcase(testcase, test)
|
|
55
57
|
results_issue_project_reporter.update_issue(issue, test)
|
|
56
58
|
end
|
|
59
|
+
|
|
60
|
+
# Checks if a test result should be reported.
|
|
61
|
+
#
|
|
62
|
+
# @return [Boolean] false if the test was skipped or failed because of a transient error that can be ignored.
|
|
63
|
+
# Otherwise returns true.
|
|
64
|
+
def should_report?(test)
|
|
65
|
+
return false if test.skipped
|
|
66
|
+
|
|
67
|
+
if test.report.key?('exceptions')
|
|
68
|
+
reason = ignore_failure_reason(test.report['exceptions'])
|
|
69
|
+
|
|
70
|
+
if reason
|
|
71
|
+
puts "Issue update skipped because #{reason}"
|
|
72
|
+
|
|
73
|
+
return false
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
true
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Determine any reason to ignore a failure.
|
|
81
|
+
#
|
|
82
|
+
# @param [Array<Hash>] exceptions the exceptions associated with the failure.
|
|
83
|
+
# @return [String] the reason to ignore the exceptions, or `nil` if any exceptions should not be ignored.
|
|
84
|
+
def ignore_failure_reason(exceptions)
|
|
85
|
+
exception_classes = exceptions
|
|
86
|
+
.filter_map { |exception| exception['class'] if IGNORE_EXCEPTIONS.include?(exception['class']) }
|
|
87
|
+
.compact
|
|
88
|
+
return if exception_classes.empty? || exception_classes.size < exceptions.size
|
|
89
|
+
|
|
90
|
+
msg = exception_classes.many? ? 'the errors were' : 'the error was'
|
|
91
|
+
"#{msg} #{exception_classes.join(', ')}"
|
|
92
|
+
end
|
|
57
93
|
end
|
|
58
94
|
end
|
|
59
95
|
end
|
|
@@ -115,7 +115,7 @@ module Gitlab
|
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
exception['message'].gsub!(/(private_token=)[\w-]+/, '********')
|
|
118
|
-
exception['message_lines'].each { |line| line.gsub!(/(private_token=)([\w-]+)/, '********') }
|
|
118
|
+
Array(exception['message_lines']).each { |line| line.gsub!(/(private_token=)([\w-]+)/, '********') }
|
|
119
119
|
|
|
120
120
|
{
|
|
121
121
|
'message' => "#{exception['class']}: #{exception['message']}",
|
data/lib/gitlab/qa/runner.rb
CHANGED
|
@@ -15,6 +15,7 @@ module Gitlab
|
|
|
15
15
|
Runtime::Scenario.define(:seed_db, false)
|
|
16
16
|
Runtime::Scenario.define(:seed_admin_token, true) # Create an admin access token for root user by default
|
|
17
17
|
Runtime::Scenario.define(:omnibus_exec_commands, [])
|
|
18
|
+
Runtime::Scenario.define(:skip_server_hooks, false)
|
|
18
19
|
|
|
19
20
|
# Omnibus Configurators specified by flags
|
|
20
21
|
@active_configurators = []
|
|
@@ -37,6 +38,10 @@ module Gitlab
|
|
|
37
38
|
Runtime::Scenario.define(:seed_admin_token, false)
|
|
38
39
|
end
|
|
39
40
|
|
|
41
|
+
opts.on('--skip-server-hooks', 'Skip adding global git server hooks') do
|
|
42
|
+
Runtime::Scenario.define(:skip_server_hooks, true)
|
|
43
|
+
end
|
|
44
|
+
|
|
40
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|
|
|
41
46
|
Runtime::Scenario.define(:qa_image, value)
|
|
42
47
|
end
|
|
@@ -4,7 +4,7 @@ module Gitlab
|
|
|
4
4
|
module QA
|
|
5
5
|
module Runtime
|
|
6
6
|
module OmnibusConfigurations
|
|
7
|
-
class
|
|
7
|
+
class DecompositionMultipleDb < Default
|
|
8
8
|
def configuration
|
|
9
9
|
# HACK: commenting commands out as these commands should be run *after* the first
|
|
10
10
|
# reconfiguration (see first command in #exec_commands)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Runtime
|
|
6
|
+
module OmnibusConfigurations
|
|
7
|
+
class DecompositionSingleDb < Default
|
|
8
|
+
def configuration
|
|
9
|
+
<<~OMNIBUS
|
|
10
|
+
gitlab_rails['databases']['main']['enable'] = true
|
|
11
|
+
gitlab_rails['databases']['ci']['enable'] = true
|
|
12
|
+
gitlab_rails['databases']['ci']['db_database'] = 'gitlabhq_production'
|
|
13
|
+
OMNIBUS
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -12,22 +12,43 @@ module Gitlab
|
|
|
12
12
|
# the window defined by the `weekday_hours` method.
|
|
13
13
|
# We perform a single API call to get the commit
|
|
14
14
|
class Version < Scenario::Template
|
|
15
|
+
SOURCE_MAP = {
|
|
16
|
+
'git@dev.gitlab.org:gitlab/gitlab-ee.git' => {
|
|
17
|
+
host: 'dev.gitlab.org',
|
|
18
|
+
project: 'gitlab/gitlab-ee'
|
|
19
|
+
},
|
|
20
|
+
'git@dev.gitlab.org:gitlab/gitlabhq.git' => {
|
|
21
|
+
host: 'dev.gitlab.org',
|
|
22
|
+
project: 'gitlab/gitlabhq'
|
|
23
|
+
},
|
|
24
|
+
'git@gitlab.com:gitlab-org/gitlab.git' => {
|
|
25
|
+
host: 'gitlab.com',
|
|
26
|
+
project: 'gitlab-org/gitlab'
|
|
27
|
+
},
|
|
28
|
+
'git@gitlab.com:gitlab-org/gitlab-foss.git' => {
|
|
29
|
+
host: 'gitlab.com',
|
|
30
|
+
project: 'gitlab-org/gitlab-foss'
|
|
31
|
+
}
|
|
32
|
+
}.freeze
|
|
33
|
+
|
|
15
34
|
def perform(release = 'ce')
|
|
16
35
|
version = Component::Gitlab.perform do |gitlab|
|
|
17
36
|
gitlab.release = release
|
|
18
37
|
gitlab.act do
|
|
19
38
|
pull
|
|
20
|
-
|
|
39
|
+
rails_version
|
|
21
40
|
end
|
|
22
41
|
end
|
|
23
42
|
|
|
24
|
-
project =
|
|
25
|
-
|
|
43
|
+
project = SOURCE_MAP[version[:source]][:project]
|
|
44
|
+
host = SOURCE_MAP[version[:source]][:host]
|
|
45
|
+
sha = version[:sha]
|
|
46
|
+
commit = api_commit_detail(host, project, sha)
|
|
26
47
|
|
|
27
48
|
if commit_within_hours?(commit['created_at'], weekday_hours(commit['created_at']))
|
|
28
|
-
puts "Found commit #{
|
|
49
|
+
puts "Found commit #{sha} in recent history of #{project} on #{host}"
|
|
29
50
|
else
|
|
30
|
-
puts "Did not find #{
|
|
51
|
+
puts "Did not find #{sha} in recent history of #{project} on #{host}"
|
|
31
52
|
exit 1
|
|
32
53
|
end
|
|
33
54
|
end
|
|
@@ -51,9 +72,14 @@ module Gitlab
|
|
|
51
72
|
Time.at(Time.parse(commit_time_string).utc).to_datetime > Time.at((Time.now - hours * 60 * 60).utc).to_datetime
|
|
52
73
|
end
|
|
53
74
|
|
|
54
|
-
def api_commit_detail(project,
|
|
55
|
-
|
|
56
|
-
|
|
75
|
+
def api_commit_detail(host, project, sha)
|
|
76
|
+
url = "https://#{host}/api/v4/projects/#{CGI.escape(project)}/repository/commits/#{sha}"
|
|
77
|
+
|
|
78
|
+
if host == 'dev.gitlab.org'
|
|
79
|
+
Runtime::Env.require_qa_dev_access_token!
|
|
80
|
+
|
|
81
|
+
url = "#{url}?private_token=#{Runtime::Env.qa_dev_access_token}"
|
|
82
|
+
end
|
|
57
83
|
|
|
58
84
|
JSON.parse(Net::HTTP.get(URI(url)))
|
|
59
85
|
end
|
|
@@ -68,12 +68,13 @@ module Gitlab
|
|
|
68
68
|
|
|
69
69
|
# Log message prefix
|
|
70
70
|
#
|
|
71
|
+
# @note when outputted, the date will be formatted as "Jun 07 2022 11:30:00 UTC"
|
|
71
72
|
# @param [DateTime] date
|
|
72
73
|
# @param [String] source
|
|
73
74
|
# @param [String] severity
|
|
74
75
|
# @return [String]
|
|
75
76
|
def message_prefix(date, source, severity)
|
|
76
|
-
"[
|
|
77
|
+
"[#{date.strftime('%h %d %Y %H:%M:%S %Z')} (#{source})] #{severity.ljust(5)} -- "
|
|
77
78
|
end
|
|
78
79
|
end
|
|
79
80
|
end
|
data/lib/gitlab/qa/version.rb
CHANGED
data/lib/gitlab/qa.rb
CHANGED
|
@@ -20,7 +20,8 @@ module Gitlab
|
|
|
20
20
|
autoload :ObjectStorageGcs, 'gitlab/qa/runtime/omnibus_configurations/object_storage_gcs'
|
|
21
21
|
autoload :LicenseMode, 'gitlab/qa/runtime/omnibus_configurations/license_mode'
|
|
22
22
|
autoload :RegistryObjectStorage, 'gitlab/qa/runtime/omnibus_configurations/registry_object_storage'
|
|
23
|
-
autoload :
|
|
23
|
+
autoload :DecompositionSingleDb, 'gitlab/qa/runtime/omnibus_configurations/decomposition_single_db'
|
|
24
|
+
autoload :DecompositionMultipleDb, 'gitlab/qa/runtime/omnibus_configurations/decomposition_multiple_db'
|
|
24
25
|
end
|
|
25
26
|
end
|
|
26
27
|
|
data/scripts/generate-qa-jobs.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
|
|
3
|
+
require 'yaml'
|
|
4
|
+
|
|
3
5
|
class GenerateQAJobs
|
|
4
6
|
def initialize(no_of_example_files)
|
|
5
7
|
@no_of_example_files = no_of_example_files
|
|
@@ -7,63 +9,82 @@ class GenerateQAJobs
|
|
|
7
9
|
end
|
|
8
10
|
|
|
9
11
|
# rubocop:disable Metrics/AbcSize
|
|
10
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
11
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
12
12
|
def execute
|
|
13
13
|
jobs = load_yml_contents('base')
|
|
14
|
-
jobs.
|
|
15
|
-
jobs.
|
|
16
|
-
jobs.
|
|
17
|
-
jobs.
|
|
18
|
-
jobs.
|
|
19
|
-
jobs.
|
|
20
|
-
jobs.
|
|
21
|
-
jobs.
|
|
22
|
-
jobs.
|
|
23
|
-
jobs.
|
|
24
|
-
jobs.
|
|
25
|
-
jobs.
|
|
26
|
-
jobs.
|
|
27
|
-
jobs.
|
|
28
|
-
jobs.
|
|
29
|
-
jobs.
|
|
30
|
-
jobs.
|
|
31
|
-
jobs.
|
|
32
|
-
jobs.
|
|
33
|
-
jobs.
|
|
34
|
-
jobs.
|
|
35
|
-
jobs.
|
|
36
|
-
jobs.
|
|
37
|
-
jobs.
|
|
38
|
-
jobs.
|
|
39
|
-
jobs.
|
|
40
|
-
jobs.
|
|
41
|
-
jobs.
|
|
42
|
-
jobs.
|
|
43
|
-
jobs.
|
|
44
|
-
jobs.
|
|
45
|
-
jobs.
|
|
46
|
-
jobs.
|
|
47
|
-
jobs.
|
|
14
|
+
jobs.merge!(load_yml_contents('sanity_framework'))
|
|
15
|
+
jobs.merge!(load_yml_contents('custom_parallel'))
|
|
16
|
+
jobs.merge!(load_yml_contents('instance', should_automatically_run?('test_instance_all')))
|
|
17
|
+
jobs.merge!(load_yml_contents('relative_url', should_automatically_run?('test_instance_all')))
|
|
18
|
+
jobs.merge!(load_yml_contents('decomposition_single_db', should_automatically_run?('test_instance_all')))
|
|
19
|
+
jobs.merge!(load_yml_contents('decomposition_multiple_db', should_automatically_run?('test_instance_all')))
|
|
20
|
+
jobs.merge!(load_yml_contents('repository_storage', should_automatically_run?('test_instance_all_repository_storage')))
|
|
21
|
+
jobs.merge!(load_yml_contents('omnibus_image'))
|
|
22
|
+
jobs.merge!(load_yml_contents('update', should_automatically_run?('test_instance_all')))
|
|
23
|
+
jobs.merge!(load_yml_contents('omnibus_upgrade'))
|
|
24
|
+
jobs.merge!(load_yml_contents('ee_previous_to_ce_update'))
|
|
25
|
+
jobs.merge!(load_yml_contents('mattermost', should_automatically_run?('test_integration_mattermost')))
|
|
26
|
+
jobs.merge!(load_yml_contents('service_ping_disabled', should_automatically_run?('test_integration_servicepingdisabled')))
|
|
27
|
+
jobs.merge!(load_yml_contents('ldap_no_tls', should_automatically_run?('test_integration_ldapnotls')))
|
|
28
|
+
jobs.merge!(load_yml_contents('ldap_tls', should_automatically_run?('test_integration_ldaptls')))
|
|
29
|
+
jobs.merge!(load_yml_contents('ldap_no_server', should_automatically_run?('test_integration_ldapnoserver')))
|
|
30
|
+
jobs.merge!(load_yml_contents('instance_saml', should_automatically_run?('test_integration_instancesaml')))
|
|
31
|
+
jobs.merge!(load_yml_contents('group_saml', should_automatically_run?('test_integration_groupsaml')))
|
|
32
|
+
jobs.merge!(load_yml_contents('object_storage', should_automatically_run?('test_instance_all_object_storage')))
|
|
33
|
+
jobs.merge!(load_yml_contents('object_storage_aws', should_automatically_run?('test_instance_all_object_storage')))
|
|
34
|
+
jobs.merge!(load_yml_contents('object_storage_gcs', should_automatically_run?('test_instance_all_object_storage')))
|
|
35
|
+
jobs.merge!(load_yml_contents('object_storage_registry_tls', should_automatically_run?('test_integration_registrytls')))
|
|
36
|
+
jobs.merge!(load_yml_contents('registry', should_automatically_run?('test_integration_registry')))
|
|
37
|
+
jobs.merge!(load_yml_contents('packages', should_automatically_run?('test_instance_all_packages')))
|
|
38
|
+
jobs.merge!(load_yml_contents('elasticsearch', should_automatically_run?('test_integration_elasticsearch')))
|
|
39
|
+
jobs.merge!(load_yml_contents('praefect', should_automatically_run?('test_instance_all')))
|
|
40
|
+
jobs.merge!(load_yml_contents('gitaly_cluster', should_automatically_run?('test_instance_all')))
|
|
41
|
+
jobs.merge!(load_yml_contents('mtls', should_automatically_run?('test_instance_all_mtls')))
|
|
42
|
+
jobs.merge!(load_yml_contents('smtp', should_automatically_run?('test_integration_smtp')))
|
|
43
|
+
jobs.merge!(load_yml_contents('jira', should_automatically_run?('test_instance_all_jira')))
|
|
44
|
+
jobs.merge!(load_yml_contents('integrations', should_automatically_run?('test_instance_all_integrations')))
|
|
45
|
+
jobs.merge!(load_yml_contents('large_setup', should_automatically_run?('test_instance_all_can_use_large_setup')))
|
|
46
|
+
jobs.merge!(load_yml_contents('cloud_activation', should_automatically_run?('test_instance_all_cloud_activation')))
|
|
47
|
+
jobs.merge!(load_yml_contents('registry_with_cdn', should_automatically_run?('test_integration_registrywithcdn')))
|
|
48
|
+
jobs.merge!(load_yml_contents('staging'))
|
|
48
49
|
|
|
49
50
|
# Disabling geo jobs temporarily due to https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/774
|
|
50
|
-
#
|
|
51
|
+
# jobs.merge!(load_yml_contents('geo', should_automatically_run?('scenario_test_geo')))
|
|
52
|
+
|
|
53
|
+
yaml_string = jobs.to_yaml
|
|
54
|
+
de_stringify_reference(yaml_string)
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
yaml_string
|
|
53
57
|
end
|
|
58
|
+
|
|
54
59
|
# rubocop:enable Metrics/AbcSize
|
|
55
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
|
56
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
57
60
|
|
|
58
61
|
private
|
|
59
62
|
|
|
60
|
-
def
|
|
63
|
+
def should_automatically_run?(example_file_name)
|
|
61
64
|
@no_of_example_files.include?(example_file_name)
|
|
62
65
|
end
|
|
63
66
|
|
|
64
|
-
def load_yml_contents(file_prefix)
|
|
67
|
+
def load_yml_contents(file_prefix, automatic = true)
|
|
65
68
|
jobs_dir_path = File.expand_path('../.gitlab/ci/jobs', __dir__)
|
|
66
|
-
File.read(File.join(jobs_dir_path, "#{file_prefix}.gitlab-ci.yml"))
|
|
69
|
+
file_contents = File.read(File.join(jobs_dir_path, "#{file_prefix}.gitlab-ci.yml"))
|
|
70
|
+
|
|
71
|
+
# Enclose !reference in double quotes at it is not supported with YAML.load
|
|
72
|
+
stringify_reference(file_contents)
|
|
73
|
+
yaml_hash = YAML.safe_load(file_contents)
|
|
74
|
+
|
|
75
|
+
yaml_hash.each { |key, value| value.merge!("when" => "manual") } unless automatic
|
|
76
|
+
|
|
77
|
+
yaml_hash
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def stringify_reference(str)
|
|
81
|
+
match_data = str.match(/!reference \[[a-zA-Z_, ]*\]/)
|
|
82
|
+
str.gsub!(match_data[0], "\"#{match_data[0]}\"") if match_data
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def de_stringify_reference(str)
|
|
86
|
+
match_data = str.match(/"(!reference \[[a-zA-Z_, ]*\])"/)
|
|
87
|
+
str.gsub!(match_data[0], match_data[1]) if match_data
|
|
67
88
|
end
|
|
68
89
|
end
|
|
69
90
|
|
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: 7.
|
|
4
|
+
version: 7.32.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: 2022-
|
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: climate_control
|
|
@@ -219,9 +219,10 @@ files:
|
|
|
219
219
|
- ".gitignore"
|
|
220
220
|
- ".gitlab-ci.yml"
|
|
221
221
|
- ".gitlab/ci/jobs/base.gitlab-ci.yml"
|
|
222
|
-
- ".gitlab/ci/jobs/ci_decomposition.gitlab-ci.yml"
|
|
223
222
|
- ".gitlab/ci/jobs/cloud_activation.gitlab-ci.yml"
|
|
224
223
|
- ".gitlab/ci/jobs/custom_parallel.gitlab-ci.yml"
|
|
224
|
+
- ".gitlab/ci/jobs/decomposition_multiple_db.gitlab-ci.yml"
|
|
225
|
+
- ".gitlab/ci/jobs/decomposition_single_db.gitlab-ci.yml"
|
|
225
226
|
- ".gitlab/ci/jobs/ee_previous_to_ce_update.gitlab-ci.yml"
|
|
226
227
|
- ".gitlab/ci/jobs/elasticsearch.gitlab-ci.yml"
|
|
227
228
|
- ".gitlab/ci/jobs/geo.gitlab-ci.yml"
|
|
@@ -336,7 +337,8 @@ files:
|
|
|
336
337
|
- lib/gitlab/qa/runtime/env.rb
|
|
337
338
|
- lib/gitlab/qa/runtime/logger.rb
|
|
338
339
|
- lib/gitlab/qa/runtime/omnibus_configuration.rb
|
|
339
|
-
- lib/gitlab/qa/runtime/omnibus_configurations/
|
|
340
|
+
- lib/gitlab/qa/runtime/omnibus_configurations/decomposition_multiple_db.rb
|
|
341
|
+
- lib/gitlab/qa/runtime/omnibus_configurations/decomposition_single_db.rb
|
|
340
342
|
- lib/gitlab/qa/runtime/omnibus_configurations/default.rb
|
|
341
343
|
- lib/gitlab/qa/runtime/omnibus_configurations/license_mode.rb
|
|
342
344
|
- lib/gitlab/qa/runtime/omnibus_configurations/object_storage.rb
|