gitlab_quality-test_tooling 1.5.1 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ba60bceafbfb950d7cc588d11b14b457f74cdf3f39271b33b171d7de935c6a2
4
- data.tar.gz: 3129a7a6da1a0c6f46df06ccd69f4d6d84a2f926a1dca268ea73455054fdbf4d
3
+ metadata.gz: ecfb78e3fc7f1f23f118c98b16cdf1c104774734d08c4ff04dd6e4c7b25ae703
4
+ data.tar.gz: 4ef1ed6d2f559f427f0c26e92b90f631b5f407b7b604914c3b17786563675966
5
5
  SHA512:
6
- metadata.gz: 0cfd0c911a463fe793c701ae13bef14dcd4e5220bc0e41819126e6659f1bcb6589ce1dba5baa33f6410f92a8ddc6414623cb7952638f66a3d79a55099089f1a6
7
- data.tar.gz: 12600147b76a659a725662119d08318999a85f1483a5d68bb6da14f464085f3d67fc6748a2f94dcee9bef82357c62a17f874d3a3feb2ee6961fbcb094f61aec0
6
+ metadata.gz: 345e33ac54c7a917bb735a715e63bb8fcbe23464186aab1d02697ae1904f894a31ee4c04e2fb793262a04a4e768518e21eb5d0214616a337ca4f526a3a14af42
7
+ data.tar.gz: 5cf0dff6f8b7ff0f9526027fb3cc1efef03cf2ca1cf655d29054ff8075217e7221936b666e619e18cc09eaa003d3b70a65f1927124c6efb8c2f1516da9f00f27
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gitlab_quality-test_tooling (1.5.1)
4
+ gitlab_quality-test_tooling (1.5.3)
5
5
  activesupport (>= 6.1, < 7.2)
6
6
  amatch (~> 0.4.1)
7
7
  gitlab (~> 4.19)
@@ -15,7 +15,7 @@ PATH
15
15
  GEM
16
16
  remote: https://rubygems.org/
17
17
  specs:
18
- activesupport (6.1.7.3)
18
+ activesupport (7.0.8)
19
19
  concurrent-ruby (~> 1.0, >= 1.0.2)
20
20
  i18n (>= 1.6, < 2)
21
21
  minitest (>= 5.1)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
4
+
3
5
  module GitlabQuality
4
6
  module TestTooling
5
7
  module Report
@@ -15,6 +15,7 @@ module GitlabQuality
15
15
  merge_request_iid: merge_request_iid)
16
16
  @files = Array(input_files)
17
17
  @merge_request_iid = merge_request_iid
18
+ @slow_tests = []
18
19
  end
19
20
 
20
21
  def invoke!
@@ -25,7 +26,7 @@ module GitlabQuality
25
26
 
26
27
  private
27
28
 
28
- attr_reader :gitlab_merge_request, :files, :project, :merge_request_iid
29
+ attr_reader :gitlab_merge_request, :files, :project, :merge_request_iid, :slow_tests
29
30
 
30
31
  def run!
31
32
  puts "Reporting slow tests in MR #{merge_request_iid}"
@@ -33,21 +34,26 @@ module GitlabQuality
33
34
  TestResults::Builder.new(files).test_results_per_file do |test_results|
34
35
  puts "=> Reporting #{test_results.count} tests in #{test_results.path}"
35
36
 
36
- upsert_mr_note(slow_related_tests(slow_tests(test_results))) if should_create_mr_note?(test_results)
37
+ @slow_tests += slow_related_tests(find_slow_tests(test_results))
37
38
  end
39
+
40
+ @slow_tests.uniq!
41
+ @slow_tests.reject!(&:failed?)
42
+
43
+ return unless @slow_tests.any?
44
+
45
+ upsert_mr_note(@slow_tests)
38
46
  end
39
47
 
