gitlab-qa 4.3.3 → 4.4.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.
@@ -20,9 +20,6 @@ Metrics/MethodLength:
20
20
  Rails:
21
21
  Enabled: false
22
22
 
23
- Style/ExtendSelf:
24
- Enabled: false
25
-
26
23
  Style/ModuleFunction:
27
24
  Enabled: false
28
25
 
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'nokogiri'
4
+
5
+ main_report_file = ARGV.shift
6
+ unless main_report_file
7
+ puts 'usage: merge_html_reports <main-report> <base-artifact-url> [parallel reports...]'
8
+ exit 1
9
+ end
10
+
11
+ base_artifact_url = ARGV.shift
12
+ unless base_artifact_url
13
+ puts 'usage: merge_html_reports <main-report> <base-artifact-url> [parallel reports...]'
14
+ exit 1
15
+ end
16
+
17
+ # Create the base report with empty body tag
18
+ new_report = Nokogiri::HTML.parse(File.read(ARGV[0]))
19
+ new_report.at_css('body').remove
20
+ empty_body = Nokogiri::XML::Node.new('body', new_report)
21
+ new_report.at_css('head').add_next_sibling(empty_body)
22
+
23
+ ARGV.each do |report_file|
24
+ report = Nokogiri::HTML.parse(File.read(report_file))
25
+
26
+ report.css('a').each do |link|
27
+ link_suffix = link['href'].slice(19..-1)
28
+ link['href'] = base_artifact_url + link_suffix
29
+ end
30
+
31
+ header = report.css('div #rspec-header')
32
+ tests = report.css('dt[id^="example_group_"]')
33
+
34
+ header.search("//h1/text()").first.content = "Test results for job: #{report_file.slice(/rspec-(.*)\.htm/, 1)}"
35
+
36
+ tests.each do |test|
37
+ title = test.parent
38
+ group = title.parent
39
+ script = title.css('script')
40
+
41
+ if script.inner_html.include? 'makeYellow'
42
+ test.remove_class('passed')
43
+ test.add_class('not_implemented')
44
+
45
+ group.remove_class('passed')
46
+ group.add_class('not_implemented')
47
+ header.add_class('not_implemented')
48
+
49
+ script.remove
50
+ test.next_sibling.remove
51
+ test.next_sibling.remove
52
+
53
+ elsif script.inner_html.include? 'makeRed'
54
+ test.remove_class('passed')
55
+ test.add_class('failed')
56
+
57
+ group.remove_class('passed')
58
+ group.add_class('failed')
59
+ header.add_class('failed')
60
+
61
+ script.remove
62
+ test.next_sibling.remove
63
+ test.next_sibling.remove
64
+ end
65
+ end
66
+
67
+ duration = report.at_css('p#duration')
68
+ totals = report.at_css('p#totals')
69
+
70
+ duration_script = report.css('div.results script')[-2]
71
+ totals_script = report.css('div.results script')[-1]
72
+
73
+ duration_text = duration_script.text.slice(49..-3)
74
+ totals_text = totals_script.text.slice(47..-3)
75
+
76
+ duration.inner_html = duration_text
77
+ totals.inner_html = totals_text
78
+
79
+ duration_script.remove
80
+ totals_script.remove
81
+
82
+ # Add the new result after the last one to keep the test order
83
+ new_report.css('body')[-1].add_next_sibling(report.at_css('body'))
84
+ end
85
+
86
+ File.write(main_report_file, new_report)
@@ -10,7 +10,7 @@ Gitlab.configure do |config|
10
10
  end
11
11
 
12
12
  class CommitComment
13
- def self.post!(status)
13
+ def self.post!(status, report_file_name)
14
14
  unless ENV['TOP_UPSTREAM_SOURCE_SHA']
15
15
  puts "The 'TOP_UPSTREAM_SOURCE_SHA' environment variable is missing, cannot post a comment on a missing upstream commit."
16
16
  return
@@ -33,18 +33,26 @@ class CommitComment
33
33
  "failed! :boom:"
34
34
  end
35
35
 
