gitlab-qa 7.24.5 → 7.25.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab/ci/jobs/actioncable.gitlab-ci.yml +41 -0
  3. data/.gitlab/ci/jobs/base.gitlab-ci.yml +281 -0
  4. data/.gitlab/ci/jobs/cloud_activation.gitlab-ci.yml +30 -0
  5. data/.gitlab/ci/jobs/custom_parallel.gitlab-ci.yml +21 -0
  6. data/.gitlab/ci/jobs/ee_previous_to_ce_update.gitlab-ci.yml +18 -0
  7. data/.gitlab/ci/jobs/elasticsearch.gitlab-ci.yml +20 -0
  8. data/.gitlab/ci/jobs/geo.gitlab-ci.yml +18 -0
  9. data/.gitlab/ci/jobs/gitaly_cluster.gitlab-ci.yml +45 -0
  10. data/.gitlab/ci/jobs/group_saml.gitlab-ci.yml +20 -0
  11. data/.gitlab/ci/jobs/instance.gitlab-ci.yml +55 -0
  12. data/.gitlab/ci/jobs/instance_saml.gitlab-ci.yml +41 -0
  13. data/.gitlab/ci/jobs/integrations.gitlab-ci.yml +14 -0
  14. data/.gitlab/ci/jobs/jira.gitlab-ci.yml +41 -0
  15. data/.gitlab/ci/jobs/large_setup.gitlab-ci.yml +19 -0
  16. data/.gitlab/ci/jobs/ldap_no_server.gitlab-ci.yml +20 -0
  17. data/.gitlab/ci/jobs/ldap_no_tls.gitlab-ci.yml +41 -0
  18. data/.gitlab/ci/jobs/ldap_tls.gitlab-ci.yml +41 -0
  19. data/.gitlab/ci/jobs/mattermost.gitlab-ci.yml +41 -0
  20. data/.gitlab/ci/jobs/mtls.gitlab-ci.yml +17 -0
  21. data/.gitlab/ci/jobs/object_storage.gitlab-ci.yml +49 -0
  22. data/.gitlab/ci/jobs/object_storage_aws.gitlab-ci.yml +25 -0
  23. data/.gitlab/ci/jobs/object_storage_gcs.gitlab-ci.yml +23 -0
  24. data/.gitlab/ci/jobs/object_storage_registry_tls.gitlab-ci.yml +41 -0
  25. data/.gitlab/ci/jobs/omnibus_image.gitlab-ci.yml +15 -0
  26. data/.gitlab/ci/jobs/omnibus_upgrade.gitlab-ci.yml +28 -0
  27. data/.gitlab/ci/jobs/packages.gitlab-ci.yml +25 -0
  28. data/.gitlab/ci/jobs/praefect.gitlab-ci.yml +71 -0
  29. data/.gitlab/ci/jobs/registry.gitlab-ci.yml +41 -0
  30. data/.gitlab/ci/jobs/registry_with_cdn.gitlab-ci.yml +43 -0
  31. data/.gitlab/ci/jobs/relative_url.gitlab-ci.yml +65 -0
  32. data/.gitlab/ci/jobs/repository_storage.gitlab-ci.yml +41 -0
  33. data/.gitlab/ci/jobs/sanity_framework.gitlab-ci.yml +24 -0
  34. data/.gitlab/ci/jobs/service_ping_disabled.gitlab-ci.yml +19 -0
  35. data/.gitlab/ci/jobs/smtp.gitlab-ci.yml +19 -0
  36. data/.gitlab/ci/jobs/staging.gitlab-ci.yml +10 -0
  37. data/.gitlab/ci/jobs/update.gitlab-ci.yml +60 -0
  38. data/.gitlab/ci/rules.gitlab-ci.yml +19 -6
  39. data/.gitlab-ci.yml +115 -1332
  40. data/Dangerfile +1 -3
  41. data/bin/notify_upstream +98 -0
  42. data/docs/what_tests_can_be_run.md +15 -0
  43. data/lib/gitlab/qa/component/base.rb +0 -1
  44. data/lib/gitlab/qa/component/gitlab.rb +35 -0
  45. data/lib/gitlab/qa/component/staging_ref.rb +1 -0
  46. data/lib/gitlab/qa/docker/engine.rb +4 -0
  47. data/lib/gitlab/qa/release.rb +1 -1
  48. data/lib/gitlab/qa/report/relate_failure_issue.rb +9 -3
  49. data/lib/gitlab/qa/runner.rb +10 -0
  50. data/lib/gitlab/qa/runtime/env.rb +14 -1
  51. data/lib/gitlab/qa/scenario/test/instance/staging_ref_geo.rb +27 -0
  52. data/lib/gitlab/qa/scenario/test/integration/mattermost.rb +5 -1
  53. data/lib/gitlab/qa/scenario/test/integration/registry_with_cdn.rb +42 -0
  54. data/lib/gitlab/qa/version.rb +1 -1
  55. data/lib/gitlab/qa.rb +2 -0
  56. data/scripts/generate-qa-jobs.rb +72 -0
  57. data/support/data/license_usage_seed.rb +75 -0
  58. metadata +43 -4
  59. data/.gitlab/ci/danger.gitlab-ci.yml +0 -25
  60. data/bin/notify_upstream_commit +0 -61