40
- def should_create_mr_note?(test_results)
41
- gitlab_merge_request.merge_request_changed_files.any? &&
42
- slow_tests(test_results).any? &&
43
- slow_related_tests(slow_tests(test_results)).any?
48
+ def related_test?(slow_test)
49
+ base_file = slow_test.file.split('/').last.gsub('_spec.rb', '')
50
+
51
+ merge_request_changed_files.any? { |change| change =~ /#{base_file}/ }
44
52
  end
45
53
 
46
54
  def slow_related_tests(slow_test_results)
47
- slow_test_results.select do |slow_test_result|
48
- base_file = slow_test_result.file.split('/').last.gsub('_spec.rb', '')
49
-
50
- merge_request_changed_files.any? { |change| change =~ /#{base_file}/ }
55
+ slow_test_results.select do |slow_test|
56
+ related_test?(slow_test)
51
57
  end
52
58
  end
53
59
 
@@ -55,7 +61,7 @@ module GitlabQuality
55
61
  @merge_request_changed_files ||= gitlab_merge_request.merge_request_changed_files
56
62
  end
57
63
 
58
- def slow_tests(test_results)
64
+ def find_slow_tests(test_results)
59
65
  test_results.select(&:slow_test?)
60
66
  end
61
67
 
@@ -66,7 +72,8 @@ module GitlabQuality
66
72
  ":tools: #{SLOW_TEST_NOTE_SOURCE_CODE}\n",
67
73
  ":recycle: #{SLOW_TEST_NOTE_FEEDBACK}\n",
68
74
  "---\n",
69
- ':snail: Slow tests detected in this merge request, might be related with changed RSpec files.',
75
+ ":snail: Slow tests detected in this merge request. These slow tests might be related to this merge request's changes.",
76
+ "<details><summary>Click to expand</summary>\n",
70
77
  '| Job | File | Name | Duration | Expected duration |',
71
78
  '| --- | --- | --- | --- | --- |'
72
79
  ]
@@ -83,7 +90,7 @@ module GitlabQuality
83
90
  end
84
91
 
85
92
  def build_note(slow_test)
86
- rows = note_header + slow_test_rows(slow_test)
93
+ rows = note_header + slow_test_rows(slow_test) + ["\n</details>"]
87
94
 
88
95
  rows.join("\n")
89
96
  end
@@ -105,11 +112,13 @@ module GitlabQuality
105
112
  end
106
113
 
107
114
  def add_slow_test_rows(gitlab_note, slow_tests)
115
+ gitlab_note.gsub!("\n\n</details>", "")
116
+
108
117
  slow_tests.each do |slow_test|
109
118
  gitlab_note += "\n#{slow_test_table_row(slow_test)}" unless note_comment_includes_slow_test?(gitlab_note, slow_test)
110
119
  end
111
120
 
112
- gitlab_note
121
+ "#{gitlab_note}\n\n</details>"
113
122
  end
114
123
 
115
124
  def upsert_mr_note(slow_tests)
@@ -126,7 +126,10 @@ module GitlabQuality
126
126
  return
127
127
  end
128
128
 
129
- super
129
+ created_issue = super
130
+ test.failure_issue ||= created_issue.web_url
131
+
132
+ created_issue
130
133
  end
131
134
 
132
135
  def pipeline_issues_with_similar_stacktrace(test)
@@ -16,6 +16,9 @@ module GitlabQuality
16
16
  NEW_ISSUE_LABELS = Set.new(['test', 'type::maintenance', 'maintenance::performance', 'priority::3', 'severity::3', 'rspec profiling', 'rspec:slow test']).freeze
17
17
  SEARCH_LABELS = %w[test maintenance::performance].freeze
18
18
 
19
+ JOB_URL_REGEX = %r{(?<job_url>https://(?<host>[\w.]+)/(?<project_path>[\w\-./]+)/-/jobs/\d+)}
20
+ REPORT_ITEM_REGEX = /^1\. \d{4}-\d{2}-\d{2}: #{JOB_URL_REGEX} \((?<pipeline_url>.+)\)$/
21
+
19
22
  MultipleIssuesFound = Class.new(StandardError)
20
23
 
21
24
  private
@@ -45,9 +48,23 @@ module GitlabQuality
45
48
  to improve them. More context available about this issue in the [top slow tests guide](https://docs.gitlab.com/ee/development/testing_guide/best_practices.html#top-slow-tests).
46
49
 
47
50
  Add `allowed_to_be_slow: true` to the RSpec test if this is a legit slow test and close the issue.
51
+
52
+ #{reports_section(test)}
48
53
  DESCRIPTION
49
54
  end
50
55
 
56
+ def reports_section(test)
57
+ <<~REPORTS
58
+ ### Reports (1)
59
+
60
+ #{report_list_item(test)}
61
+ REPORTS
62
+ end
63
+
64
+ def report_list_item(test)
65
+ "1. #{Time.new.utc.strftime('%F')}: #{test.ci_job_url} (#{ENV.fetch('CI_PIPELINE_URL', 'pipeline url is missing')})"
66
+ end
67
+
51
68
  def create_slow_issue(test)
52
69
  puts " => Finding existing issues for slow test '#{test.name}' (run time: #{test.run_time} seconds)..."
53
70
 
@@ -58,6 +75,8 @@ module GitlabQuality
58
75
  else
59
76
  issues.each do |issue|
60
77
  puts " => Existing issue link #{issue['web_url']}"
78
+
79
+ update_reports(issue, test)
61
80
  end
62
81
  end
63
82
 
@@ -65,6 +84,39 @@ module GitlabQuality
65
84
  rescue MultipleIssuesFound => e
66
85
  warn(e.message)
67
86
  end
87
+
88
+ def update_reports(issue, test)
89
+ # We reopen closed issues to not lose any history
90
+ state_event = issue.state == 'closed' ? 'reopen' : nil
91
+
92
+ issue_attrs = {
93
+ description: up_to_date_issue_description(issue.description, test)
94
+ }
95
+
96
+ issue_attrs[:state_event] = state_event if state_event
97
+
98
+ gitlab.edit_issue(iid: issue.iid, options: issue_attrs)
99
+ puts " => Added a report in '#{issue.title}': #{issue.web_url}!"
100
+ end
101
+
102
+ def up_to_date_issue_description(issue_description, test)
103
+ new_issue_description =
104
+ if issue_description.include?('### Reports')
105
+ # We count the number of existing reports.
106
+ reports_count = issue_description
107
+ .scan(REPORT_ITEM_REGEX)
108
+ .size.to_i + 1
109
+ issue_description.sub(/^### Reports.*$/, "### Reports (#{reports_count})")
110
+ else # For issue with the legacy format, we add the Reports section
111
+ reports_count = issue_description
112
+ .scan(JOB_URL_REGEX)
113
+ .size.to_i + 1
114
+
115
+ "#{issue_description}\n\n### Reports (#{reports_count})"
116
+ end
117
+
118
+ "#{new_issue_description}\n#{report_list_item(test)}"
119
+ end
68
120
  end
69
121
  end
70
122
  end
@@ -3,6 +3,7 @@
3
3
  require 'forwardable'
4
4
  require 'fileutils'
5
5
  require 'rainbow'
6
+ require 'active_support'
6
7
  require 'active_support/logger'
7
8
 
8
9
  module GitlabQuality
@@ -33,6 +33,10 @@ module GitlabQuality
33
33
  status == 'pending'
34
34
  end
35
35
 
36
+ def failed?
37
+ status == 'failed'
38
+ end
39
+
36
40
  def ci_job_url
37
41
  report.fetch('ci_job_url', '')
38
42
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GitlabQuality
4
4
  module TestTooling
5
- VERSION = "1.5.1"
5
+ VERSION = "1.5.3"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitlab_quality-test_tooling
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.1
4
+ version: 1.5.3
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-11-07 00:00:00.000000000 Z
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: climate_control