36
+ # The HTML report can't be opened as a web page so we're forced to
37
+ # download it. See https://gitlab.com/gitlab-org/gitlab/issues/25192
36
38
  Gitlab.create_commit_comment(
37
39
  top_upstream_source_project,
38
40
  top_upstream_source_sha,
39
- "The [`gitlab-qa` downstream pipeline](#{ENV['CI_PIPELINE_URL']}) #{status_with_icon}")
41
+ <<~COMMENT
42
+ The [`gitlab-qa` downstream pipeline](#{ENV['CI_PIPELINE_URL']}) #{status_with_icon}.
43
+
44
+ You can download a report of the test results: [`#{report_file_name}`](#{ENV['CI_JOB_URL']}/artifacts/raw/#{report_file_name})
45
+ COMMENT
46
+ )
40
47
  rescue Gitlab::Error::Error => error
41
48
  puts "Ignoring the following error: #{error}"
42
49
  end
43
50
  end
44
51
 
45
- status = ARGV[0].to_s.strip
46
- if status != ''
47
- CommitComment.post!(status.to_sym)
48
- else
49
- puts "Please provide a status!"
50
- end
52
+ status = ARGV.shift.to_s.strip
53
+ report_file_name = ARGV.shift.to_s.strip
54
+
55
+ abort "Please provide a status!" if status == ''
56
+ abort "Please provide a file name for the report!" if report_file_name == ''
57
+
58
+ CommitComment.post!(status.to_sym, report_file_name)
@@ -5,16 +5,18 @@ make a few changes to your `gdk/gitlab/config/gitlab.yml` file.
5
5
 
6
6
  1. Retrieve your current local IP with `ifconfig`, e.g. `192.168.0.12`.
7
7
  1. Create a file named `host` in your GDK directory containing your IP. E.g.:
8
- `echo 192.168.0.12 > host`
9
- 1. Edit `gdk/gitlab/config/gitlab.yml` and replace `host: localhost` with
10
- `host: 192.168.0.12`.
11
- 1. Also replace `ssh_host: localhost` (found under `gitlab_shell`) with
8
+ `echo "192.168.0.12" > host`
9
+ 1. Edit `gdk/gitlab/config/gitlab.yml` and
10
+ - replace `host: localhost` under `production:gitlab` with `host: 192.168.0.12`.
11
+ - replace `ssh_host: localhost` under `production:gitlab_shell` with
12
12
  `ssh_host: 192.168.0.12`.
13
- 1. Enable the `sshd` service by uncommenting the relevant line in your
14
- `Procfile`.
15
- 1. Edit `openssh/sshd_config` and
13
+ - replace `host: localhost` under `production:webpack:dev_server` with
14
+ `host: 192.168.0.12`.
15
+ 1. Edit `Procfile` in your GDK directory and
16
+ - enable the `sshd` service by uncommenting the relevant line
17
+ 1. Edit `openssh/sshd_config` in your GDK directory and
16
18
  - set `ListenAddress` to `192.168.0.12:2222`
17
- - add `AcceptEnv GIT_PROTOCOL` to allow use of [Git protocol v2][Git protocol]
19
+ - add `AcceptEnv GIT_PROTOCOL` to allow the use of the [Git protocol v2][Git protocol]
18
20
  1. Restart your GDK
19
21
  1. Run the QA scenario as follows:
20
22
 
@@ -36,6 +36,14 @@ For more details on the internals, please read the
36
36
  * `GITLAB_QA_PASSWORD_1` - password for `GITLAB_QA_USERNAME_1` available in environments where signup is disabled (e.g. staging.gitlab.com)
37
37
  * `GITLAB_QA_USERNAME_2` - another username available in environments where signup is disabled
38
38
  * `GITLAB_QA_PASSWORD_2` - password for `GITLAB_QA_USERNAME_2` available in environments where signup is disabled (e.g. staging.gitlab.com)
39
+ * `GITLAB_QA_USERNAME_3` - another username available in environments where signup is disabled
40
+ * `GITLAB_QA_PASSWORD_3` - password for `GITLAB_QA_USERNAME_3` available in environments where signup is disabled (e.g. staging.gitlab.com)
41
+ * `GITLAB_QA_USERNAME_4` - another username available in environments where signup is disabled
42
+ * `GITLAB_QA_PASSWORD_4` - password for `GITLAB_QA_USERNAME_4` available in environments where signup is disabled (e.g. staging.gitlab.com)
43
+ * `GITLAB_QA_USERNAME_5` - another username available in environments where signup is disabled
44
+ * `GITLAB_QA_PASSWORD_5` - password for `GITLAB_QA_USERNAME_5` available in environments where signup is disabled (e.g. staging.gitlab.com)
45
+ * `GITLAB_QA_USERNAME_6` - another username available in environments where signup is disabled
46
+ * `GITLAB_QA_PASSWORD_6` - password for `GITLAB_QA_USERNAME_6` available in environments where signup is disabled (e.g. staging.gitlab.com)
39
47
  * `GITLAB_LDAP_USERNAME` - LDAP username to use when signing into GitLab
40
48
  * `GITLAB_LDAP_PASSWORD` - LDAP password to use when signing into GitLab
41
49
  * `GITLAB_ADMIN_USERNAME` - Admin username to use when adding a license
@@ -1,4 +1,4 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
  require 'gitlab/qa/version'
4
4
 
@@ -20,11 +20,11 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  # Some dependencies are pinned, to prevent new cops from breaking the CI pipelines
22
22
  spec.add_development_dependency 'climate_control', '~> 0.2'
23
- spec.add_development_dependency 'gitlab-styles', '2.2.0'
23
+ spec.add_development_dependency 'gitlab-styles', '2.4.0'
24
24
  spec.add_development_dependency 'pry', '~> 0.11'
25
25
  spec.add_development_dependency 'rake', '~> 12.2'
26
26
  spec.add_development_dependency 'rspec', '~> 3.7'
27
- spec.add_development_dependency 'rubocop', '0.52.0'
27
+ spec.add_development_dependency 'rubocop', '~> 0.54.0'
28
28
  spec.add_development_dependency 'rubocop-rspec', '1.20.1'
29
29
  spec.add_development_dependency 'webmock', '3.7.0'
30
30
  end
@@ -64,6 +64,12 @@ module Gitlab
64
64
  autoload :Elasticsearch, 'gitlab/qa/component/elasticsearch'
65
65
  end
66
66
 
67
+ module Support
68
+ autoload :GetRequest, 'gitlab/qa/support/get_request'
69
+ autoload :DevEEQAImage, 'gitlab/qa/support/dev_ee_qa_image'
70
+ autoload :InvalidResponseError, 'gitlab/qa/support/invalid_response_error'
71
+ end
72
+
67
73
  module Docker
68
74
  autoload :Command, 'gitlab/qa/docker/command'
69
75
  autoload :Engine, 'gitlab/qa/docker/engine'
@@ -97,6 +97,17 @@ module Gitlab
97
97
  def start # rubocop:disable Metrics/AbcSize
98
98
  ensure_configured!
99
99
 
100
+ if release.dev_gitlab_org?
101
+ Docker::Command.execute(
102
+ [
103
+ 'login',
104
+ '--username gitlab-qa-bot',
105
+ %(--password "#{Runtime::Env.dev_access_token_variable}"),
106
+ Release::DEV_REGISTRY
107
+ ]
108
+ )
109
+ end
110
+
100
111
  docker.run(image, tag) do |command|
101
112
  command << "-d -p #{port}"
102
113
  command << "--name #{name}"
@@ -18,6 +18,17 @@ module Gitlab
18
18
  def perform # rubocop:disable Metrics/AbcSize
19
19
  raise ArgumentError unless [suite, release].all?
20
20
 
21
+ if release.dev_gitlab_org?
22
+ Docker::Command.execute(
23
+ [
24
+ 'login',
25
+ '--username gitlab-qa-bot',
26
+ %(--password "#{Runtime::Env.dev_access_token_variable}"),
27
+ Release::DEV_REGISTRY
28
+ ]
29
+ )
30
+ end
31
+
21
32
  puts "Running test suite `#{suite}` for #{release.project_name}"
22
33
 
23
34
  name = "#{release.project_name}-qa-#{SecureRandom.hex(4)}"
@@ -8,19 +8,9 @@ module Gitlab
8
8
  class Staging
9
9
  ADDRESS = 'https://staging.gitlab.com'.freeze
10
10
 
11
- class InvalidResponseError < StandardError
12
- attr_reader :response
13
-
14
- def initialize(address, response)
15
- @response = response
16
-
17
- super "Invalid response received from #{address}"
18
- end
19
- end
20
-
21
11
  def self.release
22
12
  Release.new(image)
23
- rescue InvalidResponseError => ex
13
+ rescue Support::InvalidResponseError => ex
24
14
  warn ex.message
25
15
  warn "#{ex.response.code} #{ex.response.message}: #{ex.response.body}"
26
16
  exit 1
@@ -40,7 +30,7 @@ module Gitlab
40
30
  # - https://gitlab.com/gitlab-org/quality/staging/issues/56
41
31
  # - https://gitlab.com/gitlab-org/release/framework/issues/421
42
32
  # - https://gitlab.com/gitlab-org/gitlab-qa/issues/398
43
- DevEEQAImage.new.retrieve_image_from_container_registry!(staging_revision)
33
+ Support::DevEEQAImage.new.retrieve_image_from_container_registry!(staging_revision)
44
34
  else
45
35
  # Auto-deploy builds have a tag formatted like 12.0.12345+5159f2949cb.59c9fa631
46
36
  # but the version api returns a semver version like 12.0.1
@@ -84,88 +74,13 @@ module Gitlab
84
74
  private
85
75
 
86
76
  def api_get!
87
- @response_body ||=
77
+ @response_body ||= # rubocop:disable Naming/MemoizedInstanceVariableName
88
78
  begin
89
- response = GetRequest.new(uri, Runtime::Env.qa_access_token).execute!
79
+ response = Support::GetRequest.new(uri, Runtime::Env.qa_access_token).execute!
90
80
  JSON.parse(response.body)
91
81
  end
92
82
  end
93
83
  end
94
-
95
- class DevEEQAImage
96
- attr_reader :base_url
97
-
98
- DEV_ADDRESS = 'https://dev.gitlab.org'.freeze
99
- GITLAB_EE_QA_REPOSITORY_ID = 55
100
- QAImageNotFoundError = Class.new(StandardError)
101
-
102
- def initialize
103
- @base_url = "#{DEV_ADDRESS}/api/v4/projects/gitlab%2Fomnibus-gitlab/registry/repositories/#{GITLAB_EE_QA_REPOSITORY_ID}/tags?per_page=100"
104
-
105
- Runtime::Env.require_qa_dev_access_token!
106
- end
107
-
108
- def retrieve_image_from_container_registry!(revision)
109
- request_url = base_url
110
-
111
- begin
112
- response = api_get!(URI.parse(request_url))
113
- tags = JSON.parse(response.body)
114
-
115
- matching_qa_image_tag = find_matching_qa_image_tag(tags, revision)
116
- return matching_qa_image_tag['location'] if matching_qa_image_tag
117
-
118
- request_url = next_page_url_from_response(response)
119
- end while request_url
120
-
121
- raise QAImageNotFoundError, "No `gitlab-ee-qa` image could be found for the revision `#{revision}`."
122
- end
123
-
124
- private
125
-
126
- def api_get!(uri)
127
- GetRequest.new(uri, Runtime::Env.qa_dev_access_token).execute!
128
- end
129
-
130
- def next_page_url_from_response(response)
131
- response['x-next-page'].to_s != '' ? "#{base_url}&page=#{response['x-next-page']}" : nil
132
- end
133
-
134
- def find_matching_qa_image_tag(tags, revision)
135
- tags.find { |tag| tag['name'].end_with?(revision) }
136
- end
137
- end
138
-
139
- class GetRequest
140
- attr_reader :uri, :token
141
-
142
- def initialize(uri, token)
143
- @uri = uri
144
- @token = token
145
- end
146
-
147
- def execute!
148
- response =
149
- Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
150
- http.request(build_request)
151
- end
152
-
153
- case response
154
- when Net::HTTPSuccess
155
- response
156
- else
157
- raise InvalidResponseError.new(uri.to_s, response)
158
- end
159
- end
160
-
161
- private
162
-
163
- def build_request
164
- Net::HTTP::Get.new(uri).tap do |req|
165
- req['PRIVATE-TOKEN'] = token
166
- end
167
- end
168
- end
169
84
  end
170
85
  end
171
86
  end
@@ -20,6 +20,21 @@ module Gitlab
20
20
  (:(?<tag>.+))?
21
21
  \z
22
22
  }xi
