gitlab-qa 8.0.0 → 8.3.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/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +0 -6
- data/.gitlab/ci/jobs/metrics.gitlab-ci.yml +41 -0
- data/.gitlab/ci/jobs/opensearch.gitlab-ci.yml +20 -0
- data/.gitlab-ci.yml +1 -0
- data/Gemfile.lock +22 -22
- data/docs/release_process.md +1 -0
- data/docs/trainings.md +2 -0
- data/docs/what_tests_can_be_run.md +2 -0
- data/lib/gitlab/qa/component/base.rb +6 -1
- data/lib/gitlab/qa/component/gitlab.rb +29 -12
- data/lib/gitlab/qa/component/opensearch.rb +33 -0
- data/lib/gitlab/qa/component/specs.rb +12 -3
- data/lib/gitlab/qa/docker/command.rb +4 -0
- data/lib/gitlab/qa/docker/engine.rb +8 -0
- data/lib/gitlab/qa/runtime/env.rb +8 -1
- data/lib/gitlab/qa/scenario/test/integration/metrics.rb +43 -0
- data/lib/gitlab/qa/scenario/test/integration/opensearch.rb +62 -0
- data/lib/gitlab/qa/scenario/test/omnibus/update.rb +38 -2
- data/lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb +115 -0
- data/lib/gitlab/qa/support/gitlab_upgrade_path.rb +94 -0
- data/lib/gitlab/qa/support/gitlab_version_info.rb +180 -0
- data/lib/gitlab/qa/version.rb +1 -1
- data/scripts/generate-qa-jobs.rb +2 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f11ebd2677dc7ba62bd4b55efc03ad8d9560c38a3e601897a9a201d3c09c8eae
|
|
4
|
+
data.tar.gz: f8db94175a79e62ae625e8b975fc49b03c4077ff608f40a85fa7ea7a5b3f859d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 21199373f3dff6e7e9204062fec4e204309e33d3bd50994285691aa8b833e926262ac9359810ba5f0cc1a624168693a7e4f195e3abc819088b5bc2f6736f4d07
|
|
7
|
+
data.tar.gz: a7dc574dceebed5e61b2383030cd114df7cabd00c974d5e548bed6364a031d6617f8495716fc8b7eb6043b6ad33eb8db33adc0f7cc7b0125871dca8a704c6f26
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
ee:cloud-activation:
|
|
2
|
-
before_script:
|
|
3
|
-
- unset EE_LICENSE
|
|
4
|
-
- !reference [default, before_script]
|
|
5
2
|
extends:
|
|
6
3
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
7
4
|
- .test
|
|
@@ -14,9 +11,6 @@ ee:cloud-activation:
|
|
|
14
11
|
GITLAB_QA_OPTIONS_COMBINED: "$GITLAB_QA_OPTIONS --seed-db license*.rb"
|
|
15
12
|
|
|
16
13
|
ee:cloud-activation-quarantine:
|
|
17
|
-
before_script:
|
|
18
|
-
- unset EE_LICENSE
|
|
19
|
-
- !reference [default, before_script]
|
|
20
14
|
extends:
|
|
21
15
|
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
22
16
|
- .test
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
ce:metrics:
|
|
2
|
+
extends:
|
|
3
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
|
4
|
+
- .test
|
|
5
|
+
- .high-capacity
|
|
6
|
+
- .ce-variables
|
|
7
|
+
- .rspec-report-opts
|
|
8
|
+
variables:
|
|
9
|
+
QA_SCENARIO: "Test::Integration::Metrics"
|
|
10
|
+
|
|
11
|
+
ce:metrics-quarantine:
|
|
12
|
+
extends:
|
|
13
|
+
- .rules:ce-never-when-triggered-by-feature-flag-definition-change
|
|
14
|
+
- .test
|
|
15
|
+
- .high-capacity
|
|
16
|
+
- .ce-variables
|
|
17
|
+
- .quarantine
|
|
18
|
+
- .rspec-report-opts
|
|
19
|
+
variables:
|
|
20
|
+
QA_SCENARIO: "Test::Integration::Metrics"
|
|
21
|
+
|
|
22
|
+
ee:metrics:
|
|
23
|
+
extends:
|
|
24
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
25
|
+
- .test
|
|
26
|
+
- .high-capacity
|
|
27
|
+
- .ee-variables
|
|
28
|
+
- .rspec-report-opts
|
|
29
|
+
variables:
|
|
30
|
+
QA_SCENARIO: "Test::Integration::Metrics"
|
|
31
|
+
|
|
32
|
+
ee:metrics-quarantine:
|
|
33
|
+
extends:
|
|
34
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
35
|
+
- .test
|
|
36
|
+
- .high-capacity
|
|
37
|
+
- .ee-variables
|
|
38
|
+
- .quarantine
|
|
39
|
+
- .rspec-report-opts
|
|
40
|
+
variables:
|
|
41
|
+
QA_SCENARIO: "Test::Integration::Metrics"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
ee:opensearch:
|
|
2
|
+
extends:
|
|
3
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
4
|
+
- .test
|
|
5
|
+
- .high-capacity
|
|
6
|
+
- .ee-variables
|
|
7
|
+
- .rspec-report-opts
|
|
8
|
+
variables:
|
|
9
|
+
QA_SCENARIO: "Test::Integration::Opensearch"
|
|
10
|
+
|
|
11
|
+
ee:opensearch-quarantine:
|
|
12
|
+
extends:
|
|
13
|
+
- .rules:ee-never-when-triggered-by-feature-flag-definition-change
|
|
14
|
+
- .test
|
|
15
|
+
- .high-capacity
|
|
16
|
+
- .ee-variables
|
|
17
|
+
- .quarantine
|
|
18
|
+
- .rspec-report-opts
|
|
19
|
+
variables:
|
|
20
|
+
QA_SCENARIO: "Test::Integration::Opensearch"
|
data/.gitlab-ci.yml
CHANGED
|
@@ -105,6 +105,7 @@ generate-jobs:
|
|
|
105
105
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag can_use_large_setup
|
|
106
106
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag cloud_activation
|
|
107
107
|
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag object_storage
|
|
108
|
+
- bundle exec bin/qa Test::Instance::All http://dummy.test --count-examples-only -- $QA_TESTS --tag metrics
|
|
108
109
|
- cp -r no_of_examples $CI_PROJECT_DIR
|
|
109
110
|
|
|
110
111
|
# TOP_UPSTREAM_DEFAULT_BRANCH is the default branch name of the original project that triggered a pipeline in this project.
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
gitlab-qa (8.
|
|
4
|
+
gitlab-qa (8.3.0)
|
|
5
5
|
activesupport (~> 6.1)
|
|
6
6
|
gitlab (~> 4.18.0)
|
|
7
7
|
http (~> 5.0)
|
|
@@ -13,7 +13,7 @@ PATH
|
|
|
13
13
|
GEM
|
|
14
14
|
remote: https://rubygems.org/
|
|
15
15
|
specs:
|
|
16
|
-
activesupport (6.1.6)
|
|
16
|
+
activesupport (6.1.6.1)
|
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
18
18
|
i18n (>= 1.6, < 2)
|
|
19
19
|
minitest (>= 5.1)
|
|
@@ -72,11 +72,11 @@ GEM
|
|
|
72
72
|
faraday-em_http (1.0.0)
|
|
73
73
|
faraday-em_synchrony (1.0.0)
|
|
74
74
|
faraday-excon (1.1.0)
|
|
75
|
-
faraday-http-cache (2.
|
|
75
|
+
faraday-http-cache (2.4.0)
|
|
76
76
|
faraday (>= 0.8)
|
|
77
77
|
faraday-httpclient (1.0.1)
|
|
78
|
-
faraday-multipart (1.0.
|
|
79
|
-
multipart-post (
|
|
78
|
+
faraday-multipart (1.0.4)
|
|
79
|
+
multipart-post (~> 2)
|
|
80
80
|
faraday-net_http (1.0.1)
|
|
81
81
|
faraday-net_http_persistent (1.2.0)
|
|
82
82
|
faraday-patron (1.0.0)
|
|
@@ -101,7 +101,7 @@ GEM
|
|
|
101
101
|
rubocop-rails (~> 2.9)
|
|
102
102
|
rubocop-rspec (~> 1.44)
|
|
103
103
|
hashdiff (1.0.1)
|
|
104
|
-
http (5.0
|
|
104
|
+
http (5.1.0)
|
|
105
105
|
addressable (~> 2.8)
|
|
106
106
|
http-cookie (~> 1.0)
|
|
107
107
|
http-form_data (~> 2.2)
|
|
@@ -112,7 +112,7 @@ GEM
|
|
|
112
112
|
httparty (0.20.0)
|
|
113
113
|
mime-types (~> 3.0)
|
|
114
114
|
multi_xml (>= 0.5.2)
|
|
115
|
-
i18n (1.
|
|
115
|
+
i18n (1.12.0)
|
|
116
116
|
concurrent-ruby (~> 1.0)
|
|
117
117
|
jaro_winkler (1.5.4)
|
|
118
118
|
kramdown (2.4.0)
|
|
@@ -127,17 +127,17 @@ GEM
|
|
|
127
127
|
mime-types-data (~> 3.2015)
|
|
128
128
|
mime-types-data (3.2022.0105)
|
|
129
129
|
mini_portile2 (2.8.0)
|
|
130
|
-
minitest (5.
|
|
130
|
+
minitest (5.16.2)
|
|
131
131
|
multi_xml (0.6.0)
|
|
132
|
-
multipart-post (2.
|
|
132
|
+
multipart-post (2.2.3)
|
|
133
133
|
nap (1.1.0)
|
|
134
134
|
no_proxy_fix (0.1.2)
|
|
135
|
-
nokogiri (1.13.
|
|
135
|
+
nokogiri (1.13.8)
|
|
136
136
|
mini_portile2 (~> 2.8.0)
|
|
137
137
|
racc (~> 1.4)
|
|
138
|
-
octokit (4.
|
|
139
|
-
faraday (>=
|
|
140
|
-
sawyer (~> 0.
|
|
138
|
+
octokit (4.25.1)
|
|
139
|
+
faraday (>= 1, < 3)
|
|
140
|
+
sawyer (~> 0.9)
|
|
141
141
|
open4 (1.3.4)
|
|
142
142
|
parallel (1.22.1)
|
|
143
143
|
parser (3.1.2.0)
|
|
@@ -147,11 +147,11 @@ GEM
|
|
|
147
147
|
method_source (~> 1.0)
|
|
148
148
|
public_suffix (4.0.7)
|
|
149
149
|
racc (1.6.0)
|
|
150
|
-
rack (2.2.
|
|
150
|
+
rack (2.2.4)
|
|
151
151
|
rainbow (3.0.0)
|
|
152
152
|
rake (13.0.6)
|
|
153
153
|
rchardet (1.8.0)
|
|
154
|
-
regexp_parser (2.
|
|
154
|
+
regexp_parser (2.5.0)
|
|
155
155
|
reverse_markdown (2.1.1)
|
|
156
156
|
nokogiri
|
|
157
157
|
rexml (3.2.5)
|
|
@@ -177,7 +177,7 @@ GEM
|
|
|
177
177
|
rubocop-ast (>= 0.6.0)
|
|
178
178
|
ruby-progressbar (~> 1.7)
|
|
179
179
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
180
|
-
rubocop-ast (1.
|
|
180
|
+
rubocop-ast (1.19.1)
|
|
181
181
|
parser (>= 3.1.1.0)
|
|
182
182
|
rubocop-gitlab-security (0.1.1)
|
|
183
183
|
rubocop (>= 0.51)
|
|
@@ -193,9 +193,9 @@ GEM
|
|
|
193
193
|
rubocop-ast (>= 0.7.1)
|
|
194
194
|
ruby-progressbar (1.11.0)
|
|
195
195
|
ruby2_keywords (0.0.5)
|
|
196
|
-
sawyer (0.
|
|
196
|
+
sawyer (0.9.2)
|
|
197
197
|
addressable (>= 2.3.5)
|
|
198
|
-
faraday (
|
|
198
|
+
faraday (>= 0.17.3, < 3)
|
|
199
199
|
solargraph (0.45.0)
|
|
200
200
|
backport (~> 1.2)
|
|
201
201
|
benchmark
|
|
@@ -215,8 +215,8 @@ GEM
|
|
|
215
215
|
terminal-table (3.0.2)
|
|
216
216
|
unicode-display_width (>= 1.1.1, < 3)
|
|
217
217
|
thor (1.2.1)
|
|
218
|
-
tilt (2.0.
|
|
219
|
-
tzinfo (2.0.
|
|
218
|
+
tilt (2.0.11)
|
|
219
|
+
tzinfo (2.0.5)
|
|
220
220
|
concurrent-ruby (~> 1.0)
|
|
221
221
|
unf (0.1.4)
|
|
222
222
|
unf_ext
|
|
@@ -227,9 +227,9 @@ GEM
|
|
|
227
227
|
crack (>= 0.3.2)
|
|
228
228
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
229
229
|
webrick (1.7.0)
|
|
230
|
-
yard (0.9.
|
|
230
|
+
yard (0.9.28)
|
|
231
231
|
webrick (~> 1.7.0)
|
|
232
|
-
zeitwerk (2.
|
|
232
|
+
zeitwerk (2.6.0)
|
|
233
233
|
|
|
234
234
|
PLATFORMS
|
|
235
235
|
ruby
|
data/docs/release_process.md
CHANGED
|
@@ -23,6 +23,7 @@ when we make a change - no matter the size of the change.
|
|
|
23
23
|
- If there is one, update it if necessary.
|
|
24
24
|
- If not, update [`lib/gitlab/qa/version.rb`] to an appropriate [semantic version](https://semver.org) in a new merge request using the [release template](https://gitlab.com/gitlab-org/gitlab-qa/blob/master/.gitlab/merge_request_templates/Release.md)
|
|
25
25
|
and title the MR like `"Bump version to <version>"`.
|
|
26
|
+
- Run `bundle update` to update the `Gemfile.lock` with the new version number of `gitlab-qa`.
|
|
26
27
|
- Merge the merge request.
|
|
27
28
|
- The new version should automatically be tagged and pushed to Rubygems by the `gem-release` job in the merge commit pipeline.
|
|
28
29
|
- Update the release notes for the newly created tag (https://gitlab.com/gitlab-org/gitlab-qa/-/tags):
|
data/docs/trainings.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# GitLab QA trainings
|
|
2
2
|
|
|
3
|
+
The handbook has [information about the entire test automation framework](https://about.gitlab.com/handbook/engineering/quality/#test-automation-framework), including GitLab QA. There you can find links to additional documentation and videos.
|
|
4
|
+
|
|
3
5
|
## Build team training on GitLab QA
|
|
4
6
|
|
|
5
7
|
A great introduction to the GitLab QA project, its internal structure, how it's
|
|
@@ -84,6 +84,7 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
|
|
|
84
84
|
| `QA_INFLUXDB_TOKEN` |- | Influxdb token for test metrics reporting | No|
|
|
85
85
|
| `QA_RUN_TYPE` |- | QA run type like `staging-full`, `canary`, `production` etc. Used in test metrics reporting | No|
|
|
86
86
|
| `QA_VALIDATE_RESOURCE_REUSE` | `false` | Set to `true` to [validate resource reuse](https://docs.gitlab.com/ee/development/testing_guide/end_to_end/resources.html#reusable-resources) after a test suite | No |
|
|
87
|
+
| `QA_USE_PUBLIC_IP_API` | `false` | When performing Instance tests against a remote/pre-existing instance, use an API to detect the public API for requests coming from gitlab-qa. Used by tests that exercise IP-address restrictions and similar
|
|
87
88
|
| `GITHUB_USERNAME` |- | Username for authenticating with GitHub. | No|
|
|
88
89
|
| `GITHUB_PASSWORD` |- | Password for authenticating with GitHub. | No|
|
|
89
90
|
| `GITLAB_QA_LOOP_RUNNER_MINUTES` | `1` | Minutes to run and repeat a spec while using the '--loop' option; default value is 1 minute. | No|
|
|
@@ -98,6 +99,7 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
|
|
|
98
99
|
| `GEO_FAILOVER` | `false` | Set to `true` when a Geo secondary site has been promoted to a Geo primary site. | No|
|
|
99
100
|
| `GITLAB_INITIAL_ROOT_PASSWORD` | `5iveL!fe` | Initial root password for Omnibus installations | No|
|
|
100
101
|
| `COLORIZED_LOGS` | `false` | Colors GitLab QA and test logs to improve readability | No|
|
|
102
|
+
| `QA_DOCKER_ADD_HOSTS` |- | Comma separated list of hosts to add to /etc/hosts in docker container | No|
|
|
101
103
|
|
|
102
104
|
## [Supported Remote Grid environment variables](./running_against_remote_grid.md)
|
|
103
105
|
|
|
@@ -7,13 +7,14 @@ module Gitlab
|
|
|
7
7
|
include Scenario::Actable
|
|
8
8
|
|
|
9
9
|
attr_reader :docker
|
|
10
|
-
attr_accessor :volumes, :network, :environment, :runner_network
|
|
10
|
+
attr_accessor :volumes, :ports, :network, :environment, :runner_network
|
|
11
11
|
attr_writer :name, :exec_commands
|
|
12
12
|
|
|
13
13
|
def initialize
|
|
14
14
|
@docker = Docker::Engine.new
|
|
15
15
|
@environment = {}
|
|
16
16
|
@volumes = {}
|
|
17
|
+
@ports = []
|
|
17
18
|
@network_aliases = []
|
|
18
19
|
@exec_commands = []
|
|
19
20
|
end
|
|
@@ -85,6 +86,10 @@ module Gitlab
|
|
|
85
86
|
command << "--net #{network}"
|
|
86
87
|
command << "--hostname #{hostname}"
|
|
87
88
|
|
|
89
|
+
@ports.each do |mapping|
|
|
90
|
+
command.port(mapping)
|
|
91
|
+
end
|
|
92
|
+
|
|
88
93
|
@volumes.to_h.each do |to, from|
|
|
89
94
|
command.volume(to, from, 'Z')
|
|
90
95
|
end
|
|
@@ -7,6 +7,7 @@ require 'uri'
|
|
|
7
7
|
require 'forwardable'
|
|
8
8
|
require 'openssl'
|
|
9
9
|
require 'tempfile'
|
|
10
|
+
require 'json'
|
|
10
11
|
|
|
11
12
|
module Gitlab
|
|
12
13
|
module QA
|
|
@@ -16,7 +17,7 @@ module Gitlab
|
|
|
16
17
|
using Rainbow
|
|
17
18
|
|
|
18
19
|
attr_reader :release, :omnibus_configuration, :omnibus_gitlab_rails_env
|
|
19
|
-
attr_accessor :tls, :skip_availability_check, :runner_network, :seed_admin_token, :seed_db
|
|
20
|
+
attr_accessor :tls, :skip_availability_check, :runner_network, :seed_admin_token, :seed_db, :skip_server_hooks
|
|
20
21
|
attr_writer :name, :relative_path
|
|
21
22
|
|
|
22
23
|
def_delegators :release, :tag, :image, :edition
|
|
@@ -46,6 +47,7 @@ module Gitlab
|
|
|
46
47
|
|
|
47
48
|
@seed_admin_token = Runtime::Scenario.seed_admin_token
|
|
48
49
|
@seed_db = Runtime::Scenario.seed_db
|
|
50
|
+
@skip_server_hooks = Runtime::Scenario.skip_server_hooks
|
|
49
51
|
|
|
50
52
|
self.release = 'CE'
|
|
51
53
|
end
|
|
@@ -83,8 +85,8 @@ module Gitlab
|
|
|
83
85
|
tls ? 'https' : 'http'
|
|
84
86
|
end
|
|
85
87
|
|
|
86
|
-
def
|
|
87
|
-
tls ?
|
|
88
|
+
def gitlab_port
|
|
89
|
+
tls ? ["443:443"] : ["80"]
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
def gitaly_tls
|
|
@@ -119,6 +121,10 @@ module Gitlab
|
|
|
119
121
|
super
|
|
120
122
|
end
|
|
121
123
|
|
|
124
|
+
def exist?(image, tag)
|
|
125
|
+
docker.manifest_exists?("#{image}:#{tag}")
|
|
126
|
+
end
|
|
127
|
+
|
|
122
128
|
def prepare_gitlab_omnibus_config
|
|
123
129
|
set_formless_login_token
|
|
124
130
|
set_license_mode
|
|
@@ -131,11 +137,15 @@ module Gitlab
|
|
|
131
137
|
ensure_configured!
|
|
132
138
|
|
|
133
139
|
docker.run(image: image, tag: tag) do |command|
|
|
134
|
-
command << "-d
|
|
140
|
+
command << "-d"
|
|
135
141
|
command << "--name #{name}"
|
|
136
142
|
command << "--net #{network}"
|
|
137
143
|
command << "--hostname #{hostname}"
|
|
138
144
|
|
|
145
|
+
[*@ports, *gitlab_port].each do |mapping|
|
|
146
|
+
command.port(mapping)
|
|
147
|
+
end
|
|
148
|
+
|
|
139
149
|
@volumes.to_h.each do |to, from|
|
|
140
150
|
command.volume(to, from, 'Z')
|
|
141
151
|
end
|
|
@@ -174,7 +184,7 @@ module Gitlab
|
|
|
174
184
|
name,
|
|
175
185
|
relative_path: relative_path,
|
|
176
186
|
scheme: scheme,
|
|
177
|
-
protocol_port:
|
|
187
|
+
protocol_port: gitlab_port.first.to_i
|
|
178
188
|
)
|
|
179
189
|
|
|
180
190
|
Runtime::Logger.info("Waiting for GitLab to become healthy ...")
|
|
@@ -192,7 +202,7 @@ module Gitlab
|
|
|
192
202
|
exec_commands << seed_admin_token_command if seed_admin_token
|
|
193
203
|
exec_commands << seed_test_data_command if seed_db
|
|
194
204
|
exec_commands << Runtime::Scenario.omnibus_exec_commands
|
|
195
|
-
exec_commands << add_git_server_hooks unless
|
|
205
|
+
exec_commands << add_git_server_hooks unless skip_server_hooks
|
|
196
206
|
|
|
197
207
|
commands = exec_commands.flatten.uniq
|
|
198
208
|
return if commands.empty?
|
|
@@ -202,18 +212,18 @@ module Gitlab
|
|
|
202
212
|
end
|
|
203
213
|
|
|
204
214
|
def rails_version
|
|
205
|
-
|
|
206
|
-
@release.image, @release.tag,
|
|
207
|
-
'/opt/gitlab/version-manifest.json'
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
manifest = JSON.parse(json)
|
|
215
|
+
manifest = JSON.parse(read_package_manifest)
|
|
211
216
|
{
|
|
212
217
|
sha: manifest['software']['gitlab-rails']['locked_version'],
|
|
213
218
|
source: manifest['software']['gitlab-rails']['locked_source']['git']
|
|
214
219
|
}
|
|
215
220
|
end
|
|
216
221
|
|
|
222
|
+
def package_version
|
|
223
|
+
manifest = JSON.parse(read_package_manifest)
|
|
224
|
+
manifest['software']['package-scripts']['locked_version']
|
|
225
|
+
end
|
|
226
|
+
|
|
217
227
|
def copy_key_file(env_key)
|
|
218
228
|
key_dir = ENV['CI_PROJECT_DIR'] || Dir.tmpdir
|
|
219
229
|
key_file = Tempfile.new(env_key.downcase, key_dir)
|
|
@@ -229,6 +239,13 @@ module Gitlab
|
|
|
229
239
|
|
|
230
240
|
private
|
|
231
241
|
|
|
242
|
+
def read_package_manifest
|
|
243
|
+
@docker.read_file(
|
|
244
|
+
@release.image, @release.tag,
|
|
245
|
+
'/opt/gitlab/version-manifest.json'
|
|
246
|
+
)
|
|
247
|
+
end
|
|
248
|
+
|
|
232
249
|
# Copy certs to a temporary directory in current working directory.
|
|
233
250
|
# This is needed for docker-in-docker ci environments where mount points outside of build dir are not accessible
|
|
234
251
|
#
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Component
|
|
6
|
+
class Opensearch < Base
|
|
7
|
+
DOCKER_IMAGE = 'opensearchproject/opensearch'
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
@name ||= "elastic68"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def tag
|
|
14
|
+
Runtime::Env.opensearch_version
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def start
|
|
18
|
+
@docker.run(image: image, tag: tag) do |command|
|
|
19
|
+
command << "-d"
|
|
20
|
+
command << "--name #{name}"
|
|
21
|
+
command << "--net #{network}"
|
|
22
|
+
command << "--publish 9200:9200"
|
|
23
|
+
command << "--publish 9300:9300"
|
|
24
|
+
|
|
25
|
+
command.env("discovery.type", "single-node")
|
|
26
|
+
command.env("ES_JAVA_OPTS", "-Xms512m -Xmx512m")
|
|
27
|
+
command.env("plugins.security.disabled", "true")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -23,9 +23,7 @@ module Gitlab
|
|
|
23
23
|
|
|
24
24
|
raise ArgumentError unless [suite, release].all?
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@docker.pull(image: qa_image) unless Runtime::Env.skip_pull?
|
|
26
|
+
docker_pull_qa_image_if_needed
|
|
29
27
|
|
|
30
28
|
Runtime::Logger.info("Running test suite `#{suite}` for #{release.project_name}")
|
|
31
29
|
|
|
@@ -52,6 +50,11 @@ module Gitlab
|
|
|
52
50
|
command.env('QA_HOSTNAME', hostname)
|
|
53
51
|
end
|
|
54
52
|
|
|
53
|
+
unless Runtime::Env.docker_add_hosts.empty?
|
|
54
|
+
hosts = Runtime::Env.docker_add_hosts.map { |host| "--add-host=#{host} " }.join
|
|
55
|
+
command << hosts # override /etc/hosts in docker container when test runs
|
|
56
|
+
end
|
|
57
|
+
|
|
55
58
|
env.merge(Runtime::Env.variables).each do |key, value|
|
|
56
59
|
command.env(key, value)
|
|
57
60
|
end
|
|
@@ -70,6 +73,12 @@ module Gitlab
|
|
|
70
73
|
|
|
71
74
|
private
|
|
72
75
|
|
|
76
|
+
def docker_pull_qa_image_if_needed
|
|
77
|
+
@docker.login(**release.login_params) if release.login_params
|
|
78
|
+
|
|
79
|
+
@docker.pull(image: qa_image) unless Runtime::Env.skip_pull?
|
|
80
|
+
end
|
|
81
|
+
|
|
73
82
|
def args_with_flags(args, feature_flag_set)
|
|
74
83
|
return args if feature_flag_set.empty?
|
|
75
84
|
|
|
@@ -110,6 +110,14 @@ module Gitlab
|
|
|
110
110
|
Docker::Command.execute("rm -f #{name}")
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
def manifest_exists?(name)
|
|
114
|
+
Docker::Command.execute("manifest inspect #{name}")
|
|
115
|
+
rescue Docker::Shellout::StatusError
|
|
116
|
+
false
|
|
117
|
+
else
|
|
118
|
+
true
|
|
119
|
+
end
|
|
120
|
+
|
|
113
121
|
def container_exists?(name)
|
|
114
122
|
Docker::Command.execute("container inspect #{name}")
|
|
115
123
|
rescue Docker::Shellout::StatusError
|
|
@@ -36,7 +36,6 @@ module Gitlab
|
|
|
36
36
|
'QA_SLOW_CONNECTION_LATENCY_MS' => :qa_slow_connection_latency_ms,
|
|
37
37
|
'QA_SLOW_CONNECTION_THROUGHPUT_KBPS' => :qa_slow_connection_throughput_kbps,
|
|
38
38
|
'QA_GENERATE_ALLURE_REPORT' => :generate_allure_report,
|
|
39
|
-
'QA_EE_ACTIVATION_CODE' => :ee_activation_code,
|
|
40
39
|
'QA_EXPORT_TEST_METRICS' => :qa_export_test_metrics,
|
|
41
40
|
'QA_INFLUXDB_URL' => :qa_influxdb_url,
|
|
42
41
|
'QA_INFLUXDB_TOKEN' => :qa_influxdb_token,
|
|
@@ -232,6 +231,10 @@ module Gitlab
|
|
|
232
231
|
env_var_value_if_defined('ELASTIC_VERSION') || '8.2.0'
|
|
233
232
|
end
|
|
234
233
|
|
|
234
|
+
def opensearch_version
|
|
235
|
+
env_var_value_if_defined('OPENSEARCH_VERSION') || '2.0.1'
|
|
236
|
+
end
|
|
237
|
+
|
|
235
238
|
def require_license!
|
|
236
239
|
return if ENV.include?('EE_LICENSE')
|
|
237
240
|
|
|
@@ -357,6 +360,10 @@ module Gitlab
|
|
|
357
360
|
"#{ci_project_name}-#{test_subset}"
|
|
358
361
|
end
|
|
359
362
|
|
|
363
|
+
def docker_add_hosts
|
|
364
|
+
(env_var_value_if_defined('QA_DOCKER_ADD_HOSTS') || '').split(',')
|
|
365
|
+
end
|
|
366
|
+
|
|
360
367
|
private
|
|
361
368
|
|
|
362
369
|
def enabled?(value, default: true)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Scenario
|
|
6
|
+
module Test
|
|
7
|
+
module Integration
|
|
8
|
+
class Metrics < Scenario::Template
|
|
9
|
+
PUMA_METRICS_SERVER_PORT = 8083
|
|
10
|
+
SIDEKIQ_METRICS_SERVER_PORT = 8082
|
|
11
|
+
|
|
12
|
+
def perform(release, *rspec_args)
|
|
13
|
+
Component::Gitlab.perform do |gitlab|
|
|
14
|
+
gitlab.release = release
|
|
15
|
+
gitlab.network = 'test'
|
|
16
|
+
gitlab.name = 'gitlab'
|
|
17
|
+
gitlab.ports = [PUMA_METRICS_SERVER_PORT, SIDEKIQ_METRICS_SERVER_PORT]
|
|
18
|
+
|
|
19
|
+
gitlab.omnibus_configuration << <<~RUBY
|
|
20
|
+
puma['exporter_enabled'] = true
|
|
21
|
+
puma['exporter_address'] = '0.0.0.0'
|
|
22
|
+
puma['exporter_port'] = #{PUMA_METRICS_SERVER_PORT}
|
|
23
|
+
sidekiq['metrics_enabled'] = true
|
|
24
|
+
sidekiq['listen_address'] = '0.0.0.0'
|
|
25
|
+
sidekiq['listen_port'] = #{SIDEKIQ_METRICS_SERVER_PORT}
|
|
26
|
+
RUBY
|
|
27
|
+
|
|
28
|
+
gitlab.instance do
|
|
29
|
+
Component::Specs.perform do |specs|
|
|
30
|
+
specs.suite = 'Test::Integration::Metrics'
|
|
31
|
+
specs.release = gitlab.release
|
|
32
|
+
specs.network = gitlab.network
|
|
33
|
+
specs.args = [gitlab.address, *rspec_args]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Scenario
|
|
6
|
+
module Test
|
|
7
|
+
module Integration
|
|
8
|
+
class Opensearch < Scenario::Template
|
|
9
|
+
attr_reader :gitlab_name, :spec_suite
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@gitlab_name = 'gitlab-opensearch'
|
|
13
|
+
# Currently the test suite that tests Advanced Search features is called 'Elasticsearch' which we hope to abstract to 'Advancedsearch' in the future
|
|
14
|
+
@spec_suite = 'QA::EE::Scenario::Test::Integration::Elasticsearch'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def before_perform(release)
|
|
18
|
+
raise ArgumentError, 'OpenSearch is an EE only feature!' unless release.ee?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def perform(release, *rspec_args)
|
|
22
|
+
release = QA::Release.new(release)
|
|
23
|
+
before_perform(release)
|
|
24
|
+
|
|
25
|
+
Component::Gitlab.perform do |gitlab|
|
|
26
|
+
gitlab.release = release
|
|
27
|
+
setup_opensearch_on gitlab
|
|
28
|
+
|
|
29
|
+
Component::Opensearch.perform do |opensearch|
|
|
30
|
+
opensearch.network = 'test'
|
|
31
|
+
opensearch.instance do
|
|
32
|
+
gitlab.instance do
|
|
33
|
+
Runtime::Logger.info("Running #{spec_suite} specs!")
|
|
34
|
+
|
|
35
|
+
Component::Specs.perform do |specs|
|
|
36
|
+
specs.suite = spec_suite
|
|
37
|
+
specs.release = gitlab.release
|
|
38
|
+
specs.network = gitlab.network
|
|
39
|
+
specs.args = [gitlab.address, *rspec_args]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def empty_index
|
|
48
|
+
@empty_index ||= ["gitlab-rake gitlab:elastic:create_empty_index"]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def setup_opensearch_on(instance)
|
|
52
|
+
instance.name = gitlab_name
|
|
53
|
+
instance.network = 'test'
|
|
54
|
+
instance.elastic_url = "http://elastic68:9200"
|
|
55
|
+
instance.exec_commands = empty_index
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -10,8 +10,44 @@ module Gitlab
|
|
|
10
10
|
module Omnibus
|
|
11
11
|
class Update < Scenario::Template
|
|
12
12
|
def perform(from_release, to_release = nil, *rspec_args)
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
version = Component::Gitlab.perform do |gitlab|
|
|
14
|
+
gitlab.release = from_release
|
|
15
|
+
gitlab.act do
|
|
16
|
+
pull
|
|
17
|
+
package_version
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if version
|
|
22
|
+
# Sub any plus symbols in version eg. "15.1.2+ce.0"
|
|
23
|
+
version.tr!('+', '-')
|
|
24
|
+
Runtime::Logger.info("Found previous version '#{version}'")
|
|
25
|
+
|
|
26
|
+
current_release = QA::Release.new(to_release || from_release)
|
|
27
|
+
|
|
28
|
+
type = current_release.ee? ? 'ee' : 'ce'
|
|
29
|
+
|
|
30
|
+
existing_previous = Component::Gitlab.perform do |gitlab|
|
|
31
|
+
gitlab.act do
|
|
32
|
+
next "gitlab/gitlab-#{type}:#{version}" if exist?("gitlab/gitlab-#{type}", version)
|
|
33
|
+
|
|
34
|
+
next "gitlab/gitlab-#{type}:#{version}-#{type}.0" if exist?("gitlab/gitlab-#{type}", "#{version}-#{type}.0")
|
|
35
|
+
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
Runtime::Logger.info("Could not find previous image version")
|
|
41
|
+
existing_previous = nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
previous_release = if existing_previous
|
|
45
|
+
Runtime::Logger.info("Using previous image '#{existing_previous}'")
|
|
46
|
+
QA::Release.new(existing_previous)
|
|
47
|
+
else
|
|
48
|
+
Runtime::Logger.info("Using stable as previous image")
|
|
49
|
+
QA::Release.new(from_release).previous_stable
|
|
50
|
+
end
|
|
15
51
|
|
|
16
52
|
Docker::Volumes.new.with_temporary_volumes do |volumes|
|
|
17
53
|
Component::Gitlab.perform do |gitlab|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Scenario
|
|
6
|
+
module Test
|
|
7
|
+
module Omnibus
|
|
8
|
+
class UpdateFromPrevious < Scenario::Template
|
|
9
|
+
using Rainbow
|
|
10
|
+
|
|
11
|
+
# Test update from N - 1 (major|minor|patch) version to current release
|
|
12
|
+
# Run smoke test suite on previous release to populate some data in database before update
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# perform(gitlab-ee:dev-tag, 15.3.0-pre, major)
|
|
16
|
+
# => will perform upgrades 14.9.5 -> 15.0.5 -> gitlab-ee:dev-tag
|
|
17
|
+
#
|
|
18
|
+
# @param [String] release current release docker image
|
|
19
|
+
# @param [String] current_version current gitlab version associated with docker image
|
|
20
|
+
# @param [String] semver_component semver component for N - 1 version detection, major|minor|patch
|
|
21
|
+
# @param [Array] *rspec_args rspec arguments
|
|
22
|
+
# @return [void]
|
|
23
|
+
def perform(release, current_version, semver_component, *rspec_args)
|
|
24
|
+
@current_release = QA::Release.new(release)
|
|
25
|
+
@upgrade_path = Support::GitlabUpgradePath.new(
|
|
26
|
+
current_version,
|
|
27
|
+
semver_component,
|
|
28
|
+
@current_release.edition
|
|
29
|
+
).fetch
|
|
30
|
+
|
|
31
|
+
upgrade_info = "#{[*upgrade_path, current_release].join(' => ')} (#{current_version})".bright
|
|
32
|
+
Runtime::Logger.info("Performing gitlab update: #{upgrade_info}")
|
|
33
|
+
|
|
34
|
+
update(rspec_args)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
attr_reader :current_release, :upgrade_path
|
|
40
|
+
|
|
41
|
+
# Perform update
|
|
42
|
+
#
|
|
43
|
+
# @param [Array] rspec_args
|
|
44
|
+
# @return [void]
|
|
45
|
+
def update(rspec_args)
|
|
46
|
+
Docker::Volumes.new.with_temporary_volumes do |volumes|
|
|
47
|
+
# deploy first release in upgrade path and run specs to populate db
|
|
48
|
+
run_gitlab(upgrade_path.first, volumes, ["--", "--tag", "smoke"])
|
|
49
|
+
|
|
50
|
+
# deploy releases in upgrade path
|
|
51
|
+
upgrade_path[1..].each { |release| run_gitlab(release, volumes, skip_setup: true) }
|
|
52
|
+
|
|
53
|
+
# deploy current release and run tests
|
|
54
|
+
run_gitlab(current_release, volumes, rspec_args, skip_setup: true)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Deploy gitlab instance and optionally run specs
|
|
59
|
+
#
|
|
60
|
+
# @param [Gitlab::QA::Release] release
|
|
61
|
+
# @param [Hash] volumes
|
|
62
|
+
# @return [void]
|
|
63
|
+
def run_gitlab(release, volumes, rspec_args = [], skip_setup: false)
|
|
64
|
+
Runtime::Logger.info("Deploying release: #{release.to_s.bright}")
|
|
65
|
+
|
|
66
|
+
Component::Gitlab.perform do |gitlab|
|
|
67
|
+
gitlab.release = release
|
|
68
|
+
gitlab.volumes = volumes
|
|
69
|
+
gitlab.network = 'test'
|
|
70
|
+
|
|
71
|
+
if skip_setup
|
|
72
|
+
gitlab.skip_server_hooks = true
|
|
73
|
+
gitlab.seed_db = false
|
|
74
|
+
gitlab.seed_admin_token = false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
next gitlab.launch_and_teardown_instance unless run_specs?(release)
|
|
78
|
+
|
|
79
|
+
gitlab.instance { run_specs(gitlab, release, rspec_args) }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Run specs
|
|
84
|
+
#
|
|
85
|
+
# @param [Gitlab::QA::Component::Gitlab] gitlab
|
|
86
|
+
# @param [Gitlab::QA::Release] release
|
|
87
|
+
# @param [Array] rspec_args
|
|
88
|
+
# @return [void]
|
|
89
|
+
def run_specs(gitlab, release, rspec_args)
|
|
90
|
+
Component::Specs.perform do |specs|
|
|
91
|
+
specs.release = release
|
|
92
|
+
specs.suite = 'Test::Instance::All'
|
|
93
|
+
specs.hostname = "qa-e2e-specs.#{gitlab.network}"
|
|
94
|
+
specs.network = gitlab.network
|
|
95
|
+
specs.args = [gitlab.address, *rspec_args]
|
|
96
|
+
end
|
|
97
|
+
rescue Docker::Shellout::StatusError => e
|
|
98
|
+
raise e if release == current_release # only fail on current release
|
|
99
|
+
|
|
100
|
+
Runtime::Logger.warn("Test run for release '#{gitlab.release}' finished with errors!")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Run specs on first release to populate database and release being tested
|
|
104
|
+
#
|
|
105
|
+
# @param [Gitlab::QA::Release] release
|
|
106
|
+
# @return [Boolean]
|
|
107
|
+
def run_specs?(release)
|
|
108
|
+
[upgrade_path.first, current_release].any? { |rel| rel == release }
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/module/delegation"
|
|
4
|
+
require "yaml"
|
|
5
|
+
|
|
6
|
+
module Gitlab
|
|
7
|
+
module QA
|
|
8
|
+
module Support
|
|
9
|
+
class GitlabUpgradePath
|
|
10
|
+
# Get upgrade path between N - 1 and current version not including current release
|
|
11
|
+
#
|
|
12
|
+
# @param [String] current_version
|
|
13
|
+
# @param [String] semver_component version number component for previous version detection - major|minor|patch
|
|
14
|
+
# @param [String] edition GitLab edition - ee or ce
|
|
15
|
+
def initialize(current_version, semver_component, edition)
|
|
16
|
+
@version_info = GitlabVersionInfo.new(current_version, edition)
|
|
17
|
+
@current_version = Gem::Version.new(current_version)
|
|
18
|
+
@semver_component = semver_component
|
|
19
|
+
@edition = edition
|
|
20
|
+
@logger = Runtime::Logger.logger
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Get upgrade path between releases
|
|
24
|
+
#
|
|
25
|
+
# Return array with only previous version for updates from previous minor, patch versions
|
|
26
|
+
#
|
|
27
|
+
# @return [Array<QA::Release>]
|
|
28
|
+
def fetch
|
|
29
|
+
return [release(latest_patch(previous_version))] unless major_upgrade?
|
|
30
|
+
|
|
31
|
+
# get versions between previous major and current version in gitlab upgrade path
|
|
32
|
+
path = full_upgrade_path.each_with_object([]) do |ver, arr|
|
|
33
|
+
next if ver <= previous_version || ver >= current_version
|
|
34
|
+
|
|
35
|
+
arr << ver
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
[previous_version, *path].map do |ver|
|
|
39
|
+
release(version_info.latest_patch(ver))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
delegate :latest_patch, to: :version_info
|
|
46
|
+
|
|
47
|
+
attr_reader :version_info, :current_version, :semver_component, :edition, :logger
|
|
48
|
+
|
|
49
|
+
# Upgrade from previous major
|
|
50
|
+
#
|
|
51
|
+
# @return [Boolean]
|
|
52
|
+
def major_upgrade?
|
|
53
|
+
semver_component == "major"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Docker release image
|
|
57
|
+
#
|
|
58
|
+
# @param [String] version
|
|
59
|
+
# @return [QA::Release]
|
|
60
|
+
def release(version)
|
|
61
|
+
QA::Release.new("gitlab/gitlab-#{edition}:#{version}-#{edition}.0")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Previous gitlab version
|
|
65
|
+
#
|
|
66
|
+
# @return [Gem::Version]
|
|
67
|
+
def previous_version
|
|
68
|
+
@previous_version ||= version_info.previous_version(semver_component)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Gitlab upgrade path
|
|
72
|
+
#
|
|
73
|
+
# @return [Array<Gem::Version>]
|
|
74
|
+
def full_upgrade_path
|
|
75
|
+
@full_upgrade_path ||= ::YAML
|
|
76
|
+
.safe_load(upgrade_path_yml, symbolize_names: true)
|
|
77
|
+
.map { |version| Gem::Version.new("#{version[:major]}.#{version[:minor]}") }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Upgrade path yml
|
|
81
|
+
#
|
|
82
|
+
# @return [String]
|
|
83
|
+
def upgrade_path_yml
|
|
84
|
+
@upgrade_path_yml ||= begin
|
|
85
|
+
logger.info("Fetching gitlab upgrade path from 'gitlab-com/support/toolbox/upgrade-path' project")
|
|
86
|
+
HttpRequest.make_http_request(
|
|
87
|
+
url: "https://gitlab.com/gitlab-com/support/toolbox/upgrade-path/-/raw/main/upgrade-path.yml"
|
|
88
|
+
).body
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module QA
|
|
5
|
+
module Support
|
|
6
|
+
class GitlabVersionInfo
|
|
7
|
+
VERSION_PATTERN = /^(?<version>\d+\.\d+\.\d+)/.freeze
|
|
8
|
+
COMPONENT_PATTERN = /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/.freeze
|
|
9
|
+
|
|
10
|
+
# Get previous gitlab version
|
|
11
|
+
#
|
|
12
|
+
# @param [String] current_version
|
|
13
|
+
# @param [String] edition GitLab edition - ee or ce
|
|
14
|
+
def initialize(current_version, edition)
|
|
15
|
+
@current_version = current_version
|
|
16
|
+
@edition = edition
|
|
17
|
+
@logger = Runtime::Logger.logger
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Get N - 1 version number
|
|
21
|
+
#
|
|
22
|
+
# @param [String] semver_component version number component for previous version detection - major|minor|patch
|
|
23
|
+
# @return [Gem::Version]
|
|
24
|
+
def previous_version(semver_component)
|
|
25
|
+
case semver_component
|
|
26
|
+
when "major"
|
|
27
|
+
previous_major
|
|
28
|
+
when "minor"
|
|
29
|
+
previous_minor
|
|
30
|
+
when "patch"
|
|
31
|
+
previous_patch
|
|
32
|
+
else
|
|
33
|
+
raise("Unsupported semver component, must be major|minor|patch")
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Get latest patch for specific version number
|
|
38
|
+
#
|
|
39
|
+
# @example
|
|
40
|
+
# latest_patch(Gem::Version.new("14.10")) => "14.10.5"
|
|
41
|
+
#
|
|
42
|
+
# @param [Gem::Version] version
|
|
43
|
+
# @return [String]
|
|
44
|
+
def latest_patch(version)
|
|
45
|
+
versions.find { |ver| ver.to_s.match?(/^#{version}/) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
attr_reader :current_version, :edition, :logger
|
|
51
|
+
|
|
52
|
+
# Current versions major version
|
|
53
|
+
#
|
|
54
|
+
# @return [Integer]
|
|
55
|
+
def current_major
|
|
56
|
+
@current_major ||= current_version.match(COMPONENT_PATTERN)[:major].to_i
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Current versions minor version
|
|
60
|
+
#
|
|
61
|
+
# @return [Integer]
|
|
62
|
+
def current_minor
|
|
63
|
+
@current_minor ||= current_version.match(COMPONENT_PATTERN)[:minor].to_i
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Current versions patch version
|
|
67
|
+
#
|
|
68
|
+
# @return [Integer]
|
|
69
|
+
def current_patch
|
|
70
|
+
@current_patch ||= current_version.match(COMPONENT_PATTERN)[:patch].to_i
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Previous major version
|
|
74
|
+
#
|
|
75
|
+
# @return [String]
|
|
76
|
+
def previous_major
|
|
77
|
+
return fallback_major unless tags
|
|
78
|
+
|
|
79
|
+
versions.find { |version| version.to_s.start_with?((current_major - 1).to_s) }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Previous first major version image
|
|
83
|
+
#
|
|
84
|
+
# @return [String]
|
|
85
|
+
def fallback_major
|
|
86
|
+
previous_fallback_version(current_major - 1)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Previous minor version
|
|
90
|
+
#
|
|
91
|
+
# @return [String]
|
|
92
|
+
def previous_minor
|
|
93
|
+
return fallback_minor unless tags
|
|
94
|
+
return previous_major if current_minor.zero?
|
|
95
|
+
|
|
96
|
+
versions.find { |version| version.to_s.match?(/^#{current_major}\.#{current_minor - 1}/) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Previous first minor version
|
|
100
|
+
#
|
|
101
|
+
# @return [String]
|
|
102
|
+
def fallback_minor
|
|
103
|
+
return previous_fallback_version(current_major, current_minor - 1) unless current_minor.zero?
|
|
104
|
+
|
|
105
|
+
previous_major
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Previous patch version
|
|
109
|
+
#
|
|
110
|
+
# @return [String]
|
|
111
|
+
def previous_patch
|
|
112
|
+
return fallback_patch unless tags
|
|
113
|
+
return previous_minor if current_patch.zero?
|
|
114
|
+
|
|
115
|
+
versions.find { |version| version.to_s.match?(/^#{current_major}\.#{current_minor}\.#{current_patch - 1}/) }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Previous first patch version
|
|
119
|
+
#
|
|
120
|
+
# @return [String]
|
|
121
|
+
def fallback_patch
|
|
122
|
+
return previous_fallback_version(current_major, current_minor, current_patch - 1) unless current_patch.zero?
|
|
123
|
+
|
|
124
|
+
previous_minor
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Version number from docker tag
|
|
128
|
+
#
|
|
129
|
+
# @param [String] tag
|
|
130
|
+
# @return [String]
|
|
131
|
+
def version(tag)
|
|
132
|
+
tag.match(VERSION_PATTERN)[:version]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Fallback version
|
|
136
|
+
#
|
|
137
|
+
# @param [Integer] major_component
|
|
138
|
+
# @param [Integer] minor_component
|
|
139
|
+
# @param [Integer] patch_component
|
|
140
|
+
# @return [Gem::Version]
|
|
141
|
+
def previous_fallback_version(major_component, minor_component = 0, patch_component = 0)
|
|
142
|
+
Gem::Version.new("#{major_component}.#{minor_component}.#{patch_component}")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# All available gitlab versions
|
|
146
|
+
#
|
|
147
|
+
# @return [Array<String>]
|
|
148
|
+
def versions
|
|
149
|
+
@versions = tags
|
|
150
|
+
.map { |tag| Gem::Version.new(tag.match(VERSION_PATTERN)[:version]) }
|
|
151
|
+
.sort
|
|
152
|
+
.reverse # reverse array so first match by .find always returns latest version
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# All available docker tags
|
|
156
|
+
#
|
|
157
|
+
# @return [Array<String>]
|
|
158
|
+
def tags
|
|
159
|
+
return @tags if defined?(@tags)
|
|
160
|
+
|
|
161
|
+
logger.info("Fetching docker tags from 'gitlab/gitlab-#{edition}' registry")
|
|
162
|
+
response = HttpRequest.make_http_request(
|
|
163
|
+
url: "https://registry.hub.docker.com/v1/repositories/gitlab/gitlab-#{edition}/tags",
|
|
164
|
+
fail_on_error: false
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
unless response.code == 200
|
|
168
|
+
logger.error(" failed to fetch docker tags - code: #{response.code}, response: '#{response.body}'")
|
|
169
|
+
return @tags = nil
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
@tags = JSON
|
|
173
|
+
.parse(response.body, symbolize_names: true)
|
|
174
|
+
.map { |tag| tag[:name] }
|
|
175
|
+
.select { |tag| tag.match?(VERSION_PATTERN) }
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
data/lib/gitlab/qa/version.rb
CHANGED
data/scripts/generate-qa-jobs.rb
CHANGED
|
@@ -37,6 +37,7 @@ class GenerateQAJobs
|
|
|
37
37
|
jobs.merge!(load_yml_contents('registry', should_automatically_run?('test_integration_registry')))
|
|
38
38
|
jobs.merge!(load_yml_contents('packages', should_automatically_run?('test_instance_all_packages')))
|
|
39
39
|
jobs.merge!(load_yml_contents('elasticsearch', should_automatically_run?('test_integration_elasticsearch')))
|
|
40
|
+
jobs.merge!(load_yml_contents('opensearch', should_automatically_run?('test_integration_opensearch')))
|
|
40
41
|
jobs.merge!(load_yml_contents('praefect', should_automatically_run?('test_instance_all')))
|
|
41
42
|
jobs.merge!(load_yml_contents('gitaly_cluster', should_automatically_run?('test_instance_all')))
|
|
42
43
|
jobs.merge!(load_yml_contents('mtls', should_automatically_run?('test_instance_all_mtls')))
|
|
@@ -47,6 +48,7 @@ class GenerateQAJobs
|
|
|
47
48
|
jobs.merge!(load_yml_contents('cloud_activation', should_automatically_run?('test_instance_all_cloud_activation')))
|
|
48
49
|
jobs.merge!(load_yml_contents('registry_with_cdn', should_automatically_run?('test_integration_registrywithcdn')))
|
|
49
50
|
jobs.merge!(load_yml_contents('staging'))
|
|
51
|
+
jobs.merge!(load_yml_contents('metrics', should_automatically_run?('test_instance_all_metrics')))
|
|
50
52
|
|
|
51
53
|
# Disabling geo jobs temporarily due to https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/774
|
|
52
54
|
# jobs.merge!(load_yml_contents('geo', should_automatically_run?('scenario_test_geo')))
|
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: 8.
|
|
4
|
+
version: 8.3.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-08-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: climate_control
|
|
@@ -251,6 +251,7 @@ files:
|
|
|
251
251
|
- ".gitlab/ci/jobs/ldap_no_tls.gitlab-ci.yml"
|
|
252
252
|
- ".gitlab/ci/jobs/ldap_tls.gitlab-ci.yml"
|
|
253
253
|
- ".gitlab/ci/jobs/mattermost.gitlab-ci.yml"
|
|
254
|
+
- ".gitlab/ci/jobs/metrics.gitlab-ci.yml"
|
|
254
255
|
- ".gitlab/ci/jobs/mtls.gitlab-ci.yml"
|
|
255
256
|
- ".gitlab/ci/jobs/object_storage.gitlab-ci.yml"
|
|
256
257
|
- ".gitlab/ci/jobs/object_storage_aws.gitlab-ci.yml"
|
|
@@ -258,6 +259,7 @@ files:
|
|
|
258
259
|
- ".gitlab/ci/jobs/object_storage_registry_tls.gitlab-ci.yml"
|
|
259
260
|
- ".gitlab/ci/jobs/omnibus_image.gitlab-ci.yml"
|
|
260
261
|
- ".gitlab/ci/jobs/omnibus_upgrade.gitlab-ci.yml"
|
|
262
|
+
- ".gitlab/ci/jobs/opensearch.gitlab-ci.yml"
|
|
261
263
|
- ".gitlab/ci/jobs/packages.gitlab-ci.yml"
|
|
262
264
|
- ".gitlab/ci/jobs/praefect.gitlab-ci.yml"
|
|
263
265
|
- ".gitlab/ci/jobs/registry.gitlab-ci.yml"
|
|
@@ -316,6 +318,7 @@ files:
|
|
|
316
318
|
- lib/gitlab/qa/component/ldap.rb
|
|
317
319
|
- lib/gitlab/qa/component/mail_hog.rb
|
|
318
320
|
- lib/gitlab/qa/component/minio.rb
|
|
321
|
+
- lib/gitlab/qa/component/opensearch.rb
|
|
319
322
|
- lib/gitlab/qa/component/postgresql.rb
|
|
320
323
|
- lib/gitlab/qa/component/preprod.rb
|
|
321
324
|
- lib/gitlab/qa/component/production.rb
|
|
@@ -394,7 +397,9 @@ files:
|
|
|
394
397
|
- lib/gitlab/qa/scenario/test/integration/ldap_no_tls.rb
|
|
395
398
|
- lib/gitlab/qa/scenario/test/integration/ldap_tls.rb
|
|
396
399
|
- lib/gitlab/qa/scenario/test/integration/mattermost.rb
|
|
400
|
+
- lib/gitlab/qa/scenario/test/integration/metrics.rb
|
|
397
401
|
- lib/gitlab/qa/scenario/test/integration/mtls.rb
|
|
402
|
+
- lib/gitlab/qa/scenario/test/integration/opensearch.rb
|
|
398
403
|
- lib/gitlab/qa/scenario/test/integration/praefect.rb
|
|
399
404
|
- lib/gitlab/qa/scenario/test/integration/registry.rb
|
|
400
405
|
- lib/gitlab/qa/scenario/test/integration/registry_tls.rb
|
|
@@ -405,11 +410,14 @@ files:
|
|
|
405
410
|
- lib/gitlab/qa/scenario/test/integration/ssh_tunnel.rb
|
|
406
411
|
- lib/gitlab/qa/scenario/test/omnibus/image.rb
|
|
407
412
|
- lib/gitlab/qa/scenario/test/omnibus/update.rb
|
|
413
|
+
- lib/gitlab/qa/scenario/test/omnibus/update_from_previous.rb
|
|
408
414
|
- lib/gitlab/qa/scenario/test/omnibus/upgrade.rb
|
|
409
415
|
- lib/gitlab/qa/scenario/test/sanity/version.rb
|
|
410
416
|
- lib/gitlab/qa/slack/post_to_slack.rb
|
|
411
417
|
- lib/gitlab/qa/support/dev_ee_qa_image.rb
|
|
412
418
|
- lib/gitlab/qa/support/get_request.rb
|
|
419
|
+
- lib/gitlab/qa/support/gitlab_upgrade_path.rb
|
|
420
|
+
- lib/gitlab/qa/support/gitlab_version_info.rb
|
|
413
421
|
- lib/gitlab/qa/support/http_request.rb
|
|
414
422
|
- lib/gitlab/qa/support/invalid_response_error.rb
|
|
415
423
|
- lib/gitlab/qa/test_logger.rb
|