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.
@@ -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
- report['status'] == 'pending'
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
@@ -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('-p', '--project PROJECT_ID', String, 'A valid project ID. Can be an integer or a group/project string. Required by --report-in-issues') do |value|
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('-t', '--token ACCESS_TOKEN', String, 'A valid access token. Used by --report-in-issues') do |value|
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
- 'CI_JOB_ID' => :ci_job_id,
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.each_value do |accessor|
90
- send(:attr_accessor, accessor) # rubocop:disable GitlabSecurity/PublicSend
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 ci_project_name
126
- ENV['CI_PROJECT_NAME']
128
+ def ci_pipeline_url
129
+ ENV['CI_PIPELINE_URL']
127
130
  end
128
131
 
129
- def ci_slack_webhook_url
130
- ENV['CI_SLACK_WEBHOOK_URL']
132
+ def ci_pipeline_id
133
+ ENV['CI_PIPELINE_ID']
131
134
  end
132
135
 
133
- def pipeline_from_project_name
134
- ci_project_name.to_s.start_with?('gitlab-qa') ? 'master' : ci_project_name
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 slack_icon_emoji
142
- ENV['SLACK_ICON_EMOJI']
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
- rspec_args << "--" unless rspec_args.include?('--')
55
- rspec_args << %w[--tag gitaly_cluster]
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 < Scenario::Template
7
- # rubocop:disable Metrics/AbcSize
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
- gitlab.act do
23
- prepare
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
- # Restart GitLab with Praefect enabled and then run the tests
33
- Component::Gitlab.perform do |gitlab|
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 omnibus_config_with_praefect
16
+ def gitlab_omnibus_configuration
66
17
  <<~OMNIBUS
67
- gitaly['enable'] = true;
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/gitaly'
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
- git_data_dirs({
98
- 'default' => {
99
- 'gitaly_address' => 'tcp://localhost:2305'
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
- 'gitaly' => {
102
- 'path' => '/var/opt/gitlab/git-data/repositories/gitaly'
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
@@ -1,5 +1,5 @@
1
1
  module Gitlab
2
2
  module QA
3
- VERSION = '6.4.0'.freeze
3
+ VERSION = '6.8.0'.freeze
4
4
  end
5
5
  end