23
+
24
+ # Dev tag example:
25
+ # 12.1.201906121026-325a6632895.b340d0bd35d
26
+ # |----|------------|-----------|-----------|
27
+ # | | | |
28
+ # | | | omnibus-ref
29
+ # | | gitlab-ee ref
30
+ # | timestamp
31
+ # version
32
+ DEV_TAG_REGEX = /
33
+ \A
34
+ (?<version>\d+\.\d+(.\d+)?)\.(?<timestamp>\d+)\-(?<gitlab_ref>[A-Za-z0-9]+)\.(?<omnibus_ref>[A-Za-z0-9]+)
35
+ \z
36
+ /xi
37
+
23
38
  DEFAULT_TAG = 'latest'.freeze
24
39
  DEFAULT_CANONICAL_TAG = 'nightly'.freeze
25
40
  DEV_REGISTRY = 'dev.gitlab.org:5005'.freeze
@@ -98,7 +113,11 @@ module Gitlab
98
113
 
99
114
  # Tag scheme for gitlab-{ce,ee}-qa images is like 11.1.0-rc12-ee
100
115
  def qa_tag
101
- tag.sub(/[-\.]([ce]e)(\.(\d+))?\z/, '-\1')
116
+ if dev_gitlab_org? && (match_data = tag.match(DEV_TAG_REGEX))
117
+ "#{match_data[:version]}-#{match_data[:gitlab_ref]}"
118
+ else
119
+ tag.sub(/[-\.]([ce]e)(\.(\d+))?\z/, '-\1')
120
+ end
102
121
  end
