gitlab-qa 6.3.0 → 6.7.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 +39 -1
- data/.gitlab/merge_request_templates/Release.md +1 -1
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +98 -0
- data/docs/what_tests_can_be_run.md +17 -0
- data/gitlab-qa.gemspec +3 -3
- data/lib/gitlab/qa.rb +2 -0
- data/lib/gitlab/qa/component/base.rb +1 -1
- data/lib/gitlab/qa/component/gitlab.rb +2 -2
- data/lib/gitlab/qa/component/postgresql.rb +2 -1
- data/lib/gitlab/qa/docker/shellout.rb +1 -1
- data/lib/gitlab/qa/report/base_test_results.rb +36 -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/results_in_issues.rb +9 -5
- data/lib/gitlab/qa/report/test_result.rb +95 -41
- data/lib/gitlab/qa/runtime/env.rb +8 -26
- data/lib/gitlab/qa/scenario/test/integration/actioncable.rb +36 -0
- 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 +15 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1615e54144d0b669245a15b6a5874efc1d00157fe859dbc6ff2e723380e9da10
|
|
4
|
+
data.tar.gz: f3ccd0528987c838c793d1bbc2f742833584756bf7a87c58c29b60fa2f7b6ac3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 47fce0af7a769ccb9dca14c87f3d1f169495324f753f3db60bb8aa10fc6e05a4612f0bc1704e884dca3d7349bd6d0972d5ca77421bba71f60fd03258e24bc52b
|
|
7
|
+
data.tar.gz: f1d65176693a0091989392eec19425a34d2cbc1ee92cb428178ee22ca438b19e7246fd1306bfdaaa73f5d531a6c01ad5a6b2ee1324ca72ef0ba9b255ae4782f3
|
data/.gitlab-ci.yml
CHANGED
|
@@ -5,7 +5,7 @@ stages:
|
|
|
5
5
|
- notify
|
|
6
6
|
|
|
7
7
|
default:
|
|
8
|
-
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-ruby-2.
|
|
8
|
+
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-ruby-2.7
|
|
9
9
|
tags:
|
|
10
10
|
- gitlab-org
|
|
11
11
|
cache:
|
|
@@ -729,6 +729,44 @@ ee:packages-quarantine:
|
|
|
729
729
|
variables:
|
|
730
730
|
QA_SCENARIO: "Test::Integration::Packages"
|
|
731
731
|
|
|
732
|
+
ce:actioncable:
|
|
733
|
+
extends:
|
|
734
|
+
- .test
|
|
735
|
+
- .high-capacity
|
|
736
|
+
- .ce-qa
|
|
737
|
+
- .rspec-report-opts
|
|
738
|
+
variables:
|
|
739
|
+
QA_SCENARIO: "Test::Integration::Actioncable"
|
|
740
|
+
|
|
741
|
+
ce:actioncable-quarantine:
|
|
742
|
+
extends:
|
|
743
|
+
- .test
|
|
744
|
+
- .high-capacity
|
|
745
|
+
- .ce-qa
|
|
746
|
+
- .quarantine
|
|
747
|
+
- .rspec-report-opts
|
|
748
|
+
variables:
|
|
749
|
+
QA_SCENARIO: "Test::Integration::Actioncable"
|
|
750
|
+
|
|
751
|
+
ee:actioncable:
|
|
752
|
+
extends:
|
|
753
|
+
- .test
|
|
754
|
+
- .high-capacity
|
|
755
|
+
- .ee-qa
|
|
756
|
+
- .rspec-report-opts
|
|
757
|
+
variables:
|
|
758
|
+
QA_SCENARIO: "Test::Integration::Actioncable"
|
|
759
|
+
|
|
760
|
+
ee:actioncable-quarantine:
|
|
761
|
+
extends:
|
|
762
|
+
- .test
|
|
763
|
+
- .high-capacity
|
|
764
|
+
- .ee-qa
|
|
765
|
+
- .quarantine
|
|
766
|
+
- .rspec-report-opts
|
|
767
|
+
variables:
|
|
768
|
+
QA_SCENARIO: "Test::Integration::Actioncable"
|
|
769
|
+
|
|
732
770
|
ee:elasticsearch:
|
|
733
771
|
extends:
|
|
734
772
|
- .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"
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config`
|
|
3
|
+
# on 2020-10-31 07:26:03 -0700 using RuboCop version 0.82.0.
|
|
4
|
+
# The point is for the user to remove these configuration records
|
|
5
|
+
# one by one as the offenses are removed from the code base.
|
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
|
8
|
+
|
|
9
|
+
# Offense count: 51
|
|
10
|
+
# Cop supports --auto-correct.
|
|
11
|
+
# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
|
12
|
+
# URISchemes: http, https
|
|
13
|
+
Layout/LineLength:
|
|
14
|
+
Max: 210
|
|
15
|
+
|
|
16
|
+
# Offense count: 2
|
|
17
|
+
# Cop supports --auto-correct.
|
|
18
|
+
Lint/RedundantCopDisableDirective:
|
|
19
|
+
Exclude:
|
|
20
|
+
- 'lib/gitlab/qa/component/staging.rb'
|
|
21
|
+
- 'lib/gitlab/qa/runtime/scenario.rb'
|
|
22
|
+
|
|
23
|
+
# Offense count: 1
|
|
24
|
+
# Cop supports --auto-correct.
|
|
25
|
+
# Configuration parameters: PreferredName.
|
|
26
|
+
Naming/RescuedExceptionsVariableName:
|
|
27
|
+
Exclude:
|
|
28
|
+
- 'lib/gitlab/qa/component/staging.rb'
|
|
29
|
+
|
|
30
|
+
# Offense count: 1
|
|
31
|
+
# Cop supports --auto-correct.
|
|
32
|
+
Performance/RegexpMatch:
|
|
33
|
+
Exclude:
|
|
34
|
+
- 'lib/gitlab/qa/component/gitlab.rb'
|
|
35
|
+
|
|
36
|
+
# Offense count: 3
|
|
37
|
+
# Cop supports --auto-correct.
|
|
38
|
+
RSpec/EmptyLineAfterLetBlock:
|
|
39
|
+
Exclude:
|
|
40
|
+
- 'spec/gitlab/qa/support/dev_eeqa_image_spec.rb'
|
|
41
|
+
|
|
42
|
+
# Offense count: 4
|
|
43
|
+
# Cop supports --auto-correct.
|
|
44
|
+
# Configuration parameters: CustomTransform, IgnoredWords.
|
|
45
|
+
RSpec/ExampleWording:
|
|
46
|
+
Exclude:
|
|
47
|
+
- 'spec/gitlab/qa/component/gitlab_spec.rb'
|
|
48
|
+
|
|
49
|
+
# Offense count: 2
|
|
50
|
+
RSpec/LeakyConstantDeclaration:
|
|
51
|
+
Exclude:
|
|
52
|
+
- 'spec/gitlab/qa/scenario/test/instance/deployment_base_spec.rb'
|
|
53
|
+
|
|
54
|
+
# Offense count: 93
|
|
55
|
+
# Cop supports --auto-correct.
|
|
56
|
+
# Configuration parameters: EnforcedStyle.
|
|
57
|
+
# SupportedStyles: always, always_true, never
|
|
58
|
+
Style/FrozenStringLiteralComment:
|
|
59
|
+
Enabled: false
|
|
60
|
+
|
|
61
|
+
# Offense count: 1
|
|
62
|
+
# Cop supports --auto-correct.
|
|
63
|
+
Style/HashTransformKeys:
|
|
64
|
+
Exclude:
|
|
65
|
+
- 'lib/gitlab/qa/docker/volumes.rb'
|
|
66
|
+
|
|
67
|
+
# Offense count: 6
|
|
68
|
+
# Cop supports --auto-correct.
|
|
69
|
+
Style/IfUnlessModifier:
|
|
70
|
+
Exclude:
|
|
71
|
+
- 'lib/gitlab/qa/component/gitlab.rb'
|
|
72
|
+
- 'lib/gitlab/qa/release.rb'
|
|
73
|
+
- 'lib/gitlab/qa/runtime/env.rb'
|
|
74
|
+
- 'lib/gitlab/qa/runtime/scenario.rb'
|
|
75
|
+
- 'lib/gitlab/qa/scenario/test/omnibus/upgrade.rb'
|
|
76
|
+
- 'lib/gitlab/qa/support/http_request.rb'
|
|
77
|
+
|
|
78
|
+
# Offense count: 1
|
|
79
|
+
Style/MethodMissingSuper:
|
|
80
|
+
Exclude:
|
|
81
|
+
- 'lib/gitlab/qa/runtime/scenario.rb'
|
|
82
|
+
|
|
83
|
+
# Offense count: 1
|
|
84
|
+
Style/MissingRespondToMissing:
|
|
85
|
+
Exclude:
|
|
86
|
+
- 'lib/gitlab/qa/runtime/scenario.rb'
|
|
87
|
+
|
|
88
|
+
# Offense count: 5
|
|
89
|
+
# Cop supports --auto-correct.
|
|
90
|
+
# Configuration parameters: EnforcedStyle.
|
|
91
|
+
# SupportedStyles: literals, strict
|
|
92
|
+
Style/MutableConstant:
|
|
93
|
+
Exclude:
|
|
94
|
+
- 'db/migrate/**/*'
|
|
95
|
+
- 'db/post_migrate/**/*'
|
|
96
|
+
- 'db/geo/migrate/**/*'
|
|
97
|
+
- 'lib/gitlab/qa/release.rb'
|
|
98
|
+
- 'lib/gitlab/qa/report/update_screenshot_path.rb'
|
|
@@ -545,6 +545,23 @@ $ export EE_LICENSE=$(cat /path/to/GitLab.gitlab_license)
|
|
|
545
545
|
$ gitlab-qa Test::Integration::Jira EE
|
|
546
546
|
```
|
|
547
547
|
|
|
548
|
+
### `Test::Integration::Actioncable CE|EE|<full image address>`
|
|
549
|
+
|
|
550
|
+
This tests the real-time assignees feature by setting
|
|
551
|
+
`actioncable['enable'] = true` in the Omnibus configuration
|
|
552
|
+
before starting the GitLab container.
|
|
553
|
+
|
|
554
|
+
To run tests against the GitLab container, a GitLab QA (`gitlab/gitlab-qa`)
|
|
555
|
+
container is spun up and tests are run from it by running the
|
|
556
|
+
`Test::Instance::All` scenario with the `--tag actioncable` RSpec parameter,
|
|
557
|
+
which runs only the tests with `:actioncable` metadata.
|
|
558
|
+
|
|
559
|
+
Example:
|
|
560
|
+
|
|
561
|
+
```
|
|
562
|
+
$ gitlab-qa Test::Integration::Actioncable CE
|
|
563
|
+
```
|
|
564
|
+
|
|
548
565
|
### `Test::Instance::Any CE|EE|<full image address>:nightly|latest|any_tag http://your.instance.gitlab`
|
|
549
566
|
|
|
550
567
|
This tests that a live GitLab instance works as expected by running tests
|
data/gitlab-qa.gemspec
CHANGED
|
@@ -20,12 +20,12 @@ 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', '
|
|
23
|
+
spec.add_development_dependency 'gitlab-styles', '~> 4.3.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.
|
|
28
|
-
spec.add_development_dependency 'rubocop-rspec', '1.
|
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.82.0'
|
|
28
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.36'
|
|
29
29
|
spec.add_development_dependency 'webmock', '3.7.0'
|
|
30
30
|
spec.add_runtime_dependency 'activesupport', '~> 6.0.2'
|
|
31
31
|
spec.add_runtime_dependency 'gitlab', '~> 4.11.0'
|
data/lib/gitlab/qa.rb
CHANGED
|
@@ -39,6 +39,7 @@ module Gitlab
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
module Integration
|
|
42
|
+
autoload :Actioncable, 'gitlab/qa/scenario/test/integration/actioncable'
|
|
42
43
|
autoload :Geo, 'gitlab/qa/scenario/test/integration/geo'
|
|
43
44
|
autoload :LDAP, 'gitlab/qa/scenario/test/integration/ldap'
|
|
44
45
|
autoload :LDAPNoTLS, 'gitlab/qa/scenario/test/integration/ldap_no_tls'
|
|
@@ -98,6 +99,7 @@ module Gitlab
|
|
|
98
99
|
|
|
99
100
|
module Report
|
|
100
101
|
autoload :GitlabIssueClient, 'gitlab/qa/report/gitlab_issue_client'
|
|
102
|
+
autoload :BaseTestResults, 'gitlab/qa/report/base_test_results'
|
|
101
103
|
autoload :JsonTestResults, 'gitlab/qa/report/json_test_results'
|
|
102
104
|
autoload :JUnitTestResults, 'gitlab/qa/report/junit_test_results'
|
|
103
105
|
autoload :PrepareStageReports, 'gitlab/qa/report/prepare_stage_reports'
|
|
@@ -61,7 +61,7 @@ module Gitlab
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def prepare_network
|
|
64
|
-
if runner_network && !docker.network_exists?(runner_network)
|
|
64
|
+
if runner_network && !docker.network_exists?(runner_network) # rubocop:disable Style/IfUnlessModifier
|
|
65
65
|
docker.network_create("--driver=bridge --internal #{runner_network}")
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -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
|
|
@@ -27,7 +27,7 @@ module Gitlab
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
if wait.value.exited? && wait.value.exitstatus.nonzero?
|
|
30
|
+
if wait.value.exited? && wait.value.exitstatus.nonzero? # rubocop:disable Style/IfUnlessModifier
|
|
31
31
|
raise StatusError, "Docker command `#{@command.mask_secrets}` failed!"
|
|
32
32
|
end
|
|
33
33
|
end
|
|
@@ -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
|
|
@@ -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
|
|
@@ -15,15 +15,15 @@ module Gitlab
|
|
|
15
15
|
def run!
|
|
16
16
|
puts "Reporting test results in `#{files.join(',')}` as issues in project `#{project}` via the API at `#{Runtime::Env.gitlab_api_base}`."
|
|
17
17
|
|
|
18
|
-
Dir.glob(files).each do |
|
|
19
|
-
puts "Reporting tests in #{
|
|
20
|
-
extension = File.extname(
|
|
18
|
+
Dir.glob(files).each do |path|
|
|
19
|
+
puts "Reporting tests in #{path}"
|
|
20
|
+
extension = File.extname(path)
|
|
21
21
|
|
|
22
22
|
case extension
|
|
23
23
|
when '.json'
|
|
24
|
-
test_results = Report::JsonTestResults.new(
|
|
24
|
+
test_results = Report::JsonTestResults.new(path)
|
|
25
25
|
when '.xml'
|
|
26
|
-
test_results = Report::JUnitTestResults.new(
|
|
26
|
+
test_results = Report::JUnitTestResults.new(path)
|
|
27
27
|
else
|
|
28
28
|
raise "Unknown extension #{extension}"
|
|
29
29
|
end
|
|
@@ -31,6 +31,8 @@ module Gitlab
|
|
|
31
31
|
test_results.each do |test|
|
|
32
32
|
report_test(test)
|
|
33
33
|
end
|
|
34
|
+
|
|
35
|
+
test_results.write(path)
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
@@ -48,6 +50,8 @@ module Gitlab
|
|
|
48
50
|
puts "Created new issue: #{issue.web_url}"
|
|
49
51
|
end
|
|
50
52
|
|
|
53
|
+
test.testcase ||= issue.web_url
|
|
54
|
+
|
|
51
55
|
update_labels(issue, test)
|
|
52
56
|
note_status(issue, test)
|
|
53
57
|
|
|
@@ -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
|
|
@@ -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,
|
|
@@ -85,8 +87,12 @@ module Gitlab
|
|
|
85
87
|
'DEPLOY_VERSION' => :deploy_version
|
|
86
88
|
}.freeze
|
|
87
89
|
|
|
88
|
-
ENV_VARIABLES.
|
|
89
|
-
|
|
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
|
|
90
96
|
end
|
|
91
97
|
|
|
92
98
|
def gitlab_username
|
|
@@ -113,10 +119,6 @@ module Gitlab
|
|
|
113
119
|
ENV['CI_JOB_TOKEN']
|
|
114
120
|
end
|
|
115
121
|
|
|
116
|
-
def ci_job_url
|
|
117
|
-
ENV['CI_JOB_URL']
|
|
118
|
-
end
|
|
119
|
-
|
|
120
122
|
def ci_pipeline_source
|
|
121
123
|
ENV['CI_PIPELINE_SOURCE']
|
|
122
124
|
end
|
|
@@ -125,30 +127,14 @@ module Gitlab
|
|
|
125
127
|
ENV['CI_PROJECT_NAME']
|
|
126
128
|
end
|
|
127
129
|
|
|
128
|
-
def ci_slack_webhook_url
|
|
129
|
-
ENV['CI_SLACK_WEBHOOK_URL']
|
|
130
|
-
end
|
|
131
|
-
|
|
132
130
|
def pipeline_from_project_name
|
|
133
131
|
ci_project_name.to_s.start_with?('gitlab-qa') ? 'master' : ci_project_name
|
|
134
132
|
end
|
|
135
133
|
|
|
136
|
-
def slack_qa_channel
|
|
137
|
-
ENV['SLACK_QA_CHANNEL']
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def slack_icon_emoji
|
|
141
|
-
ENV['SLACK_ICON_EMOJI']
|
|
142
|
-
end
|
|
143
|
-
|
|
144
134
|
def run_id
|
|
145
135
|
@run_id ||= "gitlab-qa-run-#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}-#{SecureRandom.hex(4)}"
|
|
146
136
|
end
|
|
147
137
|
|
|
148
|
-
def qa_access_token
|
|
149
|
-
ENV['GITLAB_QA_ACCESS_TOKEN']
|
|
150
|
-
end
|
|
151
|
-
|
|
152
138
|
def dev_access_token_variable
|
|
153
139
|
env_value_if_defined('GITLAB_QA_DEV_ACCESS_TOKEN')
|
|
154
140
|
end
|
|
@@ -228,10 +214,6 @@ module Gitlab
|
|
|
228
214
|
enabled?(ENV['QA_SKIP_PULL'], default: false)
|
|
229
215
|
end
|
|
230
216
|
|
|
231
|
-
def gitlab_qa_formless_login_token
|
|
232
|
-
env_value_if_defined('GITLAB_QA_FORMLESS_LOGIN_TOKEN')
|
|
233
|
-
end
|
|
234
|
-
|
|
235
217
|
private
|
|
236
218
|
|
|
237
219
|
def enabled?(value, default: true)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Gitlab
|
|
2
|
+
module QA
|
|
3
|
+
module Scenario
|
|
4
|
+
module Test
|
|
5
|
+
module Integration
|
|
6
|
+
class Actioncable < Scenario::Template
|
|
7
|
+
def perform(release, *rspec_args)
|
|
8
|
+
Component::Gitlab.perform do |gitlab|
|
|
9
|
+
gitlab.release = QA::Release.new(release)
|
|
10
|
+
gitlab.name = 'gitlab-actioncable'
|
|
11
|
+
gitlab.network = 'test'
|
|
12
|
+
gitlab.omnibus_config = <<~OMNIBUS
|
|
13
|
+
actioncable['enable'] = true;
|
|
14
|
+
OMNIBUS
|
|
15
|
+
|
|
16
|
+
gitlab.instance do
|
|
17
|
+
puts "Running actioncable specs!"
|
|
18
|
+
|
|
19
|
+
rspec_args << "--" unless rspec_args.include?('--')
|
|
20
|
+
rspec_args << %w[--tag actioncable]
|
|
21
|
+
|
|
22
|
+
Component::Specs.perform do |specs|
|
|
23
|
+
specs.suite = 'Test::Instance::All'
|
|
24
|
+
specs.release = gitlab.release
|
|
25
|
+
specs.network = gitlab.network
|
|
26
|
+
specs.args = [gitlab.address, *rspec_args]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -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.7.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-11-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: climate_control
|
|
@@ -28,16 +28,16 @@ dependencies:
|
|
|
28
28
|
name: gitlab-styles
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 4.3.0
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 4.3.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: pry
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -86,28 +86,28 @@ dependencies:
|
|
|
86
86
|
requirements:
|
|
87
87
|
- - "~>"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.
|
|
89
|
+
version: 0.82.0
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
94
|
- - "~>"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 0.
|
|
96
|
+
version: 0.82.0
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: rubocop-rspec
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
100
100
|
requirements:
|
|
101
|
-
- -
|
|
101
|
+
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: 1.
|
|
103
|
+
version: '1.36'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
|
-
- -
|
|
108
|
+
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: 1.
|
|
110
|
+
version: '1.36'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: webmock
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -207,6 +207,7 @@ files:
|
|
|
207
207
|
- ".gitlab/merge_request_templates/Release.md"
|
|
208
208
|
- ".rspec"
|
|
209
209
|
- ".rubocop.yml"
|
|
210
|
+
- ".rubocop_todo.yml"
|
|
210
211
|
- ".travis.yml"
|
|
211
212
|
- CONTRIBUTING.md
|
|
212
213
|
- Gemfile
|
|
@@ -257,6 +258,7 @@ files:
|
|
|
257
258
|
- lib/gitlab/qa/docker/shellout.rb
|
|
258
259
|
- lib/gitlab/qa/docker/volumes.rb
|
|
259
260
|
- lib/gitlab/qa/release.rb
|
|
261
|
+
- lib/gitlab/qa/report/base_test_results.rb
|
|
260
262
|
- lib/gitlab/qa/report/gitlab_issue_client.rb
|
|
261
263
|
- lib/gitlab/qa/report/json_test_results.rb
|
|
262
264
|
- lib/gitlab/qa/report/junit_test_results.rb
|
|
@@ -287,6 +289,7 @@ files:
|
|
|
287
289
|
- lib/gitlab/qa/scenario/test/instance/smoke.rb
|
|
288
290
|
- lib/gitlab/qa/scenario/test/instance/staging.rb
|
|
289
291
|
- lib/gitlab/qa/scenario/test/instance/staging_geo.rb
|
|
292
|
+
- lib/gitlab/qa/scenario/test/integration/actioncable.rb
|
|
290
293
|
- lib/gitlab/qa/scenario/test/integration/elasticsearch.rb
|
|
291
294
|
- lib/gitlab/qa/scenario/test/integration/geo.rb
|
|
292
295
|
- lib/gitlab/qa/scenario/test/integration/gitaly_cluster.rb
|