gitlab-qa 6.4.0 → 6.8.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 +67 -3
- 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 +4 -0
- data/lib/gitlab/qa/component/base.rb +1 -1
- 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 +6 -3
- data/lib/gitlab/qa/report/generate_test_session.rb +203 -0
- data/lib/gitlab/qa/report/gitlab_issue_client.rb +21 -7
- data/lib/gitlab/qa/report/gitlab_issue_dry_client.rb +28 -0
- data/lib/gitlab/qa/report/json_test_results.rb +2 -2
- data/lib/gitlab/qa/report/junit_test_results.rb +2 -2
- data/lib/gitlab/qa/report/relate_failure_issue.rb +139 -0
- data/lib/gitlab/qa/report/report_as_issue.rb +101 -3
- data/lib/gitlab/qa/report/results_in_issues.rb +16 -84
- data/lib/gitlab/qa/report/test_result.rb +22 -1
- data/lib/gitlab/qa/reporter.rb +30 -2
- data/lib/gitlab/qa/runtime/env.rb +34 -27
- 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/version.rb +1 -1
- metadata +17 -12
@@ -19,6 +19,10 @@ module Gitlab
|
|
19
19
|
self.failures = failures_from_exceptions
|
20
20
|
end
|
21
21
|
|
22
|
+
def stage
|
23
|
+
@stage ||= file[%r{(?:api|browser_ui)/(?:(?:\d+_)?(\w+))}, 1]
|
24
|
+
end
|
25
|
+
|
22
26
|
def name
|
23
27
|
raise NotImplementedError
|
24
28
|
end
|
@@ -46,8 +50,16 @@ module Gitlab
|
|
46
50
|
report['file_path']
|
47
51
|
end
|
48
52
|
|
53
|
+
def status
|
54
|
+
report['status']
|
55
|
+
end
|
56
|
+
|
57
|
+
def ci_job_url
|
58
|
+
report['ci_job_url']
|
59
|
+
end
|
60
|
+
|
49
61
|
def skipped
|
50
|
-
|
62
|
+
status == 'pending'
|
51
63
|
end
|
52
64
|
|
53
65
|
def testcase
|
@@ -58,6 +70,14 @@ module Gitlab
|
|
58
70
|
report['testcase'] = new_testcase
|
59
71
|
end
|
60
72
|
|
73
|
+
def failure_issue
|
74
|
+
report['failure_issue']
|
75
|
+
end
|
76
|
+
|
77
|
+
def failure_issue=(new_failure_issue)
|
78
|
+
report['failure_issue'] = new_failure_issue
|
79
|
+
end
|
80
|
+
|
61
81
|
private
|
62
82
|
|
63
83
|
# rubocop:disable Metrics/AbcSize
|
@@ -71,6 +91,7 @@ module Gitlab
|
|
71
91
|
|
72
92
|
{
|
73
93
|
'message' => "#{exception['class']}: #{exception['message']}",
|
94
|
+
'message_lines' => exception['message_lines'],
|
74
95
|
'stacktrace' => "#{exception['message_lines'].join("\n")}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
|
75
96
|
}
|
76
97
|
end
|
data/lib/gitlab/qa/reporter.rb
CHANGED
@@ -4,6 +4,7 @@ module Gitlab
|
|
4
4
|
module QA
|
5
5
|
class Reporter
|
6
6
|
# rubocop:disable Metrics/AbcSize
|
7
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
7
8
|
def self.invoke(args)
|
8
9
|
report_options = {}
|
9
10
|
slack_options = {}
|
@@ -21,11 +22,25 @@ module Gitlab
|
|
21
22
|
report_options[:input_files] = files if files
|
22
23
|
end
|
23
24
|
|
24
|
-
opts.on('-
|
25
|
+
opts.on('--relate-failure-issue FILES', String, 'Relate test failures to failure issues from RSpec JSON files') do |files|
|
26
|
+
report_options[:relate_failure_issue] = true
|
27
|
+
report_options[:input_files] = files if files
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('--max-diff-ratio DIFF_RATO', Float, 'Max stacktrace diff ratio for QA failure issues detection. Used by with --relate-failure-issue') do |value|
|
31
|
+
report_options[:max_diff_ratio] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-in-issues and --relate-failure-issue') do |value|
|
25
35
|
report_options[:project] = value
|
26
36
|
end
|
27
37
|
|
28
|
-
opts.on('-
|
38
|
+
opts.on('--generate-test-session FILES', String, 'Generate test session report') do |files|
|
39
|
+
report_options[:generate_test_session] = true
|
40
|
+
report_options[:input_files] = files if files
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Required by --report-in-issues and --relate-failure-issue') do |value|
|
29
44
|
report_options[:token] = value
|
30
45
|
end
|
31
46
|
|
@@ -45,6 +60,10 @@ module Gitlab
|
|
45
60
|
report_options[:files] = files
|
46
61
|
end
|
47
62
|
|
63
|
+
opts.on('--dry-run', "Perform a dry-run (don't create or update issues)") do |files|
|
64
|
+
report_options[:dry_run] = true
|
65
|
+
end
|
66
|
+
|
48
67
|
opts.on_tail('-v', '--version', 'Show the version') do
|
49
68
|
require 'gitlab/qa/version'
|
50
69
|
puts "#{$PROGRAM_NAME} : #{VERSION}"
|
@@ -63,10 +82,18 @@ module Gitlab
|
|
63
82
|
if report_options.delete(:prepare_stage_reports)
|
64
83
|
Gitlab::QA::Report::PrepareStageReports.new(**report_options).invoke!
|
65
84
|
|
85
|
+
elsif report_options.delete(:relate_failure_issue)
|
86
|
+
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
87
|
+
Gitlab::QA::Report::RelateFailureIssue.new(**report_options).invoke!
|
88
|
+
|
66
89
|
elsif report_options.delete(:report_in_issues)
|
67
90
|
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
68
91
|
Gitlab::QA::Report::ResultsInIssues.new(**report_options).invoke!
|
69
92
|
|
93
|
+
elsif report_options.delete(:generate_test_session)
|
94
|
+
report_options[:token] = Runtime::TokenFinder.find_token!(report_options[:token])
|
95
|
+
Gitlab::QA::Report::GenerateTestSession.new(**report_options).invoke!
|
96
|
+
|
70
97
|
elsif slack_options.delete(:post_to_slack)
|
71
98
|
Gitlab::QA::Slack::PostToSlack.new(**slack_options).invoke!
|
72
99
|
|
@@ -79,6 +106,7 @@ module Gitlab
|
|
79
106
|
exit 1
|
80
107
|
end
|
81
108
|
end
|
109
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
82
110
|
# rubocop:enable Metrics/AbcSize
|
83
111
|
end
|
84
112
|
end
|
@@ -62,7 +62,7 @@ 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
|
-
'
|
65
|
+
'CI_JOB_URL' => :ci_job_url,
|
66
66
|
'CI_RUNNER_ID' => :ci_runner_id,
|
67
67
|
'CI_SERVER_HOST' => :ci_server_host,
|
68
68
|
'CI_SERVER_PERSONAL_ACCESS_TOKEN' => :ci_server_personal_access_token,
|
@@ -86,8 +86,15 @@ module Gitlab
|
|
86
86
|
'DEPLOY_VERSION' => :deploy_version
|
87
87
|
}.freeze
|
88
88
|
|
89
|
-
ENV_VARIABLES.
|
90
|
-
|
89
|
+
ENV_VARIABLES.each do |env_name, method_name|
|
90
|
+
attr_writer(method_name)
|
91
|
+
|
92
|
+
define_method(method_name) do
|
93
|
+
ENV[env_name] ||
|
94
|
+
if instance_variable_defined?("@#{method_name}")
|
95
|
+
instance_variable_get("@#{method_name}")
|
96
|
+
end
|
97
|
+
end
|
91
98
|
end
|
92
99
|
|
93
100
|
def gitlab_username
|
@@ -114,42 +121,38 @@ module Gitlab
|
|
114
121
|
ENV['CI_JOB_TOKEN']
|
115
122
|
end
|
116
123
|
|
117
|
-
def ci_job_url
|
118
|
-
ENV['CI_JOB_URL']
|
119
|
-
end
|
120
|
-
|
121
124
|
def ci_pipeline_source
|
122
125
|
ENV['CI_PIPELINE_SOURCE']
|
123
126
|
end
|
124
127
|
|
125
|
-
def
|
126
|
-
ENV['
|
128
|
+
def ci_pipeline_url
|
129
|
+
ENV['CI_PIPELINE_URL']
|
127
130
|
end
|
128
131
|
|
129
|
-
def
|
130
|
-
ENV['
|
132
|
+
def ci_pipeline_id
|
133
|
+
ENV['CI_PIPELINE_ID']
|
131
134
|
end
|
132
135
|
|
133
|
-
def
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
|
-
def slack_qa_channel
|
138
|
-
ENV['SLACK_QA_CHANNEL']
|
136
|
+
def ci_project_name
|
137
|
+
ENV['CI_PROJECT_NAME']
|
139
138
|
end
|
140
139
|
|
141
|
-
def
|
142
|
-
|
140
|
+
def pipeline_from_project_name
|
141
|
+
if ci_project_name.to_s.start_with?('gitlab-qa')
|
142
|
+
if ENV['TOP_UPSTREAM_SOURCE_JOB'].to_s.start_with?('https://ops.gitlab.net')
|
143
|
+
'staging-orchestrated'
|
144
|
+
else
|
145
|
+
'master'
|
146
|
+
end
|
147
|
+
else
|
148
|
+
ci_project_name
|
149
|
+
end
|
143
150
|
end
|
144
151
|
|
145
152
|
def run_id
|
146
153
|
@run_id ||= "gitlab-qa-run-#{Time.now.strftime('%Y-%m-%d-%H-%M-%S')}-#{SecureRandom.hex(4)}"
|
147
154
|
end
|
148
155
|
|
149
|
-
def qa_access_token
|
150
|
-
ENV['GITLAB_QA_ACCESS_TOKEN']
|
151
|
-
end
|
152
|
-
|
153
156
|
def dev_access_token_variable
|
154
157
|
env_value_if_defined('GITLAB_QA_DEV_ACCESS_TOKEN')
|
155
158
|
end
|
@@ -162,6 +165,14 @@ module Gitlab
|
|
162
165
|
ENV['GITLAB_QA_CONTAINER_REGISTRY_ACCESS_TOKEN']
|
163
166
|
end
|
164
167
|
|
168
|
+
def qa_issue_url
|
169
|
+
ENV['GITLAB_QA_ISSUE_URL']
|
170
|
+
end
|
171
|
+
|
172
|
+
def deploy_environment
|
173
|
+
ENV['DEPLOY_ENVIRONMENT'] || pipeline_from_project_name
|
174
|
+
end
|
175
|
+
|
165
176
|
def host_artifacts_dir
|
166
177
|
@host_artifacts_dir ||= File.join(ENV['QA_ARTIFACTS_DIR'] || '/tmp/gitlab-qa', Runtime::Env.run_id)
|
167
178
|
end
|
@@ -229,10 +240,6 @@ module Gitlab
|
|
229
240
|
enabled?(ENV['QA_SKIP_PULL'], default: false)
|
230
241
|
end
|
231
242
|
|
232
|
-
def gitlab_qa_formless_login_token
|
233
|
-
env_value_if_defined('GITLAB_QA_FORMLESS_LOGIN_TOKEN')
|
234
|
-
end
|
235
|
-
|
236
243
|
private
|
237
244
|
|
238
245
|
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_until_ready
|
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_until_ready
|
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