gitlab-qa 10.0.0 → 10.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14c426ca85861845164d12c2bfe65ba51aeb3791d383920ce872b9066f7d50ca
4
- data.tar.gz: 33e80bd2dd23bc1949018fe46f70bb892fecf0a9789f0365e0ccef6c01334267
3
+ metadata.gz: aede5d84c866e5e020124c2e7d5df9e3a19a142ce774482eb6c05520c4442332
4
+ data.tar.gz: cc24b8d169a913fe0f8ff0ab69429201ded46e2ba10e6c1bd861a791b92e7683
5
5
  SHA512:
6
- metadata.gz: 560b02f9b0a4321cb1b7be3c1e482f73a306b4c171bcc0bff4c6527fdd9fdabd68fb33ee042a4033cd047f3a23e8e5d84ae8017936ed6885cfd1de0c0c3eb646
7
- data.tar.gz: 149bfc867c9913c3af4865964e12ba21d96509eaf0d4c1feb2bcf8c19c3d7da1933a68fa790bb41724ae824f4090f818d4240d5562a532e1fd2461a50138d21c
6
+ metadata.gz: 2e12535c73f7452f7ee0b4298d3ea04f3ddc24e759bd98c2ac43241fc85585d85ebcbe7cb14bfdb72a898417ddd5485b698d9fdc3345687a4a6964b18139f567
7
+ data.tar.gz: 00f4bd3f028d2b96f9cb251dd0816c29c8cf5365bc5243765c833b8d03c8ba47f57ecdda5eaa7204772a9965f6a864296b069b607a5317ea558026a216b240ba
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab-qa (10.0.0)
4
+ gitlab-qa (10.2.0)
5
5
  activesupport (~> 6.1)
6
6
  gitlab (~> 4.18.0)
7
7
  http (~> 5.0)
@@ -108,6 +108,10 @@ All environment variables used by GitLab QA should be defined in [`lib/gitlab/qa
108
108
  | `QA_1P_PASSWORD` | - | Password for authenticating into 1Password. | No |
109
109
  | `QA_1P_SECRET` | - | Secret for authenticating into 1Password. | No |
110
110
  | `QA_1P_GITHUB_UUID` | - | UUID for GitHub item in GitLab-QA 1Password vault. | No |
111
+ | `RELEASE` | - | The release image to use for an orchestrated GitLab instance. | No |
112
+ | `RELEASE_REGISTRY_URL` | - | The registry url to fetch the release image for an orchestrated GitLab. | No |
113
+ | `RELEASE_REGISTRY_USERNAME` | - | The username to log in to the registry for pulling the release image for orchestrated GitLab. | No |
114
+ | `RELEASE_REGISTRY_PASSWORD` | - | The password to log in to the registry for pulling the release image for orchestrated GitLab. | No |
111
115
 
112
116
  ## [Supported Remote Grid environment variables](./running_against_remote_grid.md)
113
117
 
@@ -152,17 +152,29 @@ module Gitlab
152
152
  def login_params
153
153
  return if Runtime::Env.skip_pull?
154
154
 
155
- if dev_gitlab_org?
156
- Runtime::Env.require_qa_dev_access_token!
157
-
158
- {
159
- username: Runtime::Env.gitlab_dev_username,
160
- password: Runtime::Env.dev_access_token_variable,
161
- registry: DEV_REGISTRY
162
- }
163
- elsif omnibus_mirror? || omnibus_security?
164
- omnibus_login_params
155
+ params = if dev_gitlab_org?
156
+ Runtime::Env.require_qa_dev_access_token!
157
+
158
+ {
159
+ username: Runtime::Env.gitlab_dev_username,
160
+ password: Runtime::Env.dev_access_token_variable,
161
+ registry: DEV_REGISTRY
162
+ }
163
+ elsif omnibus_mirror? || omnibus_security?
164
+ omnibus_login_params
165
+ end
166
+
167
+ populate_registry_env_vars(params)
168
+ end
169
+
170
+ def populate_registry_env_vars(params)
171
+ if params
172
+ Runtime::Env.release_registry_url = params[:registry]
173
+ Runtime::Env.release_registry_username = params[:username]
174
+ Runtime::Env.release_registry_password = params[:password]
165
175
  end
176
+
177
+ params
166
178
  end
167
179
 
168
180
  def omnibus_login_params
@@ -23,8 +23,9 @@ module Gitlab
23
23
 
24
24
  MultipleIssuesFound = Class.new(StandardError)
25
25
 
26
- def initialize(max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
26
+ def initialize(system_logs: [], max_diff_ratio: DEFAULT_MAX_DIFF_RATIO_FOR_DETECTION, **kwargs)
27
27
  super
28
+ @system_logs = Dir.glob(system_logs)
28
29
  @max_diff_ratio = max_diff_ratio.to_f
29
30
  @issue_type = 'issue'
30
31
  @commented_issue_list = Set.new
@@ -217,7 +218,7 @@ module Gitlab
217
218
  stacktrace_match = stacktrace.match(regex)
218
219
 
219
220
  if stacktrace_match
220
- stacktrace_match[:stacktrace].gsub(/^\s*#.*$/, '').gsub(/^[[:space:]]+/, '').strip
221
+ stacktrace_match[:stacktrace].split('First happened in')[0].gsub(/^\s*#.*$/, '').gsub(/^[[:space:]]+/, '').strip
221
222
  else
222
223
  puts " => [DEBUG] Stacktrace doesn't match the expected regex (#{regex}):\n----------------\n#{stacktrace}\n----------------\n"
223
224
  end
@@ -252,10 +253,27 @@ module Gitlab
252
253
  "```\n#{full_stacktrace(test)}\n```",
253
254
  "First happened in #{test.ci_job_url}.",
254
255
  "Related test case: #{test.testcase}.",
255
- screenshot_section(test)
256
+ screenshot_section(test),
257
+ system_log_errors_section(test)
256
258
  ].join("\n\n")
