gitlab-qa 10.2.2 → 10.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d4d6777aac07a8fbb1da706af278b89fa4abc6684b37a828ec8f3b8f0cd6c49
4
- data.tar.gz: 2852a0396eb280993b58fcfe91f29b89565ba28c27615d12d9c04883aa2cfdac
3
+ metadata.gz: fe25be14520a4bf78ee88e0d5bd7e36534d79b32c5734b92b8337736c659b6b2
4
+ data.tar.gz: c0064bfce6ed145f0e7464ac72f8ca8ddc2c2ae467a956f361645e8443f7546a
5
5
  SHA512:
6
- metadata.gz: 8592539a7d61dbfd902853a53ad48310fdf216fb455be221d3d55fc27f1327919550844dade5496d003c83b54d9dfec9c4eafc7e78451b84e3d5b700c188f30c
7
- data.tar.gz: cd50e445144fb5d2f70f91eb2ef3b0355f2b78c3712722746571703d7d1bcfa34f41e5462e5ddfa92bb13ae9b206662399dad78f3be8cfa7efc9cb7d42a44545
6
+ metadata.gz: f3df8e960239e908aa0f86b7f6dcac023ce6996aadd3a4e49108cbf6f58876de94946f3d475b0828578ccb04309ca241ea8f8eeb3fa44b760624f4cb33c29b2f
7
+ data.tar.gz: 0af92a24612916090ae9a71aebef586b3261a6f99c5cd93f287199881f1f959e897bc68811f8fdb86fc607539bb4998839b6420233d300b1ceca6a3005fa7573
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-qa (10.2.2)
4
+ gitlab-qa (10.4.0)
5
5
  activesupport (~> 6.1)
6
6
  gitlab (~> 4.18.0)
7
7
  http (~> 5.0)
@@ -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
- | QA_REMOTE_GRID_USERNAME | Username to specify in the remote grid. "USERNAME@provider:80" | | "gitlab-sl" |
15
- | QA_REMOTE_GRID_ACCESS_KEY | Key/Token paired with `QA_REMOTE_GRID_USERNAME` | | |
16
- | QA_REMOTE_TUNNEL_ID | Name of the remote tunnel to use | "gitlab-sl_tunnel_id" | |
17
- | QA_REMOTE_MOBILE_DEVICE_NAME | 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" |
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
 
@@ -1072,7 +1072,10 @@ gitlab-qa Test::Integration::RegistryTLS EE --omnibus-config object_storage_aws
1072
1072
 
1073
1073
  ### `Test::Instance::Image EE --omnibus-config decomposition_single_db`
1074
1074
 
