gitlab-qa 10.2.2 → 10.3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitlab-ci.yml +7 -1
- data/Gemfile.lock +1 -1
- data/docs/running_against_remote_grid.md +10 -5
- data/fixtures/selenoid/browsers.json +25 -0
- data/lib/gitlab/qa/component/selenoid.rb +88 -0
- data/lib/gitlab/qa/component/specs.rb +15 -0
- data/lib/gitlab/qa/runtime/env.rb +20 -1
- data/lib/gitlab/qa/support/gitlab_version_info.rb +28 -8
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfc87eff61f4ee1948666c002738047c9061df3f669c16b87a78887b68776f3c
|
4
|
+
data.tar.gz: 32514740f5d1cc8403d6b388c731048d85e5da441acaf687d7f8ddad72ad44a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29a26e723aac6ac6fad94630e0e5dfe1882aa7031474dcd20f781468105dfa77f6449430202f06875a400edbc71339c0eb4183303bd3cddd432105241ce1bafc
|
7
|
+
data.tar.gz: '08751aa4982005a4ac8b80998dd07ae31a4fb08c6a4539a20c09167ab382a7bed47a6c5b74478ed30bb6db05c91c2258e11d753774b4fe9d0d6b1c36ac592462'
|
data/.gitlab-ci.yml
CHANGED
@@ -34,7 +34,7 @@ workflow:
|
|
34
34
|
# For merge requests, create a pipeline.
|
35
35
|
- if: '$CI_MERGE_REQUEST_IID'
|
36
36
|
# For the default branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
|
37
|
-
- if: '$
|
37
|
+
- if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable$/'
|
38
38
|
# For tags, create a pipeline.
|
39
39
|
- if: '$CI_COMMIT_TAG'
|
40
40
|
# When using Run pipeline button in the GitLab UI, from the project’s CI/CD > Pipelines section, create a pipeline.
|
@@ -46,6 +46,12 @@ variables:
|
|
46
46
|
BUNDLE_SILENCE_ROOT_WARNING: "true"
|
47
47
|
BUNDLE_SUPPRESS_INSTALL_USING_MESSAGES: "true"
|
48
48
|
|
49
|
+
# Override rules to allow creating backport releases
|
50
|
+
.release-base:
|
51
|
+
rules:
|
52
|
+
- if: '$CI_PIPELINE_SOURCE == "push" && ($CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH || $CI_COMMIT_REF_NAME =~ /^[\d-]+-stable$/)'
|
53
|
+
changes: ["lib/**/version.rb"]
|
54
|
+
|
49
55
|
package-and-test-env:
|
50
56
|
image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/alpine:latest
|
51
57
|
stage: .pre
|
data/Gemfile.lock
CHANGED
@@ -9,12 +9,17 @@ I.e, if you have a Selenium server set up at http://localhost:4444 or if you hav
|
|
9
9
|
| Variable | Description | Default | Example(s) |
|
10
10
|
|---------------------------|----------------------------------------------------------------|----------|--------------------------------|
|
11
11
|
| QA_BROWSER | Browser to run against | "chrome" | "chrome" "firefox" "safari" |
|
12
|
+
| QA_BROWSER_VERSION | Version of browser to run against | "latest" | "latest" "111.0" "mobile-111.0"|
|
12
13
|
| QA_REMOTE_GRID_PROTOCOL | Protocol to use | "http" | "http" "https" |
|
13
|
-
| QA_REMOTE_GRID | Remote grid to run tests against | | "localhost:3000" "provider:80" |
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
| QA_REMOTE_GRID | Remote grid to run tests against | | "localhost:3000" "provider:80" "selenoid:4444" |
|
15
|
+
| QA_LAYOUT | Used with Selenoid. Tells test nav to expect collapsed menus. "phone" expects collapsed top and left nav bars, "tablet" expects collapsed left nav bar only. | | "phone", "tablet" |
|
16
|
+
| SELENOID_DIRECTORY | Used with Selenoid. Directory to save videos to | "<host_artifacts_dir>/selenoid" | |
|
17
|
+
| USE_SELENOID | Used with Selenoid. Sets up selenoid containers. | false | false, true |
|
18
|
+
| QA_RECORD_VIDEO | Used with Selenoid. Triggers video recording. | false | false, true |
|
19
|
+
| QA_REMOTE_GRID_USERNAME | Used with Sauce Labs. Username to specify in the remote grid. "USERNAME@provider:80" | | "gitlab-sl" |
|
20
|
+
| QA_REMOTE_GRID_ACCESS_KEY | Used with Sauce Labs. Key/Token paired with `QA_REMOTE_GRID_USERNAME` | | |
|
21
|
+
| QA_REMOTE_TUNNEL_ID | Used with Sauce Labs. Name of the remote tunnel to use | "gitlab-sl_tunnel_id" | |
|
22
|
+
| QA_REMOTE_MOBILE_DEVICE_NAME | Used with Sauce Labs. Name of mobile device to test against. `QA_BROWSER` must be set to `safari` for iOS devices and `chrome` for Android devices. | | "iPhone 12 Simulator" |
|
18
23
|
|
19
24
|
## Testing with Sauce Labs
|
20
25
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"chrome": {
|
3
|
+
"default": "111.0",
|
4
|
+
"versions": {
|
5
|
+
"111.0": {
|
6
|
+
"image": "selenoid/chrome:111.0",
|
7
|
+
"port": "4444"
|
8
|
+
},
|
9
|
+
"mobile-111.0": {
|
10
|
+
"image": "registry.gitlab.com/gitlab-org/gitlab-qa/selenoid-chrome-gitlab:mobile-111.0",
|
11
|
+
"path": "/wd/hub",
|
12
|
+
"port": "4444"
|
13
|
+
}
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"MicrosoftEdge": {
|
17
|
+
"default": "111.0",
|
18
|
+
"versions": {
|
19
|
+
"111.0": {
|
20
|
+
"image": "browsers/edge:111.0",
|
21
|
+
"port": "4444"
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'http'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
module QA
|
7
|
+
module Component
|
8
|
+
# Component for the Selenoid Grid
|
9
|
+
# https://aerokube.com/selenoid/latest/
|
10
|
+
class Selenoid < Base
|
11
|
+
DOCKER_IMAGE = 'aerokube/selenoid'
|
12
|
+
DOCKER_IMAGE_TAG = 'latest-release'
|
13
|
+
|
14
|
+
def name
|
15
|
+
@name ||= 'selenoid'
|
16
|
+
end
|
17
|
+
|
18
|
+
def instance
|
19
|
+
Runtime::Env.webdriver_headless = '0'
|
20
|
+
Runtime::Env.chrome_disable_dev_shm = 'true'
|
21
|
+
Runtime::Env.remote_grid = "#{hostname}:4444"
|
22
|
+
Runtime::Env.remote_grid_protocol = 'http'
|
23
|
+
raise 'Please provide a block!' unless block_given?
|
24
|
+
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
pull_images
|
30
|
+
docker.run(image: image, tag: tag, args: ['-container-network', network]) do |command|
|
31
|
+
set_command_args(command)
|
32
|
+
set_volumes(command)
|
33
|
+
end
|
34
|
+
|
35
|
+
wait_until_ready
|
36
|
+
end
|
37
|
+
|
38
|
+
def wait_until_ready(max_attempts: 20, wait: 2)
|
39
|
+
Runtime::Logger.info("Waiting for Selenoid ...")
|
40
|
+
|
41
|
+
max_attempts.times do
|
42
|
+
return Runtime::Logger.info("Selenoid ready!") if grid_healthy?
|
43
|
+
|
44
|
+
sleep wait
|
45
|
+
end
|
46
|
+
|
47
|
+
raise "Retried #{max_attempts} times. Selenoid is not responding. Aborting."
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def grid_healthy?
|
53
|
+
HTTP.get('http://localhost:4444/ping').status&.success?
|
54
|
+
rescue HTTP::ConnectionError => _e
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
def pull_images
|
59
|
+
docker.pull(image: "selenoid/chrome", tag: Runtime::Env.browser_version) if Runtime::Env.browser == :chrome && !Runtime::Env.mobile_layout?
|
60
|
+
docker.pull(image: "selenoid/video-recorder", tag: "latest-release")
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set custom run command arguments
|
64
|
+
#
|
65
|
+
# @param [Docker::Command] command
|
66
|
+
# @return [void]
|
67
|
+
def set_command_args(command)
|
68
|
+
command << '-d '
|
69
|
+
command << "--name #{name}"
|
70
|
+
command << "--net #{network}"
|
71
|
+
command << "--hostname #{hostname}"
|
72
|
+
command << "--publish 4444:4444"
|
73
|
+
command << "-e OVERRIDE_VIDEO_OUTPUT_DIR=#{Runtime::Env.selenoid_directory}/video"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set volumes
|
77
|
+
#
|
78
|
+
# @param [Docker::Command] command
|
79
|
+
# @return [void]
|
80
|
+
def set_volumes(command)
|
81
|
+
command.volume('/var/run/docker.sock', '/var/run/docker.sock')
|
82
|
+
command.volume("#{__dir__}/../../../../fixtures/selenoid", "/etc/selenoid")
|
83
|
+
command.volume("#{Runtime::Env.selenoid_directory}/video", '/opt/selenoid/video')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
# rubocop:disable Metrics/CyclomaticComplexity
|
3
|
+
# rubocop:disable Metrics/AbcSize
|
3
4
|
|
4
5
|
require 'securerandom'
|
5
6
|
|
@@ -27,6 +28,19 @@ module Gitlab
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def perform
|
31
|
+
if Runtime::Env.use_selenoid?
|
32
|
+
Component::Selenoid.perform do |selenoid|
|
33
|
+
selenoid.network = network
|
34
|
+
selenoid.instance do
|
35
|
+
internal_perform
|
36
|
+
end
|
37
|
+
end
|
38
|
+
else
|
39
|
+
internal_perform
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def internal_perform
|
30
44
|
return Runtime::Logger.info("Skipping tests.") if skip_tests?
|
31
45
|
|
32
46
|
raise ArgumentError unless [suite, release].all?
|
@@ -114,3 +128,4 @@ module Gitlab
|
|
114
128
|
end
|
115
129
|
end
|
116
130
|
# rubocop:enable Metrics/CyclomaticComplexity
|
131
|
+
# rubocop:enable Metrics/AbcSize
|
@@ -41,6 +41,7 @@ module Gitlab
|
|
41
41
|
'QA_INFLUXDB_TOKEN' => :qa_influxdb_token,
|
42
42
|
'QA_SKIP_PULL' => :qa_skip_pull,
|
43
43
|
'QA_VALIDATE_RESOURCE_REUSE' => :qa_validate_resource_reuse,
|
44
|
+
'WEBDRIVER_HEADLESS' => :webdriver_headless,
|
44
45
|
'GITLAB_API_BASE' => :api_base,
|
45
46
|
'GITLAB_ADMIN_USERNAME' => :admin_username,
|
46
47
|
'GITLAB_ADMIN_PASSWORD' => :admin_password,
|
@@ -148,7 +149,9 @@ module Gitlab
|
|
148
149
|
'RELEASE' => :release,
|
149
150
|
'RELEASE_REGISTRY_URL' => :release_registry_url,
|
150
151
|
'RELEASE_REGISTRY_USERNAME' => :release_registry_username,
|
151
|
-
'RELEASE_REGISTRY_PASSWORD' => :release_registry_password
|
152
|
+
'RELEASE_REGISTRY_PASSWORD' => :release_registry_password,
|
153
|
+
'SELENOID_DIRECTORY' => :selenoid_directory,
|
154
|
+
'USE_SELENOID' => :use_selenoid
|
152
155
|
}.freeze
|
153
156
|
|
154
157
|
ENV_VARIABLES.each do |env_name, method_name|
|
@@ -349,6 +352,22 @@ module Gitlab
|
|
349
352
|
enabled?(env_var_value_if_defined('QA_EXPORT_TEST_METRICS'), default: true)
|
350
353
|
end
|
351
354
|
|
355
|
+
def selenoid_directory
|
356
|
+
env_var_value_if_defined('SELENOID_DIRECTORY') || "#{host_artifacts_dir}/selenoid"
|
357
|
+
end
|
358
|
+
|
359
|
+
def use_selenoid?
|
360
|
+
enabled?(env_var_value_if_defined('USE_SELENOID'), default: false)
|
361
|
+
end
|
362
|
+
|
363
|
+
def mobile_layout?
|
364
|
+
env_var_value_if_defined('QA_LAYOUT')&.match?(/tablet|phone/i)
|
365
|
+
end
|
366
|
+
|
367
|
+
def browser_version
|
368
|
+
env_var_value_if_defined('QA_BROWSER_VERSION')
|
369
|
+
end
|
370
|
+
|
352
371
|
def qa_run_type
|
353
372
|
return env_var_value_if_defined('QA_RUN_TYPE') if env_var_value_valid?('QA_RUN_TYPE')
|
354
373
|
|
@@ -47,6 +47,10 @@ module Gitlab
|
|
47
47
|
|
48
48
|
private
|
49
49
|
|
50
|
+
MAX_TAGS_HTTP_REQUESTS = 50
|
51
|
+
# https://docs.docker.com/docker-hub/api/latest/#tag/images/operation/GetNamespacesRepositoriesImages
|
52
|
+
TAGS_PER_PAGE = 100
|
53
|
+
|
50
54
|
attr_reader :current_version, :edition, :logger
|
51
55
|
|
52
56
|
# Current versions major version
|
@@ -155,28 +159,44 @@ module Gitlab
|
|
155
159
|
# All available docker tags
|
156
160
|
#
|
157
161
|
# @return [Array<String>]
|
158
|
-
# rubocop:disable Metrics/AbcSize
|
159
162
|
def tags
|
160
163
|
return @tags if defined?(@tags)
|
161
164
|
|
162
|
-
|
165
|
+
MAX_TAGS_HTTP_REQUESTS.times do |index|
|
166
|
+
tag_list, more_data = fetch_tags(page: index + 1)
|
167
|
+
|
168
|
+
if tag_list
|
169
|
+
@tags = Array(@tags)
|
170
|
+
@tags += tag_list
|
171
|
+
end
|
172
|
+
|
173
|
+
break if tag_list.nil? || more_data.nil?
|
174
|
+
end
|
175
|
+
|
176
|
+
@tags
|
177
|
+
end
|
178
|
+
|
179
|
+
def fetch_tags(page:, per_page: TAGS_PER_PAGE)
|
180
|
+
logger.info("Fetching Docker tags page #{page} from 'gitlab/gitlab-#{edition}' registry")
|
163
181
|
response = HttpRequest.make_http_request(
|
164
|
-
url: "https://registry.hub.docker.com/v2/namespaces/gitlab/repositories/gitlab-#{edition}/tags?page_size
|
182
|
+
url: "https://registry.hub.docker.com/v2/namespaces/gitlab/repositories/gitlab-#{edition}/tags?page=#{page}&page_size=#{per_page}",
|
165
183
|
fail_on_error: false
|
166
184
|
)
|
167
185
|
|
168
186
|
unless response.code == 200
|
169
187
|
logger.error(" failed to fetch docker tags - code: #{response.code}, response: '#{response.body}'")
|
170
|
-
return
|
188
|
+
return nil
|
171
189
|
end
|
172
190
|
|
173
|
-
|
174
|
-
|
191
|
+
response = JSON.parse(response.body, symbolize_names: true)
|
192
|
+
matching_tags = response
|
175
193
|
.fetch(:results)
|
176
194
|
.map { |tag| tag[:name] }
|
177
|
-
.
|
195
|
+
.grep(VERSION_PATTERN)
|
196
|
+
more_data = response.fetch(:next)
|
197
|
+
|
198
|
+
[matching_tags, more_data]
|
178
199
|
end
|
179
|
-
# rubocop:enable Metrics/AbcSize
|
180
200
|
end
|
181
201
|
end
|
182
202
|
end
|
data/lib/gitlab/qa/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab-qa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.
|
4
|
+
version: 10.3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitLab Quality
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -360,6 +360,7 @@ files:
|
|
360
360
|
- fixtures/ldap/2_add_users.ldif
|
361
361
|
- fixtures/ldap/3_add_groups.ldif
|
362
362
|
- fixtures/ldap/tanuki.ldif
|
363
|
+
- fixtures/selenoid/browsers.json
|
363
364
|
- gitlab-qa.gemspec
|
364
365
|
- lefthook.yml
|
365
366
|
- lib/gitlab/qa.rb
|
@@ -382,6 +383,7 @@ files:
|
|
382
383
|
- lib/gitlab/qa/component/production.rb
|
383
384
|
- lib/gitlab/qa/component/release.rb
|
384
385
|
- lib/gitlab/qa/component/saml.rb
|
386
|
+
- lib/gitlab/qa/component/selenoid.rb
|
385
387
|
- lib/gitlab/qa/component/specs.rb
|
386
388
|
- lib/gitlab/qa/component/staging.rb
|
387
389
|
- lib/gitlab/qa/component/staging_ref.rb
|