257
259
  end
258
260
 
261
+ def system_log_errors_section(test)
262
+ correlation_id = test.failures.first['correlation_id']
263
+ section = ''
264
+
265
+ if @system_logs.any? && !correlation_id.nil?
266
+ section = SystemLogs::SystemLogsFormatter.new(
267
+ @system_logs,
268
+ correlation_id
269
+ ).system_logs_summary_markdown
270
+ end
271
+
272
+ puts " => No system logs or correlation id provided, skipping this section in issue description" if section.empty?
273
+
274
+ section
275
+ end
276
+
259
277
  def new_issue_labels(test)
260
278
  up_to_date_labels(test: test, new_labels: NEW_ISSUE_LABELS)
261
279
  end
@@ -128,7 +128,8 @@ module Gitlab
128
128
  {
129
129
  'message' => "#{exception['class']}: #{exception['message']}",
130
130
  'message_lines' => exception['message_lines'],
131
- 'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}"
131
+ 'stacktrace' => "#{format_message_lines(exception['message_lines'])}\n#{exception['backtrace'].slice(0..spec_file_first_index).join("\n")}",
132
+ 'correlation_id' => exception['correlation_id']
132
133
  }
133
134
  end
134
135
  end
@@ -7,6 +7,7 @@ module Gitlab
7
7
  class Reporter
8
8
  # rubocop:disable Metrics/AbcSize
9
9
  # rubocop:disable Metrics/PerceivedComplexity
10
+ # rubocop:disable Metrics/CyclomaticComplexity
10
11
  def self.invoke(args)
11
12
  report_options = {}
12
13
  slack_options = {}
@@ -65,6 +66,12 @@ module Gitlab
65
66
  slack_options[:message] = slack_options[:message] + "\n\n" + Gitlab::QA::Report::SummaryTable.create(input_files: files)
66
67
  end
67
68
 
