gitlab-qa 6.1.3 → 6.5.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/.gitlab-ci.yml +0 -38
- data/.gitlab/merge_request_templates/Release.md +1 -1
- data/docs/what_tests_can_be_run.md +1 -0
- data/lib/gitlab/qa.rb +3 -0
- data/lib/gitlab/qa/component/gitlab.rb +2 -2
- data/lib/gitlab/qa/component/postgresql.rb +2 -1
- data/lib/gitlab/qa/component/specs.rb +2 -0
- data/lib/gitlab/qa/report/base_test_results.rb +36 -0
- data/lib/gitlab/qa/report/gitlab_issue_client.rb +135 -0
- data/lib/gitlab/qa/report/json_test_results.rb +14 -6
- data/lib/gitlab/qa/report/junit_test_results.rb +12 -6
- data/lib/gitlab/qa/report/report_as_issue.rb +47 -0
- data/lib/gitlab/qa/report/results_in_issues.rb +33 -153
- data/lib/gitlab/qa/report/test_result.rb +95 -41
- data/lib/gitlab/qa/reporter.rb +4 -19
- data/lib/gitlab/qa/runtime/env.rb +10 -27
- data/lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb +7 -2
- data/lib/gitlab/qa/scenario/test/integration/praefect.rb +41 -84
- data/lib/gitlab/qa/scenario/test/omnibus/image.rb +1 -1
- data/lib/gitlab/qa/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97ec064795e04d091b6d04bff27d6c163635a1a08d1e9b28efedf17111f2b1a6
|
4
|
+
data.tar.gz: 8318fb6919671c0af482d9dda37f751d15d60732b6654eca890fd87118f9f8d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dcc298d8f343ee158a4e1229748a96853555082f20de96ed3b5851e413fdc47a832eebd9d0f27f8aba959aacdcbd28c0409beea9abbf8ca7a8feeb18cc066171
|
7
|
+
data.tar.gz: 8bdf4528158b4f5c5f09bb87f4604dc3eda02c73d98a064714375f24f0e245c636fefb5a6e5b2f7c93db8d46053b5ebeb7eb3821fd17ae8c04eb459f8c0154fd
|
data/.gitlab-ci.yml
CHANGED
@@ -229,44 +229,6 @@ ee:instance-quarantine:
|
|
229
229
|
variables:
|
230
230
|
QA_RSPEC_TAGS: "--tag quarantine --tag ~orchestrated"
|
231
231
|
|
232
|
-
ce:docker:
|
233
|
-
extends:
|
234
|
-
- .test
|
235
|
-
- .high-capacity
|
236
|
-
- .ce-qa
|
237
|
-
- .rspec-report-opts
|
238
|
-
variables:
|
239
|
-
QA_RSPEC_TAGS: "--tag docker"
|
240
|
-
|
241
|
-
ce:docker-quarantine:
|
242
|
-
extends:
|
243
|
-
- .test
|
244
|
-
- .high-capacity
|
245
|
-
- .ce-qa
|
246
|
-
- .quarantine
|
247
|
-
- .rspec-report-opts
|
248
|
-
variables:
|
249
|
-
QA_RSPEC_TAGS: "--tag docker --tag quarantine"
|
250
|
-
|
251
|
-
ee:docker:
|
252
|
-
extends:
|
253
|
-
- .test
|
254
|
-
- .high-capacity
|
255
|
-
- .ee-qa
|
256
|
-
- .rspec-report-opts
|
257
|
-
variables:
|
258
|
-
QA_RSPEC_TAGS: "--tag docker"
|
259
|
-
|
260
|
-
ee:docker-quarantine:
|
261
|
-
extends:
|
262
|
-
- .test
|
263
|
-
- .high-capacity
|
264
|
-
- .ee-qa
|
265
|
-
- .quarantine
|
266
|
-
- .rspec-report-opts
|
267
|
-
variables:
|
268
|
-
QA_RSPEC_TAGS: "--tag docker --tag quarantine"
|
269
|
-
|
270
232
|
ce:relative_url:
|
271
233
|
extends:
|
272
234
|
- .test
|
@@ -32,4 +32,4 @@ with the latest commit from https://gitlab.com/gitlab-org/gitlab-qa/commits/mast
|
|
32
32
|
- Checklist after merging:
|
33
33
|
- [ ] [Create a tag for the new release version](docs/release_process.md#how-to).
|
34
34
|
|
35
|
-
/label ~Quality ~
|
35
|
+
/label ~Quality ~"feature::maintenance"
|
@@ -83,6 +83,7 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
|
|
83
83
|
| `JIRA_ADMIN_USERNAME` |- | Username for authenticating with Jira server as admin. | No|
|
84
84
|
| `JIRA_ADMIN_PASSWORD` |- | Password for authenticating with Jira server as admin. | No|
|
85
85
|
| `CACHE_NAMESPACE_NAME` | `true` | Cache namespace name for groups. | No|
|
86
|
+
| `DEPLOY_VERSION` |- | The version of GitLab being tested against. | No|
|
86
87
|
|
87
88
|
## [Supported Remote Grid environment variables](./running_against_remote_grid.md)
|
88
89
|
|
data/lib/gitlab/qa.rb
CHANGED
@@ -97,9 +97,12 @@ module Gitlab
|
|
97
97
|
end
|
98
98
|
|
99
99
|
module Report
|
100
|
+
autoload :GitlabIssueClient, 'gitlab/qa/report/gitlab_issue_client'
|
101
|
+
autoload :BaseTestResults, 'gitlab/qa/report/base_test_results'
|
100
102
|
autoload :JsonTestResults, 'gitlab/qa/report/json_test_results'
|
101
103
|
autoload :JUnitTestResults, 'gitlab/qa/report/junit_test_results'
|
102
104
|
autoload :PrepareStageReports, 'gitlab/qa/report/prepare_stage_reports'
|
105
|
+
autoload :ReportAsIssue, 'gitlab/qa/report/report_as_issue'
|
103
106
|
autoload :ResultsInIssues, 'gitlab/qa/report/results_in_issues'
|
104
107
|
autoload :SummaryTable, 'gitlab/qa/report/summary_table'
|
105
108
|
autoload :TestResult, 'gitlab/qa/report/test_result'
|
@@ -128,10 +128,10 @@ module Gitlab
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
-
def
|
131
|
+
def wait_until_ready
|
132
132
|
return if skip_availability_check
|
133
133
|
|
134
|
-
if Availability.new(name, relative_path: relative_path, scheme: scheme, protocol_port: port.to_i).check(
|
134
|
+
if Availability.new(name, relative_path: relative_path, scheme: scheme, protocol_port: port.to_i).check(300)
|
135
135
|
sleep 12 # TODO, handle that better
|
136
136
|
puts ' -> GitLab is available.'
|
137
137
|
else
|
@@ -23,6 +23,8 @@ module Gitlab
|
|
23
23
|
|
24
24
|
@docker.login(**release.login_params) if release.login_params
|
25
25
|
|
26
|
+
@docker.pull(release.qa_image, release.qa_tag) unless Runtime::Env.skip_pull?
|
27
|
+
|
26
28
|
puts "Running test suite `#{suite}` for #{release.project_name}"
|
27
29
|
|
28
30
|
name = "#{release.project_name}-qa-#{SecureRandom.hex(4)}"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Report
|
6
|
+
class BaseTestResults
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
def initialize(path)
|
10
|
+
@results = parse(path)
|
11
|
+
@testcases = process
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&block)
|
15
|
+
testcases.each(&block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(path)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :results, :testcases
|
25
|
+
|
26
|
+
def parse(path)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def process
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gitlab'
|
4
|
+
|
5
|
+
module Gitlab
|
6
|
+
# Monkey patch the Gitlab client to use the correct API path and add required methods
|
7
|
+
class Client
|
8
|
+
def team_member(project, id)
|
9
|
+
get("/projects/#{url_encode(project)}/members/all/#{id}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def issue_discussions(project, issue_id, options = {})
|
13
|
+
get("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions", query: options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_note_to_issue_discussion_as_thread(project, issue_id, discussion_id, options = {})
|
17
|
+
post("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions/#{discussion_id}/notes", query: options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module QA
|
22
|
+
module Report
|
23
|
+
# The GitLab client is used for API access: https://github.com/NARKOZ/gitlab
|
24
|
+
class GitlabIssueClient
|
25
|
+
MAINTAINER_ACCESS_LEVEL = 40
|
26
|
+
RETRY_BACK_OFF_DELAY = 60
|
27
|
+
MAX_RETRY_ATTEMPTS = 3
|
28
|
+
|
29
|
+
def initialize(token:, project:)
|
30
|
+
@token = token
|
31
|
+
@project = project
|
32
|
+
@retry_backoff = 0
|
33
|
+
|
34
|
+
configure_gitlab_client
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_user_permission!
|
38
|
+
handle_gitlab_client_exceptions do
|
39
|
+
user = Gitlab.user
|
40
|
+
member = Gitlab.team_member(project, user.id)
|
41
|
+
|
42
|
+
abort_not_permitted if member.access_level < MAINTAINER_ACCESS_LEVEL
|
43
|
+
end
|
44
|
+
rescue Gitlab::Error::NotFound
|
45
|
+
abort_not_permitted
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_issues(iid:, options: {}, &select)
|
49
|
+
select ||= :itself
|
50
|
+
|
51
|
+
handle_gitlab_client_exceptions do
|
52
|
+
return [Gitlab.issue(project, iid)] if iid
|
53
|
+
|
54
|
+
Gitlab.issues(project, options)
|
55
|
+
.auto_paginate
|
56
|
+
.select(&select)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_issue(title:, description:, labels:)
|
61
|
+
puts "Creating issue..."
|
62
|
+
|
63
|
+
handle_gitlab_client_exceptions do
|
64
|
+
Gitlab.create_issue(
|
65
|
+
project,
|
66
|
+
title,
|
67
|
+
{ description: description, labels: labels }
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def edit_issue(iid:, options: {})
|
73
|
+
handle_gitlab_client_exceptions do
|
74
|
+
Gitlab.edit_issue(project, iid, options)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def handle_gitlab_client_exceptions
|
79
|
+
yield
|
80
|
+
rescue Gitlab::Error::NotFound
|
81
|
+
# This error could be raised in assert_user_permission!
|
82
|
+
# If so, we want it to terminate at that point
|
83
|
+
raise
|
84
|
+
rescue SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::InternalServerError, Gitlab::Error::Parsing => e
|
85
|
+
@retry_backoff += RETRY_BACK_OFF_DELAY
|
86
|
+
|
87
|
+
raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS
|
88
|
+
|
89
|
+
warn_exception(e)
|
90
|
+
warn("Sleeping for #{@retry_backoff} seconds before retrying...")
|
91
|
+
sleep @retry_backoff
|
92
|
+
|
93
|
+
retry
|
94
|
+
rescue StandardError => e
|
95
|
+
pipeline = QA::Runtime::Env.pipeline_from_project_name
|
96
|
+
channel = pipeline == "canary" ? "qa-production" : "qa-#{pipeline}"
|
97
|
+
error_msg = warn_exception(e)
|
98
|
+
slack_options = {
|
99
|
+
channel: channel,
|
100
|
+
icon_emoji: ':ci_failing:',
|
101
|
+
message: <<~MSG
|
102
|
+
An unexpected error occurred while reporting test results in issues.
|
103
|
+
The error occurred in job: #{QA::Runtime::Env.ci_job_url}
|
104
|
+
`#{error_msg}`
|
105
|
+
MSG
|
106
|
+
}
|
107
|
+
puts "Posting Slack message to channel: #{channel}"
|
108
|
+
|
109
|
+
Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
attr_reader :token, :project
|
115
|
+
|
116
|
+
def configure_gitlab_client
|
117
|
+
Gitlab.configure do |config|
|
118
|
+
config.endpoint = Runtime::Env.gitlab_api_base
|
119
|
+
config.private_token = token
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def abort_not_permitted
|
124
|
+
abort "You must have at least Maintainer access to the project to use this feature."
|
125
|
+
end
|
126
|
+
|
127
|
+
def warn_exception(error)
|
128
|
+
error_msg = "#{error.class.name} #{error.message}"
|
129
|
+
warn(error_msg)
|
130
|
+
error_msg
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -5,15 +5,23 @@ require 'json'
|
|
5
5
|
module Gitlab
|
6
6
|
module QA
|
7
7
|
module Report
|
8
|
-
class JsonTestResults
|
9
|
-
|
8
|
+
class JsonTestResults < BaseTestResults
|
9
|
+
def write(path)
|
10
|
+
json = results.merge('examples' => testcases.map(&:report))
|
10
11
|
|
11
|
-
|
12
|
-
@testcases = JSON.parse(File.read(file))['examples'].map { |test| TestResult.from_json(test) }
|
12
|
+
File.write(path, JSON.pretty_generate(json))
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
private
|
16
|
+
|
17
|
+
def parse(path)
|
18
|
+
JSON.parse(File.read(path))
|
19
|
+
end
|
20
|
+
|
21
|
+
def process
|
22
|
+
results['examples'].map do |test|
|
23
|
+
TestResult.from_json(test)
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
@@ -5,15 +5,21 @@ require 'nokogiri'
|
|
5
5
|
module Gitlab
|
6
6
|
module QA
|
7
7
|
module Report
|
8
|
-
class JUnitTestResults
|
9
|
-
|
8
|
+
class JUnitTestResults < BaseTestResults
|
9
|
+
def write(path)
|
10
|
+
# Ignore it for now
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
10
14
|
|
11
|
-
def
|
12
|
-
|
15
|
+
def parse(path)
|
16
|
+
Nokogiri::XML.parse(File.read(path))
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
16
|
-
|
19
|
+
def process
|
20
|
+
results.xpath('//testcase').map do |test|
|
21
|
+
TestResult.from_junit(test)
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gitlab
|
4
|
+
module QA
|
5
|
+
module Report
|
6
|
+
class ReportAsIssue
|
7
|
+
def initialize(token:, input_files:, project: nil)
|
8
|
+
@gitlab = GitlabIssueClient.new(token: token, project: project)
|
9
|
+
@files = Array(input_files)
|
10
|
+
@project = project
|
11
|
+
end
|
12
|
+
|
13
|
+
def invoke!
|
14
|
+
validate_input!
|
15
|
+
|
16
|
+
run!
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :gitlab, :files, :project
|
22
|
+
|
23
|
+
def run!
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_input!
|
28
|
+
assert_project!
|
29
|
+
assert_input_files!(files)
|
30
|
+
gitlab.assert_user_permission!
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_project!
|
34
|
+
return if project
|
35
|
+
|
36
|
+
abort "Please provide a valid project ID or path with the `-p/--project` option!"
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_input_files!(files)
|
40
|
+
return if Dir.glob(files).any?
|
41
|
+
|
42
|
+
abort "Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,58 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'nokogiri'
|
4
|
-
require 'gitlab'
|
5
4
|
require 'active_support/core_ext/enumerable'
|
6
5
|
|
7
6
|
module Gitlab
|
8
|
-
# Monkey patch the Gitlab client to use the correct API path and add required methods
|
9
|
-
class Client
|
10
|
-
def team_member(project, id)
|
11
|
-
get("/projects/#{url_encode(project)}/members/all/#{id}")
|
12
|
-
end
|
13
|
-
|
14
|
-
def issue_discussions(project, issue_id, options = {})
|
15
|
-
get("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions", query: options)
|
16
|
-
end
|
17
|
-
|
18
|
-
def add_note_to_issue_discussion_as_thread(project, issue_id, discussion_id, options = {})
|
19
|
-
post("/projects/#{url_encode(project)}/issues/#{issue_id}/discussions/#{discussion_id}/notes", query: options)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
7
|
module QA
|
24
8
|
module Report
|
25
9
|
# Uses the API to create or update GitLab issues with the results of tests from RSpec report files.
|
26
|
-
|
27
|
-
class ResultsInIssues
|
28
|
-
MAINTAINER_ACCESS_LEVEL = 40
|
10
|
+
class ResultsInIssues < ReportAsIssue
|
29
11
|
MAX_TITLE_LENGTH = 255
|
30
|
-
RETRY_BACK_OFF_DELAY = 60
|
31
|
-
MAX_RETRY_ATTEMPTS = 3
|
32
|
-
|
33
|
-
def initialize(token:, input_files:, project: nil)
|
34
|
-
@token = token
|
35
|
-
@files = Array(input_files)
|
36
|
-
@project = project
|
37
|
-
@retry_backoff = 0
|
38
|
-
end
|
39
|
-
|
40
|
-
def invoke!
|
41
|
-
configure_gitlab_client
|
42
12
|
|
43
|
-
|
13
|
+
private
|
44
14
|
|
15
|
+
def run!
|
45
16
|
puts "Reporting test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
46
17
|
|
47
|
-
Dir.glob(files).each do |
|
48
|
-
puts "Reporting tests in #{
|
49
|
-
extension = File.extname(
|
18
|
+
Dir.glob(files).each do |path|
|
19
|
+
puts "Reporting tests in #{path}"
|
20
|
+
extension = File.extname(path)
|
50
21
|
|
51
22
|
case extension
|
52
23
|
when '.json'
|
53
|
-
test_results = Report::JsonTestResults.new(
|
24
|
+
test_results = Report::JsonTestResults.new(path)
|
54
25
|
when '.xml'
|
55
|
-
test_results = Report::JUnitTestResults.new(
|
26
|
+
test_results = Report::JUnitTestResults.new(path)
|
56
27
|
else
|
57
28
|
raise "Unknown extension #{extension}"
|
58
29
|
end
|
@@ -60,52 +31,8 @@ module Gitlab
|
|
60
31
|
test_results.each do |test|
|
61
32
|
report_test(test)
|
62
33
|
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
attr_reader :files, :token, :project
|
69
|
-
|
70
|
-
def validate_input!
|
71
|
-
assert_project!
|
72
|
-
assert_input_files!(files)
|
73
|
-
assert_user_permission!
|
74
|
-
end
|
75
|
-
|
76
|
-
def assert_project!
|
77
|
-
return if project
|
78
|
-
|
79
|
-
abort "Please provide a valid project ID or path with the `-p/--project` option!"
|
80
|
-
end
|
81
|
-
|
82
|
-
def assert_input_files!(files)
|
83
|
-
return if Dir.glob(files).any?
|
84
|
-
|
85
|
-
abort "Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`"
|
86
|
-
end
|
87
|
-
|
88
|
-
def assert_user_permission!
|
89
|
-
handle_gitlab_client_exceptions do
|
90
|
-
user = Gitlab.user
|
91
|
-
member = Gitlab.team_member(project, user.id)
|
92
34
|
|
93
|
-
|
94
|
-
end
|
95
|
-
rescue Gitlab::Error::NotFound
|
96
|
-
abort_not_permitted
|
97
|
-
end
|
98
|
-
|
99
|
-
def abort_not_permitted
|
100
|
-
abort "You must have at least Maintainer access to the project to use this feature."
|
101
|
-
end
|
102
|
-
|
103
|
-
def configure_gitlab_client
|
104
|
-
handle_gitlab_client_exceptions do
|
105
|
-
Gitlab.configure do |config|
|
106
|
-
config.endpoint = Runtime::Env.gitlab_api_base
|
107
|
-
config.private_token = token
|
108
|
-
end
|
35
|
+
test_results.write(path)
|
109
36
|
end
|
110
37
|
end
|
111
38
|
|
@@ -115,6 +42,7 @@ module Gitlab
|
|
115
42
|
puts "Reporting test: #{test.file} | #{test.name}"
|
116
43
|
|
117
44
|
issue = find_issue(test)
|
45
|
+
|
118
46
|
if issue
|
119
47
|
puts "Found existing issue: #{issue.web_url}"
|
120
48
|
else
|
@@ -122,42 +50,38 @@ module Gitlab
|
|
122
50
|
puts "Created new issue: #{issue.web_url}"
|
123
51
|
end
|
124
52
|
|
53
|
+
test.testcase ||= issue.web_url
|
54
|
+
|
125
55
|
update_labels(issue, test)
|
126
56
|
note_status(issue, test)
|
127
57
|
|
128
58
|
puts "Issue updated"
|
129
59
|
end
|
130
60
|
|
131
|
-
def create_issue(test)
|
132
|
-
puts "Creating issue..."
|
133
|
-
|
134
|
-
handle_gitlab_client_exceptions do
|
135
|
-
Gitlab.create_issue(
|
136
|
-
project,
|
137
|
-
title_from_test(test),
|
138
|
-
{ description: "### Full description\n\n#{search_safe(test.name)}\n\n### File path\n\n#{test.file}", labels: 'status::automated' }
|
139
|
-
)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# rubocop:disable Metrics/AbcSize
|
144
61
|
def find_issue(test)
|
145
|
-
|
146
|
-
|
62
|
+
title = title_from_test(test)
|
63
|
+
issues =
|
64
|
+
gitlab.find_issues(
|
65
|
+
iid: iid_from_testcase_url(test.testcase),
|
66
|
+
options: { search: search_term(test) }) do |issue|
|
67
|
+
issue.state == 'opened' && issue.title.strip == title
|
68
|
+
end
|
147
69
|
|
148
|
-
|
149
|
-
.auto_paginate
|
150
|
-
.select { |issue| issue.state == 'opened' && issue.title.strip == title_from_test(test) }
|
70
|
+
warn(%(Too many issues found with the file path "#{test.file}" and name "#{test.name}")) if issues.many?
|
151
71
|
|
152
|
-
|
72
|
+
issues.first
|
73
|
+
end
|
153
74
|
|
154
|
-
|
155
|
-
|
75
|
+
def create_issue(test)
|
76
|
+
gitlab.create_issue(
|
77
|
+
title: title_from_test(test),
|
78
|
+
description: "### Full description\n\n#{search_safe(test.name)}\n\n### File path\n\n#{test.file}",
|
79
|
+
labels: 'status::automated'
|
80
|
+
)
|
156
81
|
end
|
157
|
-
# rubocop:enable Metrics/AbcSize
|
158
82
|
|
159
|
-
def
|
160
|
-
url.split('/').last.to_i
|
83
|
+
def iid_from_testcase_url(url)
|
84
|
+
url && url.split('/').last.to_i
|
161
85
|
end
|
162
86
|
|
163
87
|
def search_term(test)
|
@@ -185,7 +109,7 @@ module Gitlab
|
|
185
109
|
|
186
110
|
note = note_content(test)
|
187
111
|
|
188
|
-
handle_gitlab_client_exceptions do
|
112
|
+
gitlab.handle_gitlab_client_exceptions do
|
189
113
|
Gitlab.issue_discussions(project, issue.iid, order_by: 'created_at', sort: 'asc').each do |discussion|
|
190
114
|
return add_note_to_discussion(issue.iid, discussion.id) if new_note_matches_discussion?(note, discussion)
|
191
115
|
end
|
@@ -241,12 +165,11 @@ module Gitlab
|
|
241
165
|
end
|
242
166
|
|
243
167
|
def add_note_to_discussion(issue_iid, discussion_id)
|
244
|
-
handle_gitlab_client_exceptions do
|
168
|
+
gitlab.handle_gitlab_client_exceptions do
|
245
169
|
Gitlab.add_note_to_issue_discussion_as_thread(project, issue_iid, discussion_id, body: failure_summary)
|
246
170
|
end
|
247
171
|
end
|
248
172
|
|
249
|
-
# rubocop:disable Metrics/AbcSize
|
250
173
|
def update_labels(issue, test)
|
251
174
|
labels = issue.labels
|
252
175
|
labels.delete_if { |label| label.start_with?("#{pipeline}::") }
|
@@ -254,11 +177,8 @@ module Gitlab
|
|
254
177
|
labels << "Enterprise Edition" if ee_test?(test)
|
255
178
|
quarantine_job? ? labels << "quarantine" : labels.delete("quarantine")
|
256
179
|
|
257
|
-
|
258
|
-
Gitlab.edit_issue(project, issue.iid, labels: labels)
|
259
|
-
end
|
180
|
+
gitlab.edit_issue(iid: issue.iid, options: { labels: labels })
|
260
181
|
end
|
261
|
-
# rubocop:enable Metrics/AbcSize
|
262
182
|
|
263
183
|
def ee_test?(test)
|
264
184
|
test.file =~ %r{features/ee/(api|browser_ui)}
|
@@ -279,46 +199,6 @@ module Gitlab
|
|
279
199
|
|
280
200
|
Runtime::Env.pipeline_from_project_name
|
281
201
|
end
|
282
|
-
|
283
|
-
def handle_gitlab_client_exceptions
|
284
|
-
yield
|
285
|
-
rescue Gitlab::Error::NotFound
|
286
|
-
# This error could be raised in assert_user_permission!
|
287
|
-
# If so, we want it to terminate at that point
|
288
|
-
raise
|
289
|
-
rescue SystemCallError, OpenSSL::SSL::SSLError, Net::OpenTimeout, Net::ReadTimeout, Gitlab::Error::InternalServerError, Gitlab::Error::Parsing => e
|
290
|
-
@retry_backoff += RETRY_BACK_OFF_DELAY
|
291
|
-
|
292
|
-
raise if @retry_backoff > RETRY_BACK_OFF_DELAY * MAX_RETRY_ATTEMPTS
|
293
|
-
|
294
|
-
warn_exception(e)
|
295
|
-
warn("Sleeping for #{@retry_backoff} seconds before retrying...")
|
296
|
-
sleep @retry_backoff
|
297
|
-
|
298
|
-
retry
|
299
|
-
rescue StandardError => e
|
300
|
-
pipeline = QA::Runtime::Env.pipeline_from_project_name
|
301
|
-
channel = pipeline == "canary" ? "qa-production" : "qa-#{pipeline}"
|
302
|
-
error_msg = warn_exception(e)
|
303
|
-
slack_options = {
|
304
|
-
channel: channel,
|
305
|
-
icon_emoji: ':ci_failing:',
|
306
|
-
message: <<~MSG
|
307
|
-
An unexpected error occurred while reporting test results in issues.
|
308
|
-
The error occurred in job: #{QA::Runtime::Env.ci_job_url}
|
309
|
-
`#{error_msg}`
|
310
|
-
MSG
|
311
|
-
}
|
312
|
-
puts "Posting Slack message to channel: #{channel}"
|
313
|
-
|
314
|
-
Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
|
315
|
-
end
|
316
|
-
|
317
|
-
def warn_exception(error)
|
318
|
-
error_msg = "#{error.class.name} #{error.message}"
|
319
|
-
warn(error_msg)
|
320
|
-
error_msg
|
321
|
-
end
|
322
202
|
end
|
323
203
|
end
|
324
204
|
end
|
@@ -4,60 +4,114 @@ module Gitlab
|
|
4
4
|
module QA
|
5
5
|
module Report
|
6
6
|
class TestResult
|
7
|
-
|
8
|
-
|
9
|
-
def self.from_json(test)
|
10
|
-
new.tap do |test_result|
|
11
|
-
test_result.name = test['full_description']
|
12
|
-
test_result.file = test['file_path']
|
13
|
-
test_result.skipped = test['status'] == 'pending'
|
14
|
-
test_result.failures = failures_from_json_exceptions(test)
|
15
|
-
test_result.testcase = test['testcase']
|
16
|
-
end
|
7
|
+
def self.from_json(report)
|
8
|
+
JsonTestResult.new(report)
|
17
9
|
end
|
18
10
|
|
19
|
-
def self.from_junit(
|
20
|
-
new
|
21
|
-
test_result.name = test['name']
|
22
|
-
test_result.file = test['file']
|
23
|
-
test_result.skipped = test.search('skipped').any?
|
24
|
-
test_result.failures = failures_from_junit_exceptions(test)
|
25
|
-
end
|
11
|
+
def self.from_junit(report)
|
12
|
+
JUnitTestResult.new(report)
|
26
13
|
end
|
27
14
|
|
28
|
-
|
29
|
-
return [] unless test.key?('exceptions')
|
15
|
+
attr_accessor :report, :failures
|
30
16
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
def initialize(report)
|
18
|
+
self.report = report
|
19
|
+
self.failures = failures_from_exceptions
|
20
|
+
end
|
35
21
|
|
36
|
-
|
37
|
-
|
38
|
-
'stacktrace' => "#{exception['message_lines'].join("\n")}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
|
39
|
-
}
|
40
|
-
end
|
22
|
+
def name
|
23
|
+
raise NotImplementedError
|
41
24
|
end
|
42
|
-
private_class_method :failures_from_json_exceptions
|
43
25
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
26
|
+
def file
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def skipped
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def failures_from_exceptions
|
37
|
+
raise NotImplementedError
|
38
|
+
end
|
39
|
+
|
40
|
+
class JsonTestResult < TestResult
|
41
|
+
def name
|
42
|
+
report['full_description']
|
43
|
+
end
|
44
|
+
|
45
|
+
def file
|
46
|
+
report['file_path']
|
47
|
+
end
|
48
|
+
|
49
|
+
def skipped
|
50
|
+
report['status'] == 'pending'
|
51
|
+
end
|
52
|
+
|
53
|
+
def testcase
|
54
|
+
report['testcase']
|
55
|
+
end
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
57
|
+
def testcase=(new_testcase)
|
58
|
+
report['testcase'] = new_testcase
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
# rubocop:disable Metrics/AbcSize
|
64
|
+
def failures_from_exceptions
|
65
|
+
return [] unless report.key?('exceptions')
|
66
|
+
|
67
|
+
report['exceptions'].map do |exception|
|
68
|
+
spec_file_first_index = exception['backtrace'].rindex do |line|
|
69
|
+
line.include?(File.basename(report['file_path']))
|
70
|
+
end
|
71
|
+
|
72
|
+
{
|
73
|
+
'message' => "#{exception['class']}: #{exception['message']}",
|
74
|
+
'stacktrace' => "#{exception['message_lines'].join("\n")}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
|
75
|
+
}
|
52
76
|
end
|
77
|
+
end
|
78
|
+
# rubocop:enable Metrics/AbcSize
|
79
|
+
end
|
80
|
+
|
81
|
+
class JUnitTestResult < TestResult
|
82
|
+
def name
|
83
|
+
report['name']
|
84
|
+
end
|
53
85
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
86
|
+
def file
|
87
|
+
report['file']
|
88
|
+
end
|
89
|
+
|
90
|
+
def skipped
|
91
|
+
report.search('skipped').any?
|
92
|
+
end
|
93
|
+
|
94
|
+
attr_accessor :testcase # Ignore it for now
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def failures_from_exceptions
|
99
|
+
failures = report.search('failure')
|
100
|
+
return [] if failures.empty?
|
101
|
+
|
102
|
+
failures.map do |exception|
|
103
|
+
trace = exception.content.split("\n").map(&:strip)
|
104
|
+
spec_file_first_index = trace.rindex do |line|
|
105
|
+
line.include?(File.basename(report['file']))
|
106
|
+
end
|
107
|
+
|
108
|
+
{
|
109
|
+
'message' => "#{exception['type']}: #{exception['message']}",
|
110
|
+
'stacktrace' => trace.slice(0..spec_file_first_index).join("\n")
|
111
|
+
}
|
112
|
+
end
|
58
113
|
end
|
59
114
|
end
|
60
|
-
private_class_method :failures_from_junit_exceptions
|
61
115
|
end
|
62
116
|
end
|
63
117
|
end
|
data/lib/gitlab/qa/reporter.rb
CHANGED
@@ -60,34 +60,19 @@ module Gitlab
|
|
60
60
|
end
|
61
61
|
|
62
62
|
if args.any?
|
63
|
-
if report_options
|
64
|
-
report_options.delete(:prepare_stage_reports)
|
63
|
+
if report_options.delete(:prepare_stage_reports)
|
65
64
|
Gitlab::QA::Report::PrepareStageReports.new(**report_options).invoke!
|
66
65
|
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
if report_options[:report_in_issues]
|
71
|
-
report_options.delete(:report_in_issues)
|
66
|
+
elsif report_options.delete(:report_in_issues)
|
72
67
|
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
73
68
|
Gitlab::QA::Report::ResultsInIssues.new(**report_options).invoke!
|
74
69
|
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
if slack_options[:post_to_slack]
|
79
|
-
slack_options.delete(:post_to_slack)
|
70
|
+
elsif slack_options.delete(:post_to_slack)
|
80
71
|
Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
|
81
72
|
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
if report_options[:update_screenshot_path]
|
86
|
-
report_options.delete(:update_screenshot_path)
|
87
|
-
|
73
|
+
elsif report_options.delete(:update_screenshot_path)
|
88
74
|
Gitlab::QA::Report::UpdateScreenshotPath.new(**report_options).invoke!
|
89
75
|
|
90
|
-
exit
|
91
76
|
end
|
92
77
|
else
|
93
78
|
puts options
|
@@ -62,6 +62,8 @@ module Gitlab
|
|
62
62
|
'KNAPSACK_TEST_FILE_PATTERN' => :knapsack_test_file_pattern,
|
63
63
|
'KNAPSACK_TEST_DIR' => :knapsack_test_dir,
|
64
64
|
'CI' => :ci,
|
65
|
+
'CI_JOB_ID' => :ci_job_id,
|
66
|
+
'CI_JOB_URL' => :ci_job_url,
|
65
67
|
'CI_RUNNER_ID' => :ci_runner_id,
|
66
68
|
'CI_SERVER_HOST' => :ci_server_host,
|
67
69
|
'CI_SERVER_PERSONAL_ACCESS_TOKEN' => :ci_server_personal_access_token,
|
@@ -81,11 +83,16 @@ module Gitlab
|
|
81
83
|
'JIRA_HOSTNAME' => :jira_hostname,
|
82
84
|
'JIRA_ADMIN_USERNAME' => :jira_admin_username,
|
83
85
|
'JIRA_ADMIN_PASSWORD' => :jira_admin_password,
|
84
|
-
'CACHE_NAMESPACE_NAME' => :cache_namespace_name
|
86
|
+
'CACHE_NAMESPACE_NAME' => :cache_namespace_name,
|
87
|
+
'DEPLOY_VERSION' => :deploy_version
|
85
88
|
}.freeze
|
86
89
|
|
87
|
-
ENV_VARIABLES.
|
88
|
-
|
90
|
+
ENV_VARIABLES.each do |env_name, method_name|
|
91
|
+
attr_writer(method_name)
|
92
|
+
|
93
|
+
define_method(method_name) do
|
94
|
+
ENV[env_name] || instance_variable_get("@#{method_name}")
|
95
|
+
end
|
89
96
|
end
|
90
97
|
|
91
98
|
def gitlab_username
|
@@ -112,10 +119,6 @@ module Gitlab
|
|
112
119
|
ENV['CI_JOB_TOKEN']
|
113
120
|
end
|
114
121
|
|
115
|
-
def ci_job_url
|
116
|
-
ENV['CI_JOB_URL']
|
117
|
-
end
|
118
|
-
|
119
122
|
def ci_pipeline_source
|
120
123
|
ENV['CI_PIPELINE_SOURCE']
|
121
124
|
end
|
@@ -124,30 +127,14 @@ module Gitlab
|
|
124
127
|
ENV['CI_PROJECT_NAME']
|
125
128
|
end
|
126
129
|
|
127
|
-
def ci_slack_webhook_url
|
128
|
-
ENV['CI_SLACK_WEBHOOK_URL']
|
129
|
-
end
|
130
|
-
|
131
130
|
def pipeline_from_project_name
|
132
131
|
ci_project_name.to_s.start_with?('gitlab-qa') ? 'master' : ci_project_name
|
133
132
|
end
|
134
133
|
|
135
|
-
def slack_qa_channel
|
136
|
-
ENV['SLACK_QA_CHANNEL']
|
137
|
-
end
|
138
|
-
|
139
|
-
def slack_icon_emoji
|
140
|
-
ENV['SLACK_ICON_EMOJI']
|
141
|
-
end
|
142
|
-
|
143
134
|
def run_id
|
144
135
|
@run_id ||= "gitlab-qa-run-#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}-#{SecureRandom.hex(4)}"
|
145
136
|
end
|
146
137
|
|
147
|
-
def qa_access_token
|
148
|
-
ENV['GITLAB_QA_ACCESS_TOKEN']
|
149
|
-
end
|
150
|
-
|
151
138
|
def dev_access_token_variable
|
152
139
|
env_value_if_defined('GITLAB_QA_DEV_ACCESS_TOKEN')
|
153
140
|
end
|
@@ -227,10 +214,6 @@ module Gitlab
|
|
227
214
|
enabled?(ENV['QA_SKIP_PULL'], default: false)
|
228
215
|
end
|
229
216
|
|
230
|
-
def gitlab_qa_formless_login_token
|
231
|
-
env_value_if_defined('GITLAB_QA_FORMLESS_LOGIN_TOKEN')
|
232
|
-
end
|
233
|
-
|
234
217
|
private
|
235
218
|
|
236
219
|
def enabled?(value, default: true)
|
@@ -15,6 +15,8 @@ module Gitlab
|
|
15
15
|
@database = 'postgres'
|
16
16
|
@spec_suite = 'Test::Instance::All'
|
17
17
|
@network = 'test'
|
18
|
+
@env = {}
|
19
|
+
@tag = 'gitaly_cluster'
|
18
20
|
end
|
19
21
|
|
20
22
|
# rubocop:disable Metrics/AbcSize
|
@@ -51,14 +53,17 @@ module Gitlab
|
|
51
53
|
gitlab.instance do
|
52
54
|
puts "Running Gitaly Cluster specs!"
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
if @tag
|
57
|
+
rspec_args << "--" unless rspec_args.include?('--')
|
58
|
+
rspec_args << "--tag" << @tag
|
59
|
+
end
|
56
60
|
|
57
61
|
Component::Specs.perform do |specs|
|
58
62
|
specs.suite = spec_suite
|
59
63
|
specs.release = gitlab.release
|
60
64
|
specs.network = gitlab.network
|
61
65
|
specs.args = [gitlab.address, *rspec_args]
|
66
|
+
specs.env = @env
|
62
67
|
end
|
63
68
|
end
|
64
69
|
end
|
@@ -3,105 +3,62 @@ module Gitlab
|
|
3
3
|
module Scenario
|
4
4
|
module Test
|
5
5
|
module Integration
|
6
|
-
class Praefect <
|
7
|
-
|
8
|
-
def perform(release, *rspec_args)
|
9
|
-
Docker::Volumes.new.with_temporary_volumes do |volumes|
|
10
|
-
# Create the Praefect database before enabling Praefect
|
11
|
-
Component::Gitlab.perform do |gitlab|
|
12
|
-
gitlab.release = QA::Release.new(release)
|
13
|
-
gitlab.name = 'gitlab'
|
14
|
-
gitlab.network = 'test'
|
15
|
-
gitlab.volumes = volumes
|
16
|
-
gitlab.exec_commands = [
|
17
|
-
'gitlab-psql -d template1 -c "CREATE DATABASE praefect_production OWNER gitlab"',
|
18
|
-
'mkdir -p /var/opt/gitlab/git-data/repositories/praefect',
|
19
|
-
'chown -R git:root /var/opt/gitlab/git-data/repositories'
|
20
|
-
]
|
6
|
+
class Praefect < GitalyCluster
|
7
|
+
attr_reader :gitlab_name, :spec_suite
|
21
8
|
|
22
|
-
|
23
|
-
|
24
|
-
start
|
25
|
-
reconfigure
|
26
|
-
process_exec_commands
|
27
|
-
wait
|
28
|
-
teardown!
|
29
|
-
end
|
30
|
-
end
|
9
|
+
def initialize
|
10
|
+
super
|
31
11
|
|
32
|
-
|
33
|
-
|
34
|
-
gitlab.release = QA::Release.new(release)
|
35
|
-
gitlab.name = 'gitlab'
|
36
|
-
gitlab.network = 'test'
|
37
|
-
gitlab.volumes = volumes
|
38
|
-
gitlab.omnibus_config = omnibus_config_with_praefect
|
39
|
-
|
40
|
-
gitlab.act do
|
41
|
-
prepare_gitlab_omnibus_config
|
42
|
-
start
|
43
|
-
reconfigure
|
44
|
-
wait
|
45
|
-
|
46
|
-
puts "Running Praefect specs!"
|
47
|
-
|
48
|
-
Component::Specs.perform do |specs|
|
49
|
-
specs.suite = 'Test::Instance::All'
|
50
|
-
specs.release = gitlab.release
|
51
|
-
specs.network = gitlab.network
|
52
|
-
specs.args = [gitlab.address, *rspec_args]
|
53
|
-
specs.env = { QA_PRAEFECT_REPOSITORY_STORAGE: 'default' }
|
54
|
-
end
|
55
|
-
|
56
|
-
teardown
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
12
|
+
@tag = nil
|
13
|
+
@env = { QA_PRAEFECT_REPOSITORY_STORAGE: 'default' }
|
60
14
|
end
|
61
|
-
# rubocop:enable Metrics/AbcSize
|
62
|
-
|
63
|
-
private
|
64
15
|
|
65
|
-
def
|
16
|
+
def gitlab_omnibus_configuration
|
66
17
|
<<~OMNIBUS
|
67
|
-
|
18
|
+
external_url 'http://#{@gitlab_name}.#{@network}';
|
19
|
+
|
20
|
+
git_data_dirs({
|
21
|
+
'default' => {
|
22
|
+
'gitaly_address' => 'tcp://#{@praefect_node_name}.#{@network}:2305',
|
23
|
+
'gitaly_token' => 'PRAEFECT_EXTERNAL_TOKEN'
|
24
|
+
},
|
25
|
+
'gitaly' => {
|
26
|
+
'gitaly_address' => 'tcp://#{@gitlab_name}.#{@network}:8075',
|
27
|
+
'path' => '/var/opt/gitlab/git-data'
|
28
|
+
}
|
29
|
+
});
|
68
30
|
gitaly['listen_addr'] = '0.0.0.0:8075';
|
69
31
|
gitaly['auth_token'] = 'secret-token';
|
70
32
|
gitaly['storage'] = [
|
71
|
-
{
|
72
|
-
'name' => 'praefect-gitaly-0',
|
73
|
-
'path' => '/var/opt/gitlab/git-data/repositories/praefect'
|
74
|
-
},
|
75
33
|
{
|
76
34
|
'name' => 'gitaly',
|
77
|
-
'path' => '/var/opt/gitlab/git-data/repositories
|
35
|
+
'path' => '/var/opt/gitlab/git-data/repositories'
|
78
36
|
}
|
79
37
|
];
|
80
|
-
praefect['enable'] = true;
|
81
|
-
praefect['listen_addr'] = '0.0.0.0:2305';
|
82
|
-
praefect['auth_token'] = 'secret-token';
|
83
|
-
praefect['virtual_storages'] = {
|
84
|
-
'default' => {
|
85
|
-
'praefect-gitaly-0' => {
|
86
|
-
'address' => 'tcp://localhost:8075',
|
87
|
-
'token' => 'secret-token',
|
88
|
-
'primary' => true
|
89
|
-
}
|
90
|
-
}
|
91
|
-
};
|
92
|
-
praefect['database_host'] = '/var/opt/gitlab/postgresql';
|
93
|
-
praefect['database_user'] = 'gitlab';
|
94
|
-
praefect['database_dbname'] = 'praefect_production';
|
95
|
-
praefect['postgres_queue_enabled'] = true;
|
96
38
|
gitlab_rails['gitaly_token'] = 'secret-token';
|
97
|
-
|
98
|
-
|
99
|
-
|
39
|
+
gitlab_shell['secret_token'] = 'GITLAB_SHELL_SECRET_TOKEN';
|
40
|
+
prometheus['scrape_configs'] = [
|
41
|
+
{
|
42
|
+
'job_name' => 'praefect',
|
43
|
+
'static_configs' => [
|
44
|
+
'targets' => [
|
45
|
+
'#{@praefect_node_name}.#{@network}:9652'
|
46
|
+
]
|
47
|
+
]
|
100
48
|
},
|
101
|
-
|
102
|
-
'
|
49
|
+
{
|
50
|
+
'job_name' => 'praefect-gitaly',
|
51
|
+
'static_configs' => [
|
52
|
+
'targets' => [
|
53
|
+
'#{@primary_node_name}.#{@network}:9236',
|
54
|
+
'#{@secondary_node_name}.#{@network}:9236',
|
55
|
+
'#{@tertiary_node_name}.#{@network}:9236'
|
56
|
+
]
|
57
|
+
]
|
103
58
|
}
|
104
|
-
|
59
|
+
];
|
60
|
+
grafana['disable_login_form'] = false;
|
61
|
+
grafana['admin_password'] = 'GRAFANA_ADMIN_PASSWORD';
|
105
62
|
OMNIBUS
|
106
63
|
end
|
107
64
|
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: 6.
|
4
|
+
version: 6.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grzegorz Bizon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: climate_control
|
@@ -257,9 +257,12 @@ files:
|
|
257
257
|
- lib/gitlab/qa/docker/shellout.rb
|
258
258
|
- lib/gitlab/qa/docker/volumes.rb
|
259
259
|
- lib/gitlab/qa/release.rb
|
260
|
+
- lib/gitlab/qa/report/base_test_results.rb
|
261
|
+
- lib/gitlab/qa/report/gitlab_issue_client.rb
|
260
262
|
- lib/gitlab/qa/report/json_test_results.rb
|
261
263
|
- lib/gitlab/qa/report/junit_test_results.rb
|
262
264
|
- lib/gitlab/qa/report/prepare_stage_reports.rb
|
265
|
+
- lib/gitlab/qa/report/report_as_issue.rb
|
263
266
|
- lib/gitlab/qa/report/results_in_issues.rb
|
264
267
|
- lib/gitlab/qa/report/summary_table.rb
|
265
268
|
- lib/gitlab/qa/report/test_result.rb
|