data/Dangerfile CHANGED
@@ -1,9 +1,7 @@
1
1
  require 'gitlab-dangerfiles'
2
2
 
3
3
  Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
4
- # Import all plugins from the gem
5
4
  dangerfiles.import_plugins
6
5
 
7
- # Import only a subset of rules
8
- dangerfiles.import_dangerfiles(only: %w[changes_size commit_messages simple_roulette])
6
+ dangerfiles.import_dangerfiles(except: %w[changelog])
9
7
  end
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'gitlab'
5
+
6
+ # Default to "Multi-pipeline (from 'gitlab-org/gitlab-qa' 'notify_upstream:*' jobs)" from current project
7
+ api_token = ENV.fetch('GITLAB_QA_PROJECT_ACCESS_TOKEN') do
8
+ puts "The $GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN variable is deprecated in favor of a dedicated project access token: $GITLAB_QA_PROJECT_ACCESS_TOKEN."
9
+ puts "See https://gitlab.com/groups/gitlab-org/quality/-/epics/17 for more details."
10
+ ENV['GITLAB_BOT_MULTI_PROJECT_PIPELINE_POLLING_TOKEN']
11
+ end
12
+
13
+ # Configure credentials to be used with gitlab gem
14
+ Gitlab.configure do |config|
15
+ config.endpoint = 'https://gitlab.com/api/v4'
16
+ config.private_token = api_token
17
+ end
18
+
19
+ class CommitComment
20
+ UPSTREAM_COMMENT = <<~COMMENT
21
+ - The [`gitlab-qa-mirror` downstream pipeline](%<pipeline_url>s) for https://gitlab.com/%<project_path>s/-/merge_requests/%<mr_iid>s/diffs?commit_id=%<commit_sha>s %<status_with_icon>s
22
+ COMMENT
23
+ IDENTIFIABLE_NOTE_TAG = 'gitlab-qa:upstream-notification-note'
24
+
25
+ def self.mr?
26
+ ENV.key?('TOP_UPSTREAM_SOURCE_PROJECT') &&
27
+ ENV.key?('TOP_UPSTREAM_MERGE_REQUEST_IID') &&
28
+ ENV.key?('TOP_UPSTREAM_SOURCE_SHA') &&
29
+ !ENV['TOP_UPSTREAM_SOURCE_PROJECT'].to_s.empty? &&
30
+ !ENV['TOP_UPSTREAM_MERGE_REQUEST_IID'].to_s.empty? &&
31
+ !ENV['TOP_UPSTREAM_SOURCE_SHA'].to_s.empty?
32
+ end
33
+
34
+ def self.post!(status)
35
+ unless mr?
36
+ puts "All the 'TOP_UPSTREAM_SOURCE_PROJECT', 'TOP_UPSTREAM_MERGE_REQUEST_IID', and 'TOP_UPSTREAM_SOURCE_SHA' environment variables need to be present. We cannot post a comment on the upstream merge request."
37
+ return
38
+ end
39
+
40
+ # Look for an existing note
41
+ upstream_notification_note = Gitlab.merge_request_notes(project_path, mr_iid).auto_paginate.find do |note|
42
+ note.body.include?(IDENTIFIABLE_NOTE_TAG)
43
+ end
44
+
45
+ if upstream_notification_note
46
+ Gitlab.edit_merge_request_note(project_path, mr_iid, upstream_notification_note.id, [upstream_notification_note.body, build_comment(status)].join("\n"))
47
+ else
48
+ Gitlab.create_merge_request_comment(project_path, mr_iid, "<!-- #{IDENTIFIABLE_NOTE_TAG} -->\n#{build_comment(status)}")
49
+ end
50
+ rescue Gitlab::Error::Error => error
51
+ puts "Ignoring the following error: #{error}"
52
+ end
53
+
54
+ def self.project_path
55
+ ENV['TOP_UPSTREAM_SOURCE_PROJECT']
56
+ end
57
+
58
+ def self.mr_iid
59
+ ENV['TOP_UPSTREAM_MERGE_REQUEST_IID']
60
+ end
61
+
62
+ def self.pipeline_url
63
+ ENV['CI_PIPELINE_URL']
64
+ end
65
+
66
+ def self.commit_sha
67
+ ENV['TOP_UPSTREAM_SOURCE_SHA']
68
+ end
69
+
70
+ def self.build_comment(status)
71
+ format(UPSTREAM_COMMENT,
72
+ project_path: project_path,
73
+ mr_iid: mr_iid,
74
+ pipeline_url: pipeline_url,
75
+ status_with_icon: status_with_icon(status),
76
+ commit_sha: commit_sha
77
+ )
78
+ end
79
+
80
+ def self.status_with_icon(status)
81
+ case status
82
+ when :success
83
+ "passed. :white_check_mark:"
84
+ when :failure
85
+ "failed! :boom:"
86
+ end
87
+ end
88
+
89
+ def self.post_to_mr(project_id, mr_iid, comment)
90
+ Gitlab.create_merge_request_comment(project_id, mr_iid, comment)
91
+ end
92
+ end
93
+
94
+ status = ARGV.shift.to_s.strip
95
+
96
+ abort "Please provide a status!" if status == ''
97
+
98
+ CommitComment.post!(status.to_sym)
@@ -818,6 +818,21 @@ $ export GITLAB_PASSWORD="$GITLAB_QA_PASSWORD"
818
818
  $ gitlab-qa Test::Instance::StagingGeo