1075
- This scenario is to run tests against a GitLab instance with a [decomposed database](https://gitlab.com/groups/gitlab-org/-/epics/6160) using a single database:
1075
+ **Note: The default Omnibus config is using a single database
1076
+ with [two database connections](https://docs.gitlab.com/omnibus/settings/database.html#configuring-multiple-database-connections)**
1077
+
1078
+ This scenario is to run tests against a GitLab instance using a single database with only one `main` connection:
1076
1079
 
1077
1080
  ```ruby
1078
1081
  gitlab-qa Test::Instance::Image EE --omnibus-config decomposition_single_db
@@ -1080,7 +1083,7 @@ gitlab-qa Test::Instance::Image EE --omnibus-config decomposition_single_db
1080
1083
 
1081
1084
  ### `Test::Instance::Image EE --omnibus-config decomposition_multiple_db`
1082
1085
 
1083
- This scenario is to run tests against a GitLab instance with a [decomposed database](https://gitlab.com/groups/gitlab-org/-/epics/6160) using multiple databases:
1086
+ This scenario is to run tests against a GitLab instance using [multiple databases](https://docs.gitlab.com/ee/administration/postgresql/multiple_databases.html):
1084
1087
 
1085
1088
  ```ruby
1086
1089
  gitlab-qa Test::Instance::Image EE --omnibus-config decomposition_multiple_db
@@ -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
+ }
@@ -64,9 +64,11 @@ module Gitlab
64
64
  praefect['enable'] = false;
65
65
  prometheus['enable'] = true;
66
66
  gitaly['enable'] = true;
67
- gitaly['listen_addr'] = '0.0.0.0:#{gitaly_port}';
68
- gitaly['prometheus_listen_addr'] = '0.0.0.0:9236';
69
- gitaly['auth_token'] = 'PRAEFECT_INTERNAL_TOKEN';
67
+ gitaly['configuration'] = {
68
+ 'listen_addr': '0.0.0.0:#{gitaly_port}',
69
+ 'prometheus_listen_addr': '0.0.0.0:9236',
70
+ 'auth_token': 'PRAEFECT_INTERNAL_TOKEN'
71
+ }
70
72
  gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
71
73
  gitlab_rails['internal_api_url'] = 'http://#{cluster_config.gitlab_name}.#{cluster_config.network}';
72
74
  git_data_dirs({
@@ -60,36 +60,46 @@ module Gitlab
60
60
  gitaly['enable'] = false;
61
61
  prometheus['enable'] = true;
62
62
  praefect['enable'] = true;
63
- praefect['listen_addr'] = '0.0.0.0:#{cluster_config.praefect_port}';
64
- praefect['prometheus_listen_addr'] = '0.0.0.0:9652';
65
- praefect['auth_token'] = 'PRAEFECT_EXTERNAL_TOKEN';
66
- praefect['reconciliation_scheduling_interval'] = '10s';
67
- praefect['database_host'] = '#{cluster_config.database_node_addr}';
68
- praefect['database_user'] = 'postgres';
69
- praefect['database_port'] = #{cluster_config.database_port};
70
- praefect['database_password'] = 'SQL_PASSWORD';
71
- praefect['database_dbname'] = 'praefect_production';
72
- praefect['database_sslmode'] = 'disable';
73
- praefect['database_direct_host'] = '#{cluster_config.database_node_addr}';
74
- praefect['database_direct_port'] = #{cluster_config.database_port};
75
- praefect['virtual_storages'] = {
76
- 'default' => {
77
- 'nodes' => {
78
- '#{cluster_config.primary_node_name}' => {
79
- 'address' => 'tcp://#{cluster_config.primary_node_addr}:#{cluster_config.primary_node_port}',
80
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
81
- },
82
- '#{cluster_config.secondary_node_name}' => {
83
- 'address' => 'tcp://#{cluster_config.secondary_node_addr}:#{cluster_config.secondary_node_port}',
84
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
85
- },
86
- '#{cluster_config.tertiary_node_name}' => {
87
- 'address' => 'tcp://#{cluster_config.tertiary_node_addr}:#{cluster_config.tertiary_node_port}',
88
- 'token' => 'PRAEFECT_INTERNAL_TOKEN'
89
- }
63
+ praefect['configuration'] = {
64
+ listen_addr: '0.0.0.0:#{cluster_config.praefect_port}',
65
+ prometheus_listen_addr: '0.0.0.0:9652',
66
+ auth: {
67
+ token: 'PRAEFECT_EXTERNAL_TOKEN'
68
+ },
69
+ reconciliation: {
70
+ scheduling_interval: '10s'
71
+ },
72
+ database: {
73
+ host: '#{cluster_config.database_node_addr}',
74
+ port: #{cluster_config.database_port},
75
+ user: 'postgres',
76
+ password: 'SQL_PASSWORD',
77
+ dbname: 'praefect_production',
78
+ sslmode: 'disable'
79
+ },
80
+ virtual_storage: [
81
+ {
82
+ name: 'default',
83
+ node: [
84
+ {
85
+ 'storage': '#{cluster_config.primary_node_name}',
86
+ 'address': 'tcp://#{cluster_config.primary_node_addr}:#{cluster_config.primary_node_port}',
87
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
88
+ },
89
+ {
90
+ 'storage': '#{cluster_config.secondary_node_name}',
91
+ 'address': 'tcp://#{cluster_config.secondary_node_addr}:#{cluster_config.secondary_node_port}',
92
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
93
+ },
94
+ {
95
+ 'storage': '#{cluster_config.tertiary_node_name}',
96
+ 'address': 'tcp://#{cluster_config.tertiary_node_addr}:#{cluster_config.tertiary_node_port}',
97
+ 'token': 'PRAEFECT_INTERNAL_TOKEN'
98
+ }
99
+ ],
90
100
  }
91
- }
92
- };
101
+ ]
102
+ }
93
103
  OMNIBUS
94
104
  end
95
105
  end
@@ -0,0 +1,87 @@
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
+ end
35
+
36
+ def wait_until_ready(max_attempts: 20, wait: 2)
37
+ Runtime::Logger.info("Waiting for Selenoid ...")
38
+
39
+ max_attempts.times do
40
+ return Runtime::Logger.info("Selenoid ready!") if grid_healthy?
41
+
42
+ sleep wait
43
+ end
44
+
45
+ raise "Retried #{max_attempts} times. Selenoid is not responding. Aborting."
46
+ end
47
+
48
+ private
49
+
50
+ def grid_healthy?
51
+ HTTP.get('http://docker:4444/ping').status&.success?
52
+ rescue HTTP::ConnectionError => e
53
+ Runtime::Logger.debug(e)
54
+ false
55
+ end
56
+
57
+ def pull_images
58
+ docker.pull(image: "selenoid/chrome", tag: Runtime::Env.browser_version) if Runtime::Env.browser == 'chrome' && !Runtime::Env.mobile_layout?
59
+ docker.pull(image: "selenoid/video-recorder", tag: "latest-release") if Runtime::Env.record_video
60
+ end
61
+
62
+ # Set custom run command arguments
63
+ #
64
+ # @param [Docker::Command] command
65
+ # @return [void]
66
+ def set_command_args(command)
67
+ command << '-d '
68
+ command << "--name #{name}"
69
+ command << "--net #{network}"
70
+ command << "--hostname #{hostname}"
71
+ command << "--publish 4444:4444"
72
+ command << "-e OVERRIDE_VIDEO_OUTPUT_DIR=#{Runtime::Env.selenoid_directory}/video"
73
+ end
74
+
75
+ # Set volumes
76
+ #
77
+ # @param [Docker::Command] command
78
+ # @return [void]
79
+ def set_volumes(command)
80
+ command.volume('/var/run/docker.sock', '/var/run/docker.sock')
81
+ command.volume("#{__dir__}/../../../../fixtures/selenoid", "/etc/selenoid")
82
+ command.volume("#{Runtime::Env.selenoid_directory}/video", '/opt/selenoid/video')
83
+ end
84
+ end
85
+ end
86
+ end
87
+ 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
@@ -22,6 +22,9 @@ module Gitlab
22
22
  'QA_REMOTE_MOBILE_DEVICE_NAME' => :remote_mobile_device_name,
23
23
  'QA_REMOTE_TUNNEL_ID' => :remote_tunnel_id,
24
24
  'QA_BROWSER' => :browser,
25
+ 'QA_BROWSER_VERSION' => :browser_version,
26
+ 'QA_RECORD_VIDEO' => :record_video,
27
+ 'QA_LAYOUT' => :layout,
25
28
  'QA_ADDITIONAL_REPOSITORY_STORAGE' => :qa_additional_repository_storage,
26
29
  'QA_PRAEFECT_REPOSITORY_STORAGE' => :qa_praefect_repository_storage,
27
30
  'QA_GITALY_NON_CLUSTER_STORAGE' => :qa_gitaly_non_cluster_storage,
@@ -41,6 +44,7 @@ module Gitlab
41
44
  'QA_INFLUXDB_TOKEN' => :qa_influxdb_token,
42
45
  'QA_SKIP_PULL' => :qa_skip_pull,
43
46
  'QA_VALIDATE_RESOURCE_REUSE' => :qa_validate_resource_reuse,
47
+ 'WEBDRIVER_HEADLESS' => :webdriver_headless,
44
48
  'GITLAB_API_BASE' => :api_base,
45
49
  'GITLAB_ADMIN_USERNAME' => :admin_username,
46
50
  'GITLAB_ADMIN_PASSWORD' => :admin_password,
@@ -148,7 +152,9 @@ module Gitlab
148
152
  'RELEASE' => :release,
149
153
  'RELEASE_REGISTRY_URL' => :release_registry_url,
150
154
  'RELEASE_REGISTRY_USERNAME' => :release_registry_username,
151
- 'RELEASE_REGISTRY_PASSWORD' => :release_registry_password
155
+ 'RELEASE_REGISTRY_PASSWORD' => :release_registry_password,
156
+ 'SELENOID_DIRECTORY' => :selenoid_directory,
157
+ 'USE_SELENOID' => :use_selenoid
152
158
  }.freeze
153
159
 
154
160
  ENV_VARIABLES.each do |env_name, method_name|
@@ -349,6 +355,18 @@ module Gitlab
349
355
  enabled?(env_var_value_if_defined('QA_EXPORT_TEST_METRICS'), default: true)
350
356
  end
351
357
 
358
+ def selenoid_directory
359
+ env_var_value_if_defined('SELENOID_DIRECTORY') || "#{host_artifacts_dir}/selenoid"
360
+ end
361
+
362
+ def use_selenoid?
363
+ enabled?(env_var_value_if_defined('USE_SELENOID'), default: false)
364
+ end
365
+
366
+ def mobile_layout?
367
+ env_var_value_if_defined('QA_LAYOUT')&.match?(/tablet|phone/i)
368
+ end
369
+
352
370
  def qa_run_type
353
371
  return env_var_value_if_defined('QA_RUN_TYPE') if env_var_value_valid?('QA_RUN_TYPE')
354
372
 
@@ -8,8 +8,7 @@ module Gitlab
8
8
  def configuration
9
9
  <<~OMNIBUS
10
10
  gitlab_rails['databases']['main']['enable'] = true
11
- gitlab_rails['databases']['ci']['enable'] = true
12
- gitlab_rails['databases']['ci']['db_database'] = 'gitlabhq_production'
11
+ gitlab_rails['databases']['ci']['enable'] = false
13
12
  OMNIBUS
14
13
  end
15
14
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '10.2.2'
5
+ VERSION = '10.4.0'
6
6
  end
7
7
  end
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.2.2
4
+ version: 10.4.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: 2023-04-18 00:00:00.000000000 Z
11
+ date: 2023-05-16 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