103
122
 
104
123
  def dev_gitlab_org?
@@ -18,17 +18,6 @@ module Gitlab
18
18
 
19
19
  args.unshift(release_name) if release_name&.start_with?('--')
20
20
 
21
- if release.dev_gitlab_org?
22
- Docker::Command.execute(
23
- [
24
- 'login',
25
- '--username gitlab-qa-bot',
26
- %(--password "#{Runtime::Env.dev_access_token_variable}"),
27
- Release::DEV_REGISTRY
28
- ]
29
- )
30
- end
31
-
32
21
  Component::Specs.perform do |specs|
33
22
  specs.suite = 'Test::Instance::All'
34
23
  specs.release = release
@@ -8,7 +8,6 @@ module Gitlab
8
8
 
9
9
  ##
10
10
  # rubocop:disable Lint/MissingCopEnableDirective
11
- # rubocop:disable Metrics/MethodLength
12
11
  # rubocop:disable Metrics/AbcSize
13
12
  #
14
13
  def perform(release, *rspec_args)
@@ -6,7 +6,6 @@ module Gitlab
6
6
  module Test
7
7
  module Integration
8
8
  class ObjectStorage < Scenario::Template
9
- # rubocop:disable Metrics/AbcSize
10
9
  def perform(release, *rspec_args)
11
10
  Component::Gitlab.perform do |gitlab|
12
11
  gitlab.release = release
@@ -41,7 +40,6 @@ module Gitlab
41
40
  end
42
41
  end
43
42
  end
44
- # rubocop:enable Metrics/AbcSize
45
43
  end
46
44
  end
47
45
  end