69
+ opts.on('--include-system-log-errors FILES', String, 'Include errors from system logs in failure issues. To be used with --relate-failure-issue') do |files|
70
+ raise 'This option should be used with --relate-failure-issue.' unless report_options[:relate_failure_issue]
71
+
72
+ report_options[:system_logs] = files if files
73
+ end
74
+
68
75
  opts.on('--update-screenshot-path FILES', "Update the path to screenshots to container's host") do |files|
69
76
  report_options[:update_screenshot_path] = true
70
77
  report_options[:files] = files
@@ -116,6 +123,7 @@ module Gitlab
116
123
  exit 1
117
124
  end
118
125
  end
126
+ # rubocop:enable Metrics/CyclomaticComplexity
119
127
  # rubocop:enable Metrics/PerceivedComplexity
120
128
  # rubocop:enable Metrics/AbcSize
121
129
  end
@@ -144,7 +144,11 @@ module Gitlab
144
144
  'QA_1P_EMAIL' => :qa_1p_email,
145
145
  'QA_1P_PASSWORD' => :qa_1p_password,
146
146
  'QA_1P_SECRET' => :qa_1p_secret,
147
- 'QA_1P_GITHUB_UUID' => :qa_1p_github_uuid
147
+ 'QA_1P_GITHUB_UUID' => :qa_1p_github_uuid,
148
+ 'RELEASE' => :release,
149
+ 'RELEASE_REGISTRY_URL' => :release_registry_url,
150
+ 'RELEASE_REGISTRY_USERNAME' => :release_registry_username,
151
+ 'RELEASE_REGISTRY_PASSWORD' => :release_registry_password
148
152
  }.freeze
149
153
 
150
154
  ENV_VARIABLES.each do |env_name, method_name|
@@ -26,7 +26,7 @@ module Gitlab
26
26
  @upgrade_path = Support::GitlabUpgradePath.new(
27
27
  current_version,
28
28
  semver_component,
29
- from_edition || @current_release.edition
29
+ from_edition.nil? || from_edition == "--" ? @current_release.edition : from_edition
30
30
  ).fetch
31
31
 