819
819
  ```
820
820
 
821
+ ### `Test::Instance::StagingRefGeo`
822
+
823
+ This scenario tests that the Geo staging deployment (with [`staging-ref.gitlab.com`](https://staging-ref.gitlab.com) as the primary site and [`geo.staging-ref.gitlab.com`](https://geo.staging-ref.gitlab.com) as the secondary site) works as expected by running tests tagged `:geo` against it. This is done by spinning up a GitLab QA (`gitlab/gitlab-qa`) container and running the `QA::EE::Scenario::Test::Geo` scenario. Note that the Geo setup steps in the `QA::EE::Scenario::Test::Geo` scenario are skipped when testing a live Geo deployment.
824
+
825
+ Scenario requirements are the same as [`Test::Instance::StagingGeo`](#testinstancestaginggeo) described above.
826
+
827
+ ```
828
+ $ export GITLAB_QA_ACCESS_TOKEN=your_api_access_token
829
+ $ export GITLAB_QA_DEV_ACCESS_TOKEN=your_dev_registry_access_token
830
+ $ export GITLAB_USERNAME="gitlab-qa"
831
+ $ export GITLAB_PASSWORD="$GITLAB_QA_PASSWORD"
832
+
833
+ $ gitlab-qa Test::Instance::StagingRefGeo
834
+ ```
835
+
821
836
  ### `Test::Instance::Production`
822
837
 
823
838
  This scenario functions the same as `Test::Instance::Staging`
@@ -124,7 +124,6 @@ module Gitlab
124
124
 
125
125
  return unless docker.running?(name)
126
126
 
127
- docker.stop(name)
128
127
  docker.remove(name)
129
128
  end
130
129
 
@@ -5,6 +5,7 @@ require 'net/http'
5
5
  require 'uri'
6
6
  require 'forwardable'
7
7
  require 'openssl'
8
+ require 'tempfile'
8
9
 
9
10
  module Gitlab
10
11
  module QA
@@ -19,9 +20,11 @@ module Gitlab
19
20
  def_delegators :release, :tag, :image, :edition
20
21
 
21
22
  CERTIFICATES_PATH = File.expand_path('../../../../tls_certificates', __dir__)
23
+ DATA_SEED_PATH = File.expand_path('../../../../support/data', __dir__)
22
24
 
23
25
  SSL_PATH = '/etc/gitlab/ssl'
24
26
  TRUSTED_PATH = '/etc/gitlab/trusted-certs'
27
+ DATA_PATH = '/tmp/data-seeds'
25
28
 
26
29
  def initialize
27
30
  super
@@ -40,6 +43,7 @@ module Gitlab
40
43
  @volumes[@authority_cert_path] = TRUSTED_PATH
41
44
 
42
45
  self.release = 'CE'
46
+ self.exec_commands += seed_test_data_command if Runtime::Scenario.seed_db
43
47
  end
44
48
 
45
49
  def set_formless_login_token
@@ -166,6 +170,12 @@ module Gitlab
166
170
  end
167
171
  end
168
172
 
173
+ def process_exec_commands
174
+ @docker.copy(name, DATA_SEED_PATH, DATA_PATH) if Runtime::Scenario.seed_db
175
+
176
+ exec_commands.each { |command| @docker.exec(name, command) }
177
+ end
178
+
169
179
  def sha_version
170
180
  json = @docker.read_file(
171
181
  @release.image, @release.tag,
@@ -176,6 +186,19 @@ module Gitlab
176
186
  manifest['software']['gitlab-rails']['locked_version']
177
187
  end
178
188
 
189
+ def copy_key_file(env_key)
190
+ key_dir = ENV['CI_PROJECT_DIR'] || Dir.tmpdir
191
+ key_file = Tempfile.new(env_key.downcase, key_dir)
192
+ key_file.write(ENV.fetch(env_key))
193
+ key_file.close
194
+
195
+ File.chmod(0o744, key_file.path)
196
+
197
+ @volumes[key_file.path] = key_file.path
198
+
199
+ key_file.path
200
+ end
201
+
179
202
  private
180
203
 
181
204
  # Copy certs to a temporary directory in current working directory.
@@ -196,6 +219,18 @@ module Gitlab
196
219
  end
197
220
  end
198
221
 
222
+ def seed_test_data_command
223
+ cmd = []
224
+
225
+ Runtime::Scenario.seed_db.each do |file_patterns|
226
+ Dir["#{DATA_SEED_PATH}/#{file_patterns}"].map { |f| File.basename f }.each do |file|
227
+ cmd << "gitlab-rails runner #{DATA_PATH}/#{file}"
228
+ end
229
+ end
230
+
231
+ cmd.uniq
232
+ end
233
+
199
234
  class Availability
200
235
  def initialize(name, relative_path: '', scheme: 'http', protocol_port: 80)
201
236
  @docker = Docker::Engine.new
@@ -3,6 +3,7 @@ module Gitlab
3
3
  module Component
4
4
  class StagingRef < Staging
5
5
  ADDRESS = 'https://staging-ref.gitlab.com'.freeze
6
+ GEO_SECONDARY_ADDRESS = 'https://geo.staging-ref.gitlab.com'.freeze
6
7
  end
7
8
  end
8
9
  end
@@ -76,6 +76,10 @@ module Gitlab
76
76
  Docker::Command.execute("attach --sig-proxy=false #{name}", &block)
77
77
  end
78
78
 
79
+ def copy(name, src_path, dest_path)
80
+ Docker::Command.execute("cp #{src_path} #{name}:#{dest_path}")
81
+ end
82
+
79
83
  def restart(name)
80
84
  Docker::Command.execute("restart #{name}")
81
85
  end
@@ -147,7 +147,7 @@ module Gitlab
147
147
  registry: DEV_REGISTRY
148
148
  }
149
149
  elsif omnibus_mirror?
150
- username, password = if Runtime::Env.ci_job_token && Runtime::Env.ci_pipeline_source == 'pipeline'
150
+ username, password = if Runtime::Env.ci_job_token && Runtime::Env.ci_pipeline_source.include?('pipeline')
151
151
  ['gitlab-ci-token', Runtime::Env.ci_job_token]
152
152
  elsif Runtime::Env.qa_container_registry_access_token
153
153
  [Runtime::Env.gitlab_username, Runtime::Env.qa_container_registry_access_token]
@@ -47,7 +47,7 @@ module Gitlab
47
47
  puts " => Searching issues for test '#{test.name}'..."
48
48
 
49
49
  begin
50
- issue = find_and_link_issue(test) || create_issue(test)
50
+ issue = test.quarantine? ? find_and_link_issue(test) : find_and_link_issue(test) || create_issue(test)
51
51
  return unless issue
52
52
 
53
53
  update_labels(issue, test)
@@ -86,14 +86,16 @@ module Gitlab
86
86
  ld = Class.new.extend(Gem::Text).method(:levenshtein_distance)
87
87
  full_stacktrace = test.failures.first['message_lines'].join("\n")
88
88
  first_test_failure_stacktrace = sanitize_stacktrace(full_stacktrace, FAILURE_STACKTRACE_REGEX) || full_stacktrace
89
+ clean_first_test_failure_stacktrace = remove_unique_resource_names(first_test_failure_stacktrace)
89
90
 
90
91
  # Search with the `search` param returns 500 errors, so we filter by ~QA and then filter further in Ruby
91
92
  failure_issues(test).each_with_object({}) do |issue, memo|
92
93
  relevant_issue_stacktrace = find_issue_stacktrace(issue)
93
94
  next unless relevant_issue_stacktrace
94
95
 
95
- distance = ld.call(first_test_failure_stacktrace, relevant_issue_stacktrace)
96
- diff_ratio = distance.zero? ? 0.0 : (distance.to_f / first_test_failure_stacktrace.size).round(3)
96
+ clean_relevant_issue_stacktrace = remove_unique_resource_names(relevant_issue_stacktrace)
97
+ distance = ld.call(clean_first_test_failure_stacktrace, clean_relevant_issue_stacktrace)
98
+ diff_ratio = distance.zero? ? 0.0 : (distance.to_f / clean_first_test_failure_stacktrace.size).round(3)
97
99
 
98
100
  if diff_ratio <= max_diff_ratio
99
101
  puts " => [DEBUG] Issue #{issue.web_url} has an acceptable diff ratio of #{(diff_ratio * 100).round(2)}%."
@@ -128,6 +130,10 @@ module Gitlab
128
130
  end
129
131
  end
130
132
 
133
+ def remove_unique_resource_names(stacktrace)
134
+ stacktrace.gsub(/qa-(test|user)-[a-z0-9-]+/, '<unique-test-resource>').gsub(/(?:-|_)(?:\d+[a-z]|[a-z]+\d)[a-z\d]{4,}/, '<unique-hash>')
135
+ end
136
+
131
137
  def find_failure_issue(test)
132
138
  relevant_issues = find_relevant_failure_issues(test)
133
139
 
@@ -12,9 +12,11 @@ module Gitlab
12
12
  Runtime::Scenario.define(:run_tests, true)
13
13
  Runtime::Scenario.define(:qa_image, Runtime::Env.qa_image) if Runtime::Env.qa_image
14
14
  Runtime::Scenario.define(:omnibus_configuration, Runtime::OmnibusConfiguration.new)
15
+ Runtime::Scenario.define(:seed_db, false)
15
16
 
16
17
  # Omnibus Configurators specified by flags
17
18
  @active_configurators = []
19
+ @seed_scripts = []
18
20
  @omnibus_configurations = %w[default] # always load default configuration
19
21
 
20
22
  @options = OptionParser.new do |opts|
@@ -45,6 +47,14 @@ module Gitlab
45
47
  end
46
48
  end
47
49
 
50
+ opts.on('--seed-db search_pattern1[,search_pattern2,...]', 'Seed application database with sample test data') do |file_pattern|
51
+ file_pattern.split(',').each do |pattern|
52
+ @seed_scripts << pattern
53
+ end
54
+
55
+ Runtime::Scenario.define(:seed_db, @seed_scripts)
56
+ end
57
+
48
58
  opts.on_tail('-h', '--help', 'Show the usage') do
49
59
  puts opts
50
60
  exit
@@ -127,6 +127,11 @@ module Gitlab
127
127
  'GOOGLE_PROJECT' => :google_project,
128
128
  'GOOGLE_CLIENT_EMAIL' => :google_client_email,
129
129
  'GOOGLE_JSON_KEY' => :google_json_key,
130
+ 'GOOGLE_CDN_JSON_KEY' => :google_cdn_json_key,
131
+ 'GOOGLE_CDN_LB' => :google_cdn_load_balancer,
132
+ 'GOOGLE_CDN_SIGNURL_KEY' => :google_cdn_signurl_key,
133
+ 'GOOGLE_CDN_SIGNURL_KEY_NAME' => :google_cdn_signurl_key_name,
134
+ 'GCS_CDN_BUCKET_NAME' => :gcs_cdn_bucket_name,
130
135
  'GCS_BUCKET_NAME' => :gcs_bucket_name,
131
136
  'SMOKE_ONLY' => :smoke_only,
132
137
  'NO_ADMIN' => :no_admin,
@@ -212,7 +217,7 @@ module Gitlab
212
217
  end
213
218
 
214
219
  def elastic_version
215
- env_var_value_if_defined('ELASTIC_VERSION') || '6.4.2'.freeze
220
+ env_var_value_if_defined('ELASTIC_VERSION') || '7.17.0'.freeze
216
221
  end
217
222
 
218
223
  def require_license!
@@ -275,6 +280,14 @@ module Gitlab
275
280
  end
276
281
  end
277
282
 
283
+ def require_gcs_with_cdn_environment!
284
+ %w[GOOGLE_CDN_JSON_KEY GCS_CDN_BUCKET_NAME GOOGLE_CDN_LB GOOGLE_CDN_SIGNURL_KEY GOOGLE_CDN_SIGNURL_KEY_NAME].each do |env_key|
285
+ unless ENV.key?(env_key)
286
+ raise ArgumentError, "Environment variable #{env_key} must be set to run GCS with CDN enabled scenario"
287
+ end
288
+ end
289
+ end
290
+
278
291
  def require_initial_password!
279
292
  return unless env_var_value_if_defined('GITLAB_INITIAL_ROOT_PASSWORD').to_s.strip.empty?
280
293
 
@@ -0,0 +1,27 @@
1
+ module Gitlab
2
+ module QA
3
+ module Scenario
4
+ module Test
5
+ module Instance
6
+ class StagingRefGeo < DeploymentBase
7
+ def initialize
8
+ @suite = 'QA::EE::Scenario::Test::Geo'
9
+ end
10
+
11
+ def deployment_component
12
+ Component::StagingRef
13
+ end
14
+
15
+ def non_rspec_args
16
+ [
17
+ '--primary-address', deployment_component::ADDRESS,
18
+ '--secondary-address', deployment_component::GEO_SECONDARY_ADDRESS,
19
+ '--without-setup'
20
+ ]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -22,7 +22,11 @@ module Gitlab
22
22
  specs.suite = 'Test::Integration::Mattermost'
23
23
  specs.release = gitlab.release
24
24
  specs.network = gitlab.network
25
- specs.args = [gitlab.address, mattermost_external_url, *rspec_args]
25
+ specs.args = [
26
+ gitlab.address,
27
+ "--mattermost-address", mattermost_external_url,
28
+ *rspec_args
29
+ ]
26
30
  end
27
31
  end
28
32
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module Scenario
6
+ module Test
7
+ module Integration
8
+ class RegistryWithCDN < Scenario::Template
9
+ def perform(release, *rspec_args)
10
+ Runtime::Env.require_gcs_with_cdn_environment!
11
+
12
+ Component::Gitlab.perform do |gitlab|
13
+ gitlab.release = release
14
+ gitlab.network = 'test'
15
+ gitlab.name = 'gitlab'
16
+ sign_url_key_path = gitlab.copy_key_file('GOOGLE_CDN_SIGNURL_KEY')
17
+ cdn_gcloud_path = gitlab.copy_key_file('GOOGLE_CDN_JSON_KEY')
18
+
19
+ gitlab.omnibus_configuration << <<~OMNIBUS
20
+ external_url 'http://#{gitlab.name}.#{gitlab.network}';
21
+ registry_external_url 'http://#{gitlab.name}.#{gitlab.network}:5050';
22
+
23
+ registry['middleware'] = { 'storage' => [{ 'name' => 'googlecdn', 'options' => { 'baseurl' => '#{Runtime::Env.google_cdn_load_balancer}', 'privatekey' => '#{sign_url_key_path}', 'keyname' => '#{Runtime::Env.google_cdn_signurl_key_name}' } }] }
24
+ registry['storage'] = { 'gcs' => { 'bucket' => '#{Runtime::Env.gcs_cdn_bucket_name}', 'keyfile' => '#{cdn_gcloud_path}' } }
25
+ OMNIBUS
26
+
27
+ gitlab.instance do
28
+ Component::Specs.perform do |specs|
29
+ specs.suite = 'Test::Integration::RegistryWithCDN'
30
+ specs.release = gitlab.release
31
+ specs.network = gitlab.network
32
+ specs.args = [gitlab.address, *rspec_args]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '7.24.5'
5
+ VERSION = '7.25.1'
6
6
  end
7
7
  end
data/lib/gitlab/qa.rb CHANGED
@@ -43,6 +43,7 @@ module Gitlab
43
43
  autoload :Release, 'gitlab/qa/scenario/test/instance/release'
44
44
  autoload :Geo, 'gitlab/qa/scenario/test/instance/geo'
45
45
  autoload :StagingGeo, 'gitlab/qa/scenario/test/instance/staging_geo'
46
+ autoload :StagingRefGeo, 'gitlab/qa/scenario/test/instance/staging_ref_geo'
46
47
  autoload :Airgapped, 'gitlab/qa/scenario/test/instance/airgapped'
47
48
  end
48
49
 
@@ -76,6 +77,7 @@ module Gitlab
76
77
  autoload :RegistryTLS, 'gitlab/qa/scenario/test/integration/registry_tls'
77
78
  autoload :ServicePingDisabled, 'gitlab/qa/scenario/test/integration/service_ping_disabled'
78
79
  autoload :Integrations, 'gitlab/qa/scenario/test/integration/integrations'
80
+ autoload :RegistryWithCDN, 'gitlab/qa/scenario/test/integration/registry_with_cdn'
79
81
  end
80
82
 
81
83
  module Sanity
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class GenerateQAJobs
4
+ def initialize(no_of_example_files)
5
+ @no_of_example_files = no_of_example_files
6
+ puts "no_of_example_files: #{@no_of_example_files}"
7
+ end
8
+
9
+ # rubocop:disable Metrics/AbcSize
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ # rubocop:disable Metrics/CyclomaticComplexity
12
+ def execute
13
+ jobs = load_yml_contents('base')
14
+ jobs.concat(load_yml_contents('sanity_framework'))
15
+ jobs.concat(load_yml_contents('custom_parallel'))
16
+ jobs.concat(load_yml_contents('instance')) if should_run?('test_instance_all')
17
+ jobs.concat(load_yml_contents('relative_url')) if should_run?('test_instance_all')
18
+ jobs.concat(load_yml_contents('repository_storage')) if should_run?('test_instance_all_repository_storage')
19
+ jobs.concat(load_yml_contents('omnibus_image'))
20
+ jobs.concat(load_yml_contents('update')) if should_run?('test_instance_all')
21
+ jobs.concat(load_yml_contents('omnibus_upgrade'))
22
+ jobs.concat(load_yml_contents('ee_previous_to_ce_update'))
23
+ jobs.concat(load_yml_contents('mattermost')) if should_run?('test_integration_mattermost')
24
+ jobs.concat(load_yml_contents('service_ping_disabled')) if should_run?('test_integration_servicepingdisabled')
25
+ jobs.concat(load_yml_contents('ldap_no_tls')) if should_run?('test_integration_ldapnotls')
26
+ jobs.concat(load_yml_contents('ldap_tls')) if should_run?('test_integration_ldaptls')
27
+ jobs.concat(load_yml_contents('ldap_no_server')) if should_run?('test_integration_ldapnoserver')
28
+ jobs.concat(load_yml_contents('instance_saml')) if should_run?('test_integration_instancesaml')
29
+ jobs.concat(load_yml_contents('group_saml')) if should_run?('test_integration_groupsaml')
30
+ jobs.concat(load_yml_contents('object_storage')) if should_run?('test_instance_all_object_storage')
31
+ jobs.concat(load_yml_contents('object_storage_aws')) if should_run?('test_instance_all_object_storage')
32
+ jobs.concat(load_yml_contents('object_storage_gcs')) if should_run?('test_instance_all_object_storage')
33
+ jobs.concat(load_yml_contents('object_storage_registry_tls')) if should_run?('test_integration_registrytls')
34
+ jobs.concat(load_yml_contents('registry')) if should_run?('test_integration_registry')
35
+ jobs.concat(load_yml_contents('packages')) if should_run?('test_instance_all_packages')
36
+ jobs.concat(load_yml_contents('actioncable')) if should_run?('test_instance_all_actioncable')
37
+ jobs.concat(load_yml_contents('elasticsearch')) if should_run?('test_integration_elasticsearch')
38
+ jobs.concat(load_yml_contents('praefect')) if should_run?('test_instance_all')
39
+ jobs.concat(load_yml_contents('gitaly_cluster')) if should_run?('test_instance_all')
40
+ jobs.concat(load_yml_contents('mtls')) if should_run?('test_instance_all_mtls')
41
+ jobs.concat(load_yml_contents('smtp')) if should_run?('test_integration_smtp')
42
+ jobs.concat(load_yml_contents('jira')) if should_run?('test_instance_all_jira')
43
+ jobs.concat(load_yml_contents('integrations')) if should_run?('test_instance_all_integrations')
44
+ jobs.concat(load_yml_contents('large_setup')) if should_run?('test_instance_all_can_use_large_setup')
45
+ jobs.concat(load_yml_contents('cloud_activation')) if should_run?('test_instance_all_cloud_activation')
46
+ jobs.concat(load_yml_contents('registry_with_cdn')) if should_run?('test_integration_registrywithcdn')
47
+ jobs.concat(load_yml_contents('staging'))
48
+
49
+ # Disabling geo jobs temporarily due to https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/774
50
+ # base.concat(load_yml_contents('geo')) if should_run?('scenario_test_geo')
51
+
52
+ jobs
53
+ end
54
+ # rubocop:enable Metrics/AbcSize
55
+ # rubocop:enable Metrics/PerceivedComplexity
56
+ # rubocop:enable Metrics/CyclomaticComplexity
57
+
58
+ private
59
+
60
+ def should_run?(example_file_name)
61
+ @no_of_example_files.include?(example_file_name)
62
+ end
63
+
64
+ def load_yml_contents(file_prefix)
65
+ jobs_dir_path = File.expand_path('../.gitlab/ci/jobs', __dir__)
66
+ File.read(File.join(jobs_dir_path, "#{file_prefix}.gitlab-ci.yml"))
67
+ end
68
+ end
69
+
70
+ jobs = GenerateQAJobs.new(Dir.glob('no_of_examples/*').map { |s| File.basename(s, '.*') }).execute
71
+
72
+ File.open('generated-qa-jobs.yml', 'w') { |f| f.write(jobs) }
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Metrics/AbcSize
3
+
4
+ class LicenseUsageSeed
5
+ def self.seed!
6
+ admin_user = User.find_by(username: 'root')
7
+ group_count = seed_groups.count
8
+ user_count = seed_users.count
9
+
10
+ puts 'Start seeding license usage data...'
11
+
12
+ rand(5..20).times { create_group(admin_user) }
13
+ create_users_and_members
14
+
15
+ puts 'Creating License usage record...'
16
+ create_license_usage_record
17
+
18
+ puts "Created #{seed_users.count - user_count} users and #{seed_groups.count - group_count} groups."
19
+ puts 'License usage data seeding completed.'
20
+ end
21
+
22
+ def self.create_user
23
+ name = "test-user#{SecureRandom.hex(8)}"
24
+
25
+ User.create!(
26
+ email: "#{name}@test.com",
27
+ password: 'password',
28
+ username: name,
29
+ name: "User #{name}",
30
+ confirmed_at: Time.current
31
+ )
32
+ end
33
+
34
+ def self.create_group(user)
35
+ name = "test-group#{SecureRandom.hex(8)}"
36
+ group_params =
37
+ {
38
+ name: name,
39
+ path: name
40
+ }
41
+ ::Groups::CreateService.new(user, group_params).execute
42
+ end
43
+
44
+ def self.create_users_and_members
45
+ seed_groups.pluck(:id).each do |group_id|
46
+ 3.times { create_member(create_user, group_id) }
47
+ end
48
+ end
49
+
50
+ def self.create_member(user, group_id)
51
+ roles = Gitlab::Access.values
52
+
53
+ GroupMember.create(user_id: user.id, access_level: roles.sample, source_id: group_id)
54
+ end
55
+
56
+ def self.seed_users
57
+ User.where('username ~* ?', '^test-user')
58
+ end
59
+
60
+ def self.seed_groups
61
+ Group.where('name ~* ?', '^test-group')
62
+ end
63
+
64
+ def self.create_license_usage_record
65
+ # Force update daily billable users and historical license data
66
+ identifier = Analytics::UsageTrends::Measurement.identifiers[:billable_users]
67
+ ::Analytics::UsageTrends::CounterJobWorker.new.perform(identifier, User.minimum(:id), User.maximum(:id), Time.zone.now)
68
+
69
+ HistoricalData.track!
70
+ end
71
+ end
72
+
73
+ LicenseUsageSeed.seed!
74
+
75
+ # rubocop:enable Metrics/AbcSize