gitlab-qa 14.2.1 → 14.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/Gemfile.lock +1 -1
- data/docs/specifics_for_macos_m1_m2.md +14 -5
- data/docs/what_tests_can_be_run.md +68 -4
- data/lib/gitlab/qa/component/base.rb +4 -0
- data/lib/gitlab/qa/runtime/env.rb +3 -1
- data/lib/gitlab/qa/scenario/test/instance/repository_storage.rb +60 -14
- data/lib/gitlab/qa/scenario/test/integration/ai_gateway.rb +3 -71
- data/lib/gitlab/qa/scenario/test/integration/ai_gateway_base.rb +87 -0
- data/lib/gitlab/qa/scenario/test/integration/ai_gateway_no_add_on.rb +20 -0
- data/lib/gitlab/qa/scenario/test/integration/ai_gateway_no_license.rb +20 -0
- data/lib/gitlab/qa/scenario/test/integration/ai_gateway_no_seat_assigned.rb +19 -0
- data/lib/gitlab/qa/version.rb +1 -1
- data/rubocop/cop/gitlab/dangerous_interpolation.rb +157 -0
- data/support/setup/{code_suggestions_setup.rb → duo_pro_setup.rb} +17 -17
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bef7bd332a79ee7f62016c94ad14f6f681b8c957a9f1e862e772704b0dae9e87
|
4
|
+
data.tar.gz: 752ee71edfbbe0f9132da6dd54b201f8772cc396cd90947f9b9c37e5f027fd91
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b17db04aed34a0419361afbc7a5d3986da58be13bd2cf2c446b8442e3133eb18b56822ec9a0da686e599dc32c20c1d21545029eb75983aae6b1c956a82617c59
|
7
|
+
data.tar.gz: e7e6d86cd7c781c6dd4f1ab70a50e3a601338a2362e8b5ad7d7200aa43845bc0217056753f92e47de765658cdb2d8f8a3f52628ae2c139060cfbfe4c697118c3
|
data/.rubocop.yml
CHANGED
@@ -7,6 +7,9 @@ inherit_from:
|
|
7
7
|
- '.rubocop_todo.yml'
|
8
8
|
<% end %>
|
9
9
|
|
10
|
+
require:
|
11
|
+
- ./rubocop/cop/gitlab/dangerous_interpolation.rb
|
12
|
+
|
10
13
|
AllCops:
|
11
14
|
NewCops: enable
|
12
15
|
SuggestExtensions: false
|
@@ -51,6 +54,11 @@ CodeReuse/ActiveRecord:
|
|
51
54
|
Style/OperatorMethodCall:
|
52
55
|
Enabled: false
|
53
56
|
|
57
|
+
Gitlab/DangerousInterpolation:
|
58
|
+
Enabled: true
|
59
|
+
Include:
|
60
|
+
- 'lib/gitlab/qa/runtime/*'
|
61
|
+
|
54
62
|
# disable for now as it might break automatic publish
|
55
63
|
Gemspec/RequireMFA:
|
56
64
|
Enabled: false
|
data/Gemfile.lock
CHANGED
@@ -37,8 +37,17 @@ To resolve these issues:
|
|
37
37
|
$ export CHROME_DISABLE_DEV_SHM=true
|
38
38
|
# Disable Chrome shared memory
|
39
39
|
```
|
40
|
-
|
41
|
-
|
42
|
-
1.
|
43
|
-
|
44
|
-
|
40
|
+
|
41
|
+
2. Enable **Rosetta for x86/amd64 emulation on Apple Silicon**
|
42
|
+
1. Using Docker (Based on Docker Desktop ~v4.22.1):
|
43
|
+
1. Open **Settings** in Docker Desktop
|
44
|
+
1. Go to **Features in development**
|
45
|
+
1. Enable **Use Rosetta for x86/amd64 emulation on Apple Silicon** setting
|
46
|
+
1. Select **Apply & restart**
|
47
|
+
1. Using Rancher Desktop
|
48
|
+
1. Open **Preferences > Virtual Machine > Emulation**
|
49
|
+
1. Enable **VZ**
|
50
|
+
1. Enable **Enable Rosetta support**
|
51
|
+
1. Using Colima
|
52
|
+
1. Start with `colima start --arch aarch64 --vm-type=vz --vz-rosetta`
|
53
|
+
1. If this fails remove current configuration with `colima delete default` and retry
|
@@ -1026,11 +1026,15 @@ These tests verify features related to multiple repository storages.
|
|
1026
1026
|
**Required environment variables:**
|
1027
1027
|
|
1028
1028
|
- `QA_ADDITIONAL_REPOSITORY_STORAGE`: The name of the non-default repository storage.
|
1029
|
+
- `QA_PRAEFECT_REPOSITORY_STORAGE`: The name of the gitaly cluster (praefect) repository storage.
|
1030
|
+
- `QA_GITALY_NON_CLUSTER_STORAGE`: The name of a non gitaly cluster repository storage.
|
1029
1031
|
|
1030
1032
|
Example:
|
1031
1033
|
|
1032
1034
|
```shell
|
1033
|
-
$ export QA_ADDITIONAL_REPOSITORY_STORAGE=secondary
|
1035
|
+
$ export QA_ADDITIONAL_REPOSITORY_STORAGE=secondary
|
1036
|
+
$ export QA_GITALY_NON_CLUSTER_STORAGE=gitaly
|
1037
|
+
$ export QA_PRAEFECT_REPOSITORY_STORAGE=praefect
|
1034
1038
|
|
1035
1039
|
$ gitlab-qa Test::Instance::RepositoryStorage
|
1036
1040
|
```
|
@@ -1174,13 +1178,15 @@ need to be updated, it can be useful to proxy all requests to real `GitHub` inst
|
|
1174
1178
|
|
1175
1179
|
Testing import [by direct transfer](https://docs.gitlab.com/ee/user/group/import/#migrate-groups-by-direct-transfer-recommended) is done by spinning up 2 omnibus installations - `import-target` and `import-source`. In order for tests to work, application setting `allow_local_requests_from_web_hooks_and_services` must be enabled in target instance. This is automatically done by test process if environment variable `QA_ALLOW_LOCAL_REQUESTS` is set to `true`.
|
1176
1180
|
|
1177
|
-
### `
|
1181
|
+
### `AiGateway` Scenarios
|
1178
1182
|
|
1179
|
-
|
1183
|
+
The following `AiGateway` scenarios spin up a GitLab Omnibus instance integrated with a test AI Gateway using [fake models](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#faking-out-ai-models). These scenarios help to verify various configurations of cloud licensing and seat assignment work as expected when authenticating for AI features on self-managed instances.
|
1180
1184
|
|
1181
1185
|
**Required environment variables:**
|
1182
1186
|
|
1183
|
-
|
1187
|
+
All scenarios below require the following environment variables, **_unless otherwise noted:_**
|
1188
|
+
|
1189
|
+
- `QA_EE_ACTIVATION_CODE`: An activation code for a Staging-generated Premium or Ultimate cloud license with a purchased Duo Pro add-on. This can be found in the GitLab QA 1Password vault.
|
1184
1190
|
- `GITLAB_LICENSE_MODE`: Set to `test` in order to configure GitLab Omnibus with the correct license mode and `CUSTOMER_PORTAL_URL`.
|
1185
1191
|
|
1186
1192
|
Example:
|
@@ -1188,10 +1194,68 @@ Example:
|
|
1188
1194
|
```shell
|
1189
1195
|
$ export QA_EE_ACTIVATION_CODE="<value from 1Password>"
|
1190
1196
|
$ export GITLAB_LICENSE_MODE="test"
|
1197
|
+
```
|
1198
|
+
|
1199
|
+
----
|
1200
|
+
|
1201
|
+
#### `Test::Integration::AiGateway EE|<full image address>`
|
1191
1202
|
|
1203
|
+
- Runs tests tagged with `:ai_gateway`
|
1204
|
+
- GitLab instance has a cloud license + Duo Pro add-on, and a seat is assigned to the admin user
|
1205
|
+
|
1206
|
+
Example:
|
1207
|
+
|
1208
|
+
```shell
|
1192
1209
|
$ gitlab-qa Test::Integration::AiGateway EE
|
1193
1210
|
```
|
1194
1211
|
|
1195
1212
|
----
|
1196
1213
|
|
1214
|
+
#### `Test::Integration::AiGatewayNoSeatAssigned EE|<full image address>`
|
1215
|
+
|
1216
|
+
- Runs tests tagged with `:ai_gateway_no_seat_assigned`
|
1217
|
+
- GitLab instance has a cloud license + Duo Pro add-on, but no seat is assigned to the admin user
|
1218
|
+
|
1219
|
+
Example:
|
1220
|
+
|
1221
|
+
```shell
|
1222
|
+
$ gitlab-qa Test::Integration::AiGatewayNoSeatAssigned EE
|
1223
|
+
```
|
1224
|
+
|
1225
|
+
----
|
1226
|
+
|
1227
|
+
#### `Test::Integration::AiGatewayNoAddOn EE|<full image address>`
|
1228
|
+
|
1229
|
+
- Runs tests tagged with `:ai_gateway_no_add_on`
|
1230
|
+
- GitLab instance has a cloud license without a Duo Pro add-on, and no seat is assigned to the admin user
|
1231
|
+
|
1232
|
+
**Regarding environment variables:**
|
1233
|
+
|
1234
|
+
- `QA_EE_ACTIVATION_CODE` should be set to a Staging-generated Premium or Ultimate cloud license _without_ a Duo Pro add-on.
|
1235
|
+
|
1236
|
+
Example:
|
1237
|
+
|
1238
|
+
```shell
|
1239
|
+
$ gitlab-qa Test::Integration::AiGatewayNoAddOn EE
|
1240
|
+
```
|
1241
|
+
|
1242
|
+
---
|
1243
|
+
|
1244
|
+
#### `Test::Integration::AiGatewayNoLicense EE|<full image address>`
|
1245
|
+
|
1246
|
+
- Runs tests tagged with `:ai_gateway_no_license`
|
1247
|
+
- GitLab instance has no cloud license and no seat is assigned to the admin user
|
1248
|
+
|
1249
|
+
**Regarding environment variables:**
|
1250
|
+
|
1251
|
+
- `QA_EE_ACTIVATION_CODE` and `GITLAB_LICENSE_MODE` can be omitted
|
1252
|
+
|
1253
|
+
Example:
|
1254
|
+
|
1255
|
+
```shell
|
1256
|
+
$ gitlab-qa Test::Integration::AiGatewayNoLicense EE
|
1257
|
+
```
|
1258
|
+
|
1259
|
+
----
|
1260
|
+
|
1197
1261
|
[Back to README.md](../README.md)
|
@@ -203,6 +203,10 @@ module Gitlab
|
|
203
203
|
Runtime::Logger.warn(
|
204
204
|
"Retry instance_no_teardown due to Support::ShellCommand::StatusError -- attempt #{retries}"
|
205
205
|
)
|
206
|
+
Runtime::Logger.info(
|
207
|
+
"Follow the document " \
|
208
|
+
"https://gitlab.com/gitlab-org/quality/runbooks/-/blob/main/debug_orchestrated_test_locally/running_update-major_and_update-minor_locally.md " \
|
209
|
+
"for debugging this issue locally.")
|
206
210
|
teardown!
|
207
211
|
retry
|
208
212
|
end
|
@@ -13,7 +13,9 @@ module Gitlab
|
|
13
13
|
|
14
14
|
# Variables that are used in tests and are passed through to the docker container that executes the tests.
|
15
15
|
# These variables should be listed in /docs/what_tests_can_be_run.md#supported-gitlab-environment-variables
|
16
|
-
# unless they're defined elsewhere (e.g.: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html)
|
16
|
+
# unless they're defined elsewhere (e.g.: https://docs.gitlab.com/ee/ci/variables/predefined_variables.html).
|
17
|
+
# Any new key-value pairs should also be added to the hash at /rubocop/cop/gitlab/dangerous_interpolation.rb
|
18
|
+
# to prevent Rubocop errors.
|
17
19
|
ENV_VARIABLES = {
|
18
20
|
'QA_IMAGE' => :qa_image,
|
19
21
|
'QA_REMOTE_GRID' => :remote_grid,
|
@@ -11,31 +11,77 @@ module Gitlab
|
|
11
11
|
gitlab.release = QA::Release.new(release)
|
12
12
|
gitlab.name = 'gitlab'
|
13
13
|
gitlab.network = 'test'
|
14
|
-
gitlab.omnibus_configuration <<
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
'path' => '/var/opt/gitlab/git-data/repositories/secondary'
|
21
|
-
}
|
22
|
-
});
|
23
|
-
OMNIBUS
|
24
|
-
|
25
|
-
rspec_args << "--" unless rspec_args.include?('--')
|
26
|
-
rspec_args << %w[--tag repository_storage]
|
14
|
+
gitlab.omnibus_configuration << gitlab_omnibus_configuration
|
15
|
+
cluster = Component::GitalyCluster.perform do |c|
|
16
|
+
c.config = Component::GitalyCluster::GitalyClusterConfig.new(gitlab_name: 'gitlab')
|
17
|
+
c.release = release
|
18
|
+
c.instance
|
19
|
+
end
|
27
20
|
|
28
21
|
gitlab.instance do
|
22
|
+
cluster.join
|
23
|
+
|
24
|
+
rspec_args << "--" unless rspec_args.include?('--')
|
25
|
+
rspec_args << %w[--tag repository_storage]
|
26
|
+
|
29
27
|
Component::Specs.perform do |specs|
|
30
28
|
specs.suite = 'Test::Instance::All'
|
31
29
|
specs.release = gitlab.release
|
32
30
|
specs.network = gitlab.network
|
33
31
|
specs.args = [gitlab.address, *rspec_args]
|
34
|
-
specs.env = {
|
32
|
+
specs.env = {
|
33
|
+
'QA_PRAEFECT_REPOSITORY_STORAGE' => 'default',
|
34
|
+
'QA_GITALY_NON_CLUSTER_STORAGE' => 'gitaly',
|
35
|
+
'QA_ADDITIONAL_REPOSITORY_STORAGE' => 'secondary'
|
36
|
+
}
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def gitlab_omnibus_configuration
|
45
|
+
# refer to Gitlab::QA::Component::Praefect and Gitlab::QA::Component::Gitaly
|
46
|
+
# for details relating to the default values for tokens/secrets
|
47
|
+
<<~OMNIBUS
|
48
|
+
external_url 'http://gitlab.test';
|
49
|
+
|
50
|
+
git_data_dirs({
|
51
|
+
'default' => {
|
52
|
+
'gitaly_address' => 'tcp://praefect.test:2305',
|
53
|
+
'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
|
54
|
+
},
|
55
|
+
'gitaly' => {
|
56
|
+
'gitaly_address' => 'tcp://gitlab.test:8075',
|
57
|
+
'path' => '/var/opt/gitlab/git-data/gitaly'
|
58
|
+
},
|
59
|
+
'secondary' => {
|
60
|
+
'gitaly_address' => 'tcp://gitlab.test:8075',
|
61
|
+
'path' => '/var/opt/gitlab/git-data/secondary'
|
62
|
+
}
|
63
|
+
});
|
64
|
+
gitaly['enable'] = true;
|
65
|
+
gitaly['configuration'] = {
|
66
|
+
auth: {
|
67
|
+
token: 'secret-token',
|
68
|
+
},
|
69
|
+
listen_addr: '0.0.0.0:8075',
|
70
|
+
storage: [
|
71
|
+
{
|
72
|
+
name: 'gitaly',
|
73
|
+
path: '/var/opt/gitlab/git-data/gitaly',
|
74
|
+
},
|
75
|
+
{
|
76
|
+
name: 'secondary',
|
77
|
+
path: '/var/opt/gitlab/git-data/secondary',
|
78
|
+
},
|
79
|
+
],
|
80
|
+
};
|
81
|
+
gitlab_rails['gitaly_token'] = 'secret-token';
|
82
|
+
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
|
83
|
+
OMNIBUS
|
84
|
+
end
|
39
85
|
end
|
40
86
|
end
|
41
87
|
end
|
@@ -5,78 +5,10 @@ module Gitlab
|
|
5
5
|
module Scenario
|
6
6
|
module Test
|
7
7
|
module Integration
|
8
|
-
class AiGateway <
|
9
|
-
SETUP_SRC_PATH = File.expand_path('../../../../../../support/setup', __dir__)
|
10
|
-
SETUP_DEST_PATH = '/tmp/setup-scripts'
|
11
|
-
|
8
|
+
class AiGateway < AiGatewayBase
|
12
9
|
def initialize
|
13
|
-
|
14
|
-
@
|
15
|
-
@ai_gateway_hostname = "#{@ai_gateway_name}.#{@network}"
|
16
|
-
@ai_gateway_port = 5000
|
17
|
-
end
|
18
|
-
|
19
|
-
def perform(release, *rspec_args)
|
20
|
-
Component::Gitlab.perform do |gitlab|
|
21
|
-
setup_gitlab(gitlab, release)
|
22
|
-
|
23
|
-
Component::AiGateway.perform do |ai_gateway|
|
24
|
-
setup_ai_gateway(ai_gateway, gitlab_hostname: gitlab.hostname)
|
25
|
-
|
26
|
-
ai_gateway.instance do
|
27
|
-
gitlab.instance do
|
28
|
-
setup_code_suggestions(gitlab)
|
29
|
-
run_specs(gitlab, *rspec_args)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def setup_gitlab(gitlab, release)
|
39
|
-
gitlab.release = QA::Release.new(release)
|
40
|
-
gitlab.name = 'gitlab'
|
41
|
-
gitlab.network = @network
|
42
|
-
|
43
|
-
gitlab.omnibus_gitlab_rails_env['AI_GATEWAY_URL'] = "http://#{@ai_gateway_hostname}:#{@ai_gateway_port}"
|
44
|
-
|
45
|
-
gitlab.set_ee_activation_code
|
46
|
-
end
|
47
|
-
|
48
|
-
def setup_ai_gateway(ai_gateway, gitlab_hostname:)
|
49
|
-
ai_gateway.name = @ai_gateway_name
|
50
|
-
ai_gateway.network = @network
|
51
|
-
ai_gateway.ports = [@ai_gateway_port]
|
52
|
-
|
53
|
-
ai_gateway.configure_environment(gitlab_hostname: gitlab_hostname)
|
54
|
-
end
|
55
|
-
|
56
|
-
def setup_code_suggestions(gitlab)
|
57
|
-
Runtime::Logger.info('Setting up Code Suggestions on GitLab instance')
|
58
|
-
|
59
|
-
gitlab.docker.copy(gitlab.name, SETUP_SRC_PATH, SETUP_DEST_PATH)
|
60
|
-
|
61
|
-
gitlab.docker.exec(
|
62
|
-
gitlab.name,
|
63
|
-
"gitlab-rails runner #{SETUP_DEST_PATH}/code_suggestions_setup.rb",
|
64
|
-
mask_secrets: gitlab.secrets
|
65
|
-
)
|
66
|
-
end
|
67
|
-
|
68
|
-
def run_specs(gitlab, *rspec_args)
|
69
|
-
Runtime::Logger.info('Running AI Gateway specs!')
|
70
|
-
|
71
|
-
rspec_args << "--" unless rspec_args.include?('--')
|
72
|
-
rspec_args << %w[--tag ai_gateway]
|
73
|
-
|
74
|
-
Component::Specs.perform do |specs|
|
75
|
-
specs.suite = 'Test::Instance::All'
|
76
|
-
specs.release = gitlab.release
|
77
|
-
specs.network = gitlab.network
|
78
|
-
specs.args = [gitlab.address, *rspec_args]
|
79
|
-
end
|
10
|
+
super
|
11
|
+
@tag = 'ai_gateway'
|
80
12
|
end
|
81
13
|
end
|
82
14
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Integration
|
8
|
+
class AiGatewayBase < Scenario::Template
|
9
|
+
SETUP_SRC_PATH = File.expand_path('../../../../../../support/setup', __dir__)
|
10
|
+
SETUP_DEST_PATH = '/tmp/setup-scripts'
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@network = 'test'
|
14
|
+
@ai_gateway_name = 'ai-gateway'
|
15
|
+
@ai_gateway_hostname = "#{@ai_gateway_name}.#{@network}"
|
16
|
+
@ai_gateway_port = 5000
|
17
|
+
@use_cloud_license = true
|
18
|
+
@has_add_on = true
|
19
|
+
@assign_seats = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def perform(release, *rspec_args)
|
23
|
+
Component::Gitlab.perform do |gitlab|
|
24
|
+
set_up_gitlab(gitlab, release)
|
25
|
+
|
26
|
+
Component::AiGateway.perform do |ai_gateway|
|
27
|
+
set_up_ai_gateway(ai_gateway, gitlab_hostname: gitlab.hostname)
|
28
|
+
|
29
|
+
ai_gateway.instance do
|
30
|
+
gitlab.instance do
|
31
|
+
set_up_duo_pro(gitlab) if @use_cloud_license
|
32
|
+
run_specs(gitlab, *rspec_args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_up_gitlab(gitlab, release)
|
40
|
+
gitlab.release = QA::Release.new(release)
|
41
|
+
gitlab.name = 'gitlab'
|
42
|
+
gitlab.network = @network
|
43
|
+
|
44
|
+
gitlab.omnibus_gitlab_rails_env['AI_GATEWAY_URL'] = "http://#{@ai_gateway_hostname}:#{@ai_gateway_port}"
|
45
|
+
|
46
|
+
gitlab.set_ee_activation_code if @use_cloud_license
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_up_ai_gateway(ai_gateway, gitlab_hostname:)
|
50
|
+
ai_gateway.name = @ai_gateway_name
|
51
|
+
ai_gateway.network = @network
|
52
|
+
ai_gateway.ports = [@ai_gateway_port]
|
53
|
+
|
54
|
+
ai_gateway.configure_environment(gitlab_hostname: gitlab_hostname)
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_up_duo_pro(gitlab)
|
58
|
+
Runtime::Logger.info('Setting up Duo Pro on GitLab instance')
|
59
|
+
|
60
|
+
gitlab.docker.copy(gitlab.name, SETUP_SRC_PATH, SETUP_DEST_PATH)
|
61
|
+
|
62
|
+
gitlab.docker.exec(
|
63
|
+
gitlab.name,
|
64
|
+
"ASSIGN_SEATS=#{@assign_seats} HAS_ADD_ON=#{@has_add_on} gitlab-rails runner #{SETUP_DEST_PATH}/duo_pro_setup.rb",
|
65
|
+
mask_secrets: gitlab.secrets
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def run_specs(gitlab, *rspec_args)
|
70
|
+
Runtime::Logger.info('Running AI Gateway specs!')
|
71
|
+
|
72
|
+
rspec_args << "--" unless rspec_args.include?('--')
|
73
|
+
rspec_args << "--tag" << @tag
|
74
|
+
|
75
|
+
Component::Specs.perform do |specs|
|
76
|
+
specs.suite = 'Test::Instance::All'
|
77
|
+
specs.release = gitlab.release
|
78
|
+
specs.network = gitlab.network
|
79
|
+
specs.args = [gitlab.address, *rspec_args]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Integration
|
8
|
+
class AiGatewayNoAddOn < AiGatewayBase
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@tag = 'ai_gateway_no_add_on'
|
12
|
+
@has_add_on = false
|
13
|
+
@assign_seats = false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Integration
|
8
|
+
class AiGatewayNoLicense < AiGatewayBase
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@tag = 'ai_gateway_no_license'
|
12
|
+
@use_cloud_license = false
|
13
|
+
@assign_seats = false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Scenario
|
6
|
+
module Test
|
7
|
+
module Integration
|
8
|
+
class AiGatewayNoSeatAssigned < AiGatewayBase
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
@tag = 'ai_gateway_no_seat_assigned'
|
12
|
+
@assign_seats = false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/gitlab/qa/version.rb
CHANGED
@@ -0,0 +1,157 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Gitlab
|
6
|
+
# Checks for string interpolation of sensitive variables
|
7
|
+
# in information that's *probably* logged.
|
8
|
+
|
9
|
+
# @example
|
10
|
+
# # bad
|
11
|
+
# <<~OMNIBUS
|
12
|
+
# gitlab_rails['object_store']['objects']['lfs']['bucket'] = '#{Runtime::Env.aws_s3_secret_key}'
|
13
|
+
# OMNIBUS
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# gitlab_rails['object_store']['objects']['lfs']['bucket'] = '#{Runtime::Env.aws_s3_bucket_name}'
|
17
|
+
|
18
|
+
class DangerousInterpolation < Base
|
19
|
+
MSG = 'Sensitive variables should not be logged. ' \
|
20
|
+
'Please ensure that the interpolated variable is not sensitive. If not, add it to `ENV_VARIABLES` in the cop class.'
|
21
|
+
|
22
|
+
# These values are taken from /lib/gitlab/qa/runtime/env.rb. Sensitive variables have been removed.
|
23
|
+
ENV_VARIABLES = {
|
24
|
+
'HOST_ARTIFACT_DIR' => :host_artifacts_dir,
|
25
|
+
'QA_IMAGE' => :qa_image,
|
26
|
+
'QA_REMOTE_GRID' => :remote_grid,
|
27
|
+
'QA_REMOTE_GRID_USERNAME' => :remote_grid_username,
|
28
|
+
'QA_REMOTE_GRID_PROTOCOL' => :remote_grid_protocol,
|
29
|
+
'QA_REMOTE_MOBILE_DEVICE_NAME' => :remote_mobile_device_name,
|
30
|
+
'QA_REMOTE_TUNNEL_ID' => :remote_tunnel_id,
|
31
|
+
'QA_BROWSER' => :browser,
|
32
|
+
'QA_SELENOID_BROWSER_VERSION' => :selenoid_browser_version,
|
33
|
+
'QA_RECORD_VIDEO' => :record_video,
|
34
|
+
'QA_LAYOUT' => :layout,
|
35
|
+
'QA_VIDEO_RECORDER_IMAGE' => :video_recorder_image,
|
36
|
+
'QA_VIDEO_RECORDER_VERSION' => :video_recorder_version,
|
37
|
+
'QA_SELENOID_BROWSER_IMAGE' => :selenoid_browser_image,
|
38
|
+
'QA_ADDITIONAL_REPOSITORY_STORAGE' => :qa_additional_repository_storage,
|
39
|
+
'QA_PRAEFECT_REPOSITORY_STORAGE' => :qa_praefect_repository_storage,
|
40
|
+
'QA_GITALY_NON_CLUSTER_STORAGE' => :qa_gitaly_non_cluster_storage,
|
41
|
+
'QA_DEBUG' => :qa_debug,
|
42
|
+
'QA_CAN_TEST_ADMIN_FEATURES' => :qa_can_test_admin_features,
|
43
|
+
'QA_CAN_TEST_GIT_PROTOCOL_V2' => :qa_can_test_git_protocol_v2,
|
44
|
+
'QA_CAN_TEST_PRAEFECT' => :qa_can_test_praefect,
|
45
|
+
'QA_DISABLE_RSPEC_RETRY' => :qa_disable_rspec_retry,
|
46
|
+
'QA_SIMULATE_SLOW_CONNECTION' => :qa_simulate_slow_connection,
|
47
|
+
'QA_SLOW_CONNECTION_LATENCY_MS' => :qa_slow_connection_latency_ms,
|
48
|
+
'QA_SLOW_CONNECTION_THROUGHPUT_KBPS' => :qa_slow_connection_throughput_kbps,
|
49
|
+
'QA_GENERATE_ALLURE_REPORT' => :generate_allure_report,
|
50
|
+
'QA_EXPORT_TEST_METRICS' => :qa_export_test_metrics,
|
51
|
+
'QA_INFLUXDB_URL' => :qa_influxdb_url,
|
52
|
+
'QA_SKIP_PULL' => :qa_skip_pull,
|
53
|
+
'QA_VALIDATE_RESOURCE_REUSE' => :qa_validate_resource_reuse,
|
54
|
+
'WEBDRIVER_HEADLESS' => :webdriver_headless,
|
55
|
+
'GITLAB_ADMIN_USERNAME' => :admin_username,
|
56
|
+
'GITLAB_USERNAME' => :user_username,
|
57
|
+
'GITLAB_LDAP_USERNAME' => :ldap_username,
|
58
|
+
'GITLAB_FORKER_USERNAME' => :forker_username,
|
59
|
+
'GITLAB_USER_TYPE' => :user_type,
|
60
|
+
'GITLAB_SANDBOX_NAME' => :gitlab_sandbox_name,
|
61
|
+
'GITLAB_URL' => :gitlab_url,
|
62
|
+
'SIMPLE_SAML_HOSTNAME' => :simple_saml_hostname,
|
63
|
+
'SIMPLE_SAML_FINGERPRINT' => :simple_saml_fingerprint,
|
64
|
+
'ACCEPT_INSECURE_CERTS' => :accept_insecure_certs,
|
65
|
+
'EE_LICENSE' => :ee_license,
|
66
|
+
'GCLOUD_ACCOUNT_EMAIL' => :gcloud_account_email,
|
67
|
+
'CLOUDSDK_CORE_PROJECT' => :cloudsdk_core_project,
|
68
|
+
'GCLOUD_REGION' => :gcloud_region,
|
69
|
+
'SIGNUP_DISABLED' => :signup_disabled,
|
70
|
+
'GITLAB_QA_USERNAME_1' => :gitlab_qa_username_1,
|
71
|
+
'GITLAB_QA_USERNAME_2' => :gitlab_qa_username_2,
|
72
|
+
'QA_GITHUB_USERNAME' => :qa_github_username,
|
73
|
+
'QA_GITLAB_HOSTNAME' => :qa_gitlab_hostname,
|
74
|
+
'QA_GITLAB_USE_TLS' => :qa_gitlab_use_tls,
|
75
|
+
'KNAPSACK_GENERATE_REPORT' => :knapsack_generate_report,
|
76
|
+
'KNAPSACK_REPORT_PATH' => :knapsack_report_path,
|
77
|
+
'KNAPSACK_TEST_FILE_PATTERN' => :knapsack_test_file_pattern,
|
78
|
+
'KNAPSACK_TEST_DIR' => :knapsack_test_dir,
|
79
|
+
'NO_KNAPSACK' => :no_knapsack,
|
80
|
+
'QA_KNAPSACK_REPORT_GCS_CREDENTIALS' => :qa_knapsack_report_gcs_credentials,
|
81
|
+
'QA_KNAPSACK_REPORT_PATH' => :qa_knapsack_report_path,
|
82
|
+
'QA_RSPEC_REPORT_PATH' => :qa_rspec_report_path,
|
83
|
+
'RSPEC_FAST_QUARANTINE_PATH' => :rspec_fast_quarantine_path,
|
84
|
+
'RSPEC_SKIPPED_TESTS_REPORT_PATH' => :skipped_tests_report_path,
|
85
|
+
'CI' => :ci,
|
86
|
+
'CI_JOB_NAME' => :ci_job_name,
|
87
|
+
'CI_JOB_NAME_SLUG' => :ci_job_name_slug,
|
88
|
+
'CI_JOB_URL' => :ci_job_url,
|
89
|
+
'CI_RUNNER_ID' => :ci_runner_id,
|
90
|
+
'CI_SERVER_HOST' => :ci_server_host,
|
91
|
+
'CI_NODE_INDEX' => :ci_node_index,
|
92
|
+
'CI_NODE_TOTAL' => :ci_node_total,
|
93
|
+
'CI_PROJECT_NAME' => :ci_project_name,
|
94
|
+
'CI_PROJECT_PATH' => :ci_project_path,
|
95
|
+
'CI_PIPELINE_SOURCE' => :ci_pipeline_source,
|
96
|
+
'CI_PIPELINE_URL' => :ci_pipeline_url,
|
97
|
+
'CI_PIPELINE_CREATED_AT' => :ci_pipeline_created_at,
|
98
|
+
'CI_MERGE_REQUEST_IID' => :ci_merge_request_iid,
|
99
|
+
'GITLAB_CI' => :gitlab_ci,
|
100
|
+
'ELASTIC_URL' => :elastic_url,
|
101
|
+
'GITLAB_QA_LOOP_RUNNER_MINUTES' => :gitlab_qa_loop_runner_minutes,
|
102
|
+
'MAILHOG_HOSTNAME' => :mailhog_hostname,
|
103
|
+
'GEO_MAX_FILE_REPLICATION_TIME' => :geo_max_file_replication_time,
|
104
|
+
'GEO_MAX_DB_REPLICATION_TIME' => :geo_max_db_replication_time,
|
105
|
+
'JIRA_HOSTNAME' => :jira_hostname,
|
106
|
+
'JIRA_ADMIN_USERNAME' => :jira_admin_username,
|
107
|
+
'CACHE_NAMESPACE_NAME' => :cache_namespace_name,
|
108
|
+
'GITLAB_QA_USER_AGENT' => :gitlab_qa_user_agent,
|
109
|
+
'GEO_FAILOVER' => :geo_failover,
|
110
|
+
'GITLAB_INITIAL_ROOT_PASSWORD' => :initial_root_password,
|
111
|
+
'GITLAB_TLS_CERTIFICATE' => :gitlab_tls_certificate,
|
112
|
+
'AWS_S3_REGION' => :aws_s3_region,
|
113
|
+
'AWS_S3_KEY_ID' => :aws_s3_key_id,
|
114
|
+
'AWS_S3_BUCKET_NAME' => :aws_s3_bucket_name,
|
115
|
+
'TOP_UPSTREAM_MERGE_REQUEST_IID' => :top_upstream_merge_request_iid,
|
116
|
+
'GOOGLE_PROJECT' => :google_project,
|
117
|
+
'GOOGLE_CLIENT_EMAIL' => :google_client_email,
|
118
|
+
'GOOGLE_CDN_LB' => :google_cdn_load_balancer,
|
119
|
+
'GOOGLE_CDN_SIGNURL_KEY_NAME' => :google_cdn_signurl_key_name,
|
120
|
+
'GCS_CDN_BUCKET_NAME' => :gcs_cdn_bucket_name,
|
121
|
+
'GCS_BUCKET_NAME' => :gcs_bucket_name,
|
122
|
+
'SMOKE_ONLY' => :smoke_only,
|
123
|
+
'NO_ADMIN' => :no_admin,
|
124
|
+
'CHROME_DISABLE_DEV_SHM' => :chrome_disable_dev_shm,
|
125
|
+
'COLORIZED_LOGS' => :colorized_logs,
|
126
|
+
'FIPS' => :fips,
|
127
|
+
'JH_ENV' => :jh_env,
|
128
|
+
'QA_GITHUB_OAUTH_APP_ID' => :github_oauth_app_id,
|
129
|
+
'QA_1P_EMAIL' => :qa_1p_email,
|
130
|
+
'QA_1P_GITHUB_UUID' => :qa_1p_github_uuid,
|
131
|
+
'RELEASE' => :release,
|
132
|
+
'RELEASE_REGISTRY_URL' => :release_registry_url,
|
133
|
+
'RELEASE_REGISTRY_USERNAME' => :release_registry_username,
|
134
|
+
'SELENOID_DIRECTORY' => :selenoid_directory,
|
135
|
+
'USE_SELENOID' => :use_selenoid,
|
136
|
+
'SCHEDULE_TYPE' => :schedule_type,
|
137
|
+
'WORKSPACES_OAUTH_APP_ID' => :workspaces_oauth_app_id,
|
138
|
+
'WORKSPACES_PROXY_DOMAIN' => :workspaces_proxy_domain,
|
139
|
+
'WORKSPACES_DOMAIN_CERT' => { name: :workspaces_domain_cert, type: :file },
|
140
|
+
'WORKSPACES_DOMAIN_KEY' => { name: :workspaces_domain_key, type: :file },
|
141
|
+
'WORKSPACES_WILDCARD_CERT' => { name: :workspaces_wildcard_cert, type: :file },
|
142
|
+
'WORKSPACES_WILDCARD_KEY' => { name: :workspaces_wildcard_key, type: :file }
|
143
|
+
}.freeze
|
144
|
+
|
145
|
+
def_node_matcher :heredoc_interpolation?, <<~PATTERN
|
146
|
+
(send (const (const nil? :Runtime) :Env) ...)
|
147
|
+
PATTERN
|
148
|
+
|
149
|
+
def on_send(node)
|
150
|
+
return unless heredoc_interpolation?(node) && node.parent.parent.dstr_type? && !ENV_VARIABLES.value?(node.source.split(".")[1].to_sym)
|
151
|
+
|
152
|
+
add_offense(node)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -1,28 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class
|
3
|
+
class DuoProSetup
|
4
4
|
class << self
|
5
5
|
def configure!
|
6
6
|
activate_cloud_license
|
7
7
|
|
8
|
-
|
9
|
-
# that the code suggestions access token has been generated before proceeding
|
10
|
-
verify_code_suggestions_access_token
|
8
|
+
return unless enabled?('HAS_ADD_ON')
|
11
9
|
|
12
|
-
#
|
13
|
-
#
|
14
|
-
|
15
|
-
puts 'Enabling application setting instance_level_code_suggestions_enabled...'
|
16
|
-
ApplicationSetting.last.update(instance_level_code_suggestions_enabled: true)
|
10
|
+
# Due to the various async Sidekiq processes involved, we wait to verify
|
11
|
+
# that the service access token has been generated before proceeding
|
12
|
+
verify_service_access_token
|
17
13
|
|
18
|
-
|
14
|
+
assign_duo_pro_seat_to_admin if enabled?('ASSIGN_SEATS')
|
19
15
|
end
|
20
16
|
|
21
17
|
private
|
22
18
|
|
23
19
|
def activate_cloud_license
|
24
20
|
puts 'Activating cloud license...'
|
25
|
-
result = ::GitlabSubscriptions::ActivateService.new.execute(ENV.fetch('QA_EE_ACTIVATION_CODE'
|
21
|
+
result = ::GitlabSubscriptions::ActivateService.new.execute(ENV.fetch('QA_EE_ACTIVATION_CODE'))
|
26
22
|
|
27
23
|
if result[:success]
|
28
24
|
puts 'Cloud license activation successful'
|
@@ -33,8 +29,8 @@ class CodeSuggestionsSetup
|
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
36
|
-
def
|
37
|
-
puts 'Waiting for
|
32
|
+
def verify_service_access_token
|
33
|
+
puts 'Waiting for service access token to be available...'
|
38
34
|
|
39
35
|
max_attempts = 3
|
40
36
|
attempts = 0
|
@@ -47,12 +43,12 @@ class CodeSuggestionsSetup
|
|
47
43
|
|
48
44
|
return if tokens&.positive?
|
49
45
|
|
50
|
-
puts "Failed to create
|
46
|
+
puts "Failed to create service access token after #{max_attempts} attempts"
|
51
47
|
exit 1
|
52
48
|
end
|
53
49
|
|
54
|
-
def
|
55
|
-
puts 'Assigning
|
50
|
+
def assign_duo_pro_seat_to_admin
|
51
|
+
puts 'Assigning Duo Pro seat to admin...'
|
56
52
|
|
57
53
|
admin = User.find_by(username: 'root')
|
58
54
|
add_on = GitlabSubscriptions::AddOnPurchase.find_by(add_on: GitlabSubscriptions::AddOn.code_suggestions.last)
|
@@ -70,7 +66,11 @@ class CodeSuggestionsSetup
|
|
70
66
|
puts error
|
71
67
|
end
|
72
68
|
end
|
69
|
+
|
70
|
+
def enabled?(key, default: nil)
|
71
|
+
ENV.fetch(key, default) == 'true'
|
72
|
+
end
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
DuoProSetup.configure!
|
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.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: 2024-
|
11
|
+
date: 2024-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -446,6 +446,10 @@ files:
|
|
446
446
|
- lib/gitlab/qa/scenario/test/instance/staging_ref.rb
|
447
447
|
- lib/gitlab/qa/scenario/test/instance/staging_ref_geo.rb
|
448
448
|
- lib/gitlab/qa/scenario/test/integration/ai_gateway.rb
|
449
|
+
- lib/gitlab/qa/scenario/test/integration/ai_gateway_base.rb
|
450
|
+
- lib/gitlab/qa/scenario/test/integration/ai_gateway_no_add_on.rb
|
451
|
+
- lib/gitlab/qa/scenario/test/integration/ai_gateway_no_license.rb
|
452
|
+
- lib/gitlab/qa/scenario/test/integration/ai_gateway_no_seat_assigned.rb
|
449
453
|
- lib/gitlab/qa/scenario/test/integration/chaos.rb
|
450
454
|
- lib/gitlab/qa/scenario/test/integration/client_ssl.rb
|
451
455
|
- lib/gitlab/qa/scenario/test/integration/elasticsearch.rb
|
@@ -490,6 +494,7 @@ files:
|
|
490
494
|
- lib/gitlab/qa/support/shellout.rb
|
491
495
|
- lib/gitlab/qa/test_logger.rb
|
492
496
|
- lib/gitlab/qa/version.rb
|
497
|
+
- rubocop/cop/gitlab/dangerous_interpolation.rb
|
493
498
|
- scripts/build-package-and-test-env
|
494
499
|
- support/data/admin_access_token_seed.rb
|
495
500
|
- support/data/license_usage_seed.rb
|
@@ -498,7 +503,7 @@ files:
|
|
498
503
|
- support/manifests/suggested_reviewer/pubsub.yaml
|
499
504
|
- support/manifests/suggested_reviewer/recommender-bot.yaml
|
500
505
|
- support/manifests/suggested_reviewer/recommender.yaml
|
501
|
-
- support/setup/
|
506
|
+
- support/setup/duo_pro_setup.rb
|
502
507
|
- tls_certificates/authority/ca.crt
|
503
508
|
- tls_certificates/authority/ca.key
|
504
509
|
- tls_certificates/authority/ca.pem
|