32
32
  upgrade_info = "#{[*upgrade_path, current_release].join(' => ')} (#{current_version})".bright
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Gitlab
6
+ module QA
7
+ module SystemLogs
8
+ module Finders
9
+ class JsonLogFinder
10
+ def initialize(base_path, file_path)
11
+ @base_path = base_path
12
+ @file_path = file_path
13
+ end
14
+
15
+ def find(correlation_id)
16
+ log_file_path = "#{@base_path}/#{@file_path}"
17
+ logs = []
18
+
19
+ if File.exist?(log_file_path) && !correlation_id.nil?
20
+ File.foreach(log_file_path) do |line|
21
+ begin
22
+ json_line = JSON.parse(line, symbolize_names: true)
23
+ rescue JSON::ParserError
24
+ Runtime::Logger.debug("JsonLogFinder#find attempted to parse invalid JSON: #{line}")
25
+
26
+ next
27
+ end
28
+
29
+ if (json_line[:correlation_id])&.casecmp?(correlation_id)
30
+ normalized_line = normalize_keys(json_line)
31
+ logs << new_log(normalized_line)
32
+ end
33
+ end
34
+ end
35
+
36
+ logs
37
+ end
38
+
39
+ def new_log(data)
40
+ raise 'abstract method new_log must be defined!'
41
+ end
42
+
43
+ private
44
+
45
+ def normalize_keys(json_line)
46
+ normalized_hash = {}
47
+
48
+ json_line.each_key do |old_key|
49
+ key_string = old_key.to_s
50
+
51
+ if key_string.include?('.')
52
+ normalized_key = key_string.tr('.', '_').to_sym
53
+ normalized_hash[normalized_key] = json_line[old_key]
54
+ else
55
+ normalized_hash[old_key] = json_line[old_key]
56
+ end
57
+ end
58
+
59
+ normalized_hash
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module Finders
7
+ module Rails
8
+ class ApiLogFinder < JsonLogFinder
9
+ def initialize(base_path, file_path = 'gitlab-rails/api_json.log')
10
+ super(base_path, file_path)
11
+ end
12
+
13
+ def new_log(data)
14
+ LogTypes::Rails::ApiLog.new(data)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module Finders
7
+ module Rails
8
+ class ApplicationLogFinder < JsonLogFinder
9
+ def initialize(base_path, file_path = 'gitlab-rails/application_json.log')
10
+ super(base_path, file_path)
11
+ end
12
+
13
+ def new_log(data)
14
+ LogTypes::Rails::ApplicationLog.new(data)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module Finders
7
+ module Rails
8
+ class ExceptionLogFinder < JsonLogFinder
9
+ def initialize(base_path, file_path = 'gitlab-rails/exceptions_json.log')
10
+ super(base_path, file_path)
11
+ end
12
+
13
+ def new_log(data)
14
+ LogTypes::Rails::ExceptionLog.new(data)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module Finders
7
+ module Rails
8
+ class GraphqlLogFinder < JsonLogFinder
9
+ def initialize(base_path, file_path = 'gitlab-rails/graphql_json.log')
10
+ super(base_path, file_path)
11
+ end
12
+
13
+ def new_log(data)
14
+ LogTypes::Rails::GraphqlLog.new(data)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module LogTypes
7
+ class Log
8
+ def initialize(name, data)
9
+ @name = name
10
+ @data = data
11
+ end
12
+
13
+ attr_reader :name, :data
14
+
15
+ def summary_fields
16
+ [
17
+ :severity,
18
+ :correlation_id,
19
+ :time,
20
+ :message
21
+ ]
22
+ end
23
+
24
+ def summary
25
+ summary = {}
26
+
27
+ summary_fields.each do |field|
28
+ value = data[field]
29
+ summary[field] = value unless value.nil?
30
+ end
31
+
32
+ summary
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module LogTypes
7
+ module Rails
8
+ class ApiLog < Log
9
+ include SharedFields::Exception
10
+ include SharedFields::Meta
11
+
12
+ def initialize(data)
13
+ super('Rails API', data)
14
+ end
15
+
16
+ def summary_fields
17
+ super.concat(
18
+ [
19
+ :method,
20
+ :path,
21
+ :status,
22
+ :params,
23
+ :api_error
24
+ ],
25
+ exception_fields,
26
+ meta_fields
27
+ )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module LogTypes
7
+ module Rails
8
+ class ApplicationLog < Log
9
+ include SharedFields::Exception
10
+ include SharedFields::Meta
11
+
12
+ def initialize(data)
13
+ super('Rails Application', data)
14
+ end
15
+
16
+ def summary_fields
17
+ super.concat(
18
+ exception_fields,
19
+ meta_fields
20
+ )
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module LogTypes
7
+ module Rails
8
+ class ExceptionLog < Log
9
+ include SharedFields::Exception
10
+
11
+ def initialize(data)
12
+ super('Rails Exceptions', data)
13
+ end
14
+
15
+ def summary_fields
16
+ super.concat(exception_fields)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module LogTypes
7
+ module Rails
8
+ class GraphqlLog < Log
9
+ include SharedFields::Meta
10
+
11
+ def initialize(data)
12
+ super('Rails GraphQL', data)
13
+ end
14
+
15
+ def summary_fields
16
+ super.concat(
17
+ [
18
+ :operation_name,
19
+ :query_string,
20
+ :variables
21
+ ],
22
+ meta_fields
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ module SharedFields
7
+ module Meta
8
+ def meta_fields
9
+ [
10
+ :meta_user,
11
+ :meta_project,
12
+ :meta_caller_id
13
+ ]
14
+ end
15
+ end
16
+
17
+ module Exception
18
+ def exception_fields
19
+ [
20
+ :exception_class,
21
+ :exception_message,
22
+ :exception_backtrace
23
+ ]
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gitlab
4
+ module QA
5
+ module SystemLogs
6
+ class SystemLogsFormatter
7
+ NUM_OF_LOG_SECTIONS = 4
8
+
9
+ def initialize(base_paths, correlation_id)
10
+ @base_paths = base_paths
11
+ @correlation_id = correlation_id
12
+ end
13
+
14
+ def system_logs_summary_markdown
15
+ log_sections = Array.new(NUM_OF_LOG_SECTIONS) { [] }
16
+
17
+ @base_paths.each do |base_path|
18
+ all_logs = [
19
+ Finders::Rails::ApiLogFinder.new(base_path).find(@correlation_id),
20
+ Finders::Rails::ExceptionLogFinder.new(base_path).find(@correlation_id),
21
+ Finders::Rails::ApplicationLogFinder.new(base_path).find(@correlation_id),
22
+ Finders::Rails::GraphqlLogFinder.new(base_path).find(@correlation_id)
23
+ ]
24
+
25
+ create_log_summary_sections!(all_logs, log_sections)
26
+ end
27
+
28
+ log_sections.prepend('### System Logs') unless log_sections.all?(&:empty?)
29
+ log_sections.join("\n").rstrip
30
+ end
31
+
32
+ private
33
+
34
+ def create_log_summary_sections!(all_logs, sections)
35
+ sections.zip(all_logs) do |section, logs|
36
+ unless logs.empty?
37
+ section_title = "\n#### #{logs.first.name}"
38
+ section.append(section_title) unless section.include?(section_title)
39
+ section.append(create_log_summaries(logs))
40
+ end
41
+ end
42
+ end
43
+
44
+ def create_log_summaries(logs)
45
+ section = []
46
+
47
+ logs.each do |log|
48
+ log_summary = <<~MARKDOWN.chomp
49
+ <details><summary>Click to expand</summary>
50
+
51
+ ```json
52
+ #{JSON.pretty_generate(log.summary)}
53
+ ```
54
+ </details>
55
+ MARKDOWN
56
+
57
+ section.append(log_summary)
58
+ end
59
+
60
+ section.join("\n\n")
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Gitlab
4
4
  module QA
5
- VERSION = '10.0.0'
5
+ VERSION = '10.2.0'
6
6
  end
7
7
  end
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: 10.0.0
4
+ version: 10.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitLab Quality
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-07 00:00:00.000000000 Z
11
+ date: 2023-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control
@@ -485,6 +485,18 @@ files:
485
485
  - lib/gitlab/qa/support/invalid_response_error.rb
486
486
  - lib/gitlab/qa/support/shell_command.rb
487
487
  - lib/gitlab/qa/support/shellout.rb
488
+ - lib/gitlab/qa/system_logs/finders/json_log_finder.rb
489
+ - lib/gitlab/qa/system_logs/finders/rails/api_log_finder.rb
490
+ - lib/gitlab/qa/system_logs/finders/rails/application_log_finder.rb
491
+ - lib/gitlab/qa/system_logs/finders/rails/exception_log_finder.rb
492
+ - lib/gitlab/qa/system_logs/finders/rails/graphql_log_finder.rb
493
+ - lib/gitlab/qa/system_logs/log_types/log.rb
494
+ - lib/gitlab/qa/system_logs/log_types/rails/api_log.rb
495
+ - lib/gitlab/qa/system_logs/log_types/rails/application_log.rb
496
+ - lib/gitlab/qa/system_logs/log_types/rails/exception_log.rb
497
+ - lib/gitlab/qa/system_logs/log_types/rails/graphql_log.rb
498
+ - lib/gitlab/qa/system_logs/shared_fields.rb
499
+ - lib/gitlab/qa/system_logs/system_logs_formatter.rb
488
500
  - lib/gitlab/qa/test_logger.rb
489
501
  - lib/gitlab/qa/version.rb
490
502
  - scripts/build-package-and-test-env