gitlab-qa 14.2.1 → 14